数据结构复习---排序(2)
交换类排序、
1、冒泡排序算法
冒泡排序在众多排序算法中算比较简单的一个,基本思想是重复的进行整个数列的排序,一次比较两个元素(两两排序),如果它们顺序不符合就交换,重复这样直到数列没有再需要交换的数为止(结束条件)。就好像气泡一样,轻的气泡会往上漂浮,在不断漂浮的过程中,发生了两两交换过程,所以叫冒泡排序。
//冒泡排序
public static void bubSort(Comparable[] arr){
int N=arr.length;
for(int i=0;i<N-1;i++){
for (int j = 0; j <N-1-i ; j++) {
if(!less(arr[j],arr[j+1]))//从小到大排序 前面的比后面的大就这样
exch(arr,j,j+1);
}
}
}
2、快速排序
1.概念
快速排序,听这个名字就能想到它排序速度快,它是一种原地排序(只需要一个很小的辅助栈,注意不是数组),且将长度为N的数组排序所需的时间和NlgN成正比
缺点是:非常脆弱,在实现时一定要注意几个小细节(下面详细讲),才能避免错误。
2.基本思想:
随机找出一个数(通常就拿数组第一个数据就行),把它插入一个位置,使得它左边的数都比它小,它右边的数据都比它大,这样就将一个数组分成了两个子数组,然后再按照同样的方法把子数组再分成更小的子数组,直到不能分解为止。 它也是分治思想的一个经典实验(归并排序也是)
3.快速与归并排序的区别:
(1)归并排序将数组分成两个子数组,然后分别排序,并将有序的子数组归并以将整个数组排序;
快速排序将数组排序的方式是当两个子数组都有序时整个数组也就自然有序了
(2)归并排序的递归调用发生在处理整个数组之前
快速排序的递归调用发生在处理整个数组之后
方法其实很简单:分别从初始序列“6 1 2 7 9 3 4 5 10 8”两端开始“探测”。先从右往左找一个小于6的数,再从左往右找一个大于6的数,然后交换他们。这里可以用两个变量i和j,分别指向序列最左边和最右边。我们为这两个变量起个好听的名字“哨兵i”和“哨兵j”。刚开始的时候让哨兵i指向序列的最左边(即i=1),指向数字6。让哨兵j指向序列的最右边(即j=10),指向数字8。
现在交换哨兵i和哨兵j所指向的元素的值。交换之后的序列如下。
//对元素进行比较
private static boolean less1(Comparable v,Comparable w){
return v.compareTo(w)<=0;
}
//快速排序
public static void quickSort(Comparable[] a,int left,int right){
if(left>right)
return;
int i=left;
int j=right;
Comparable v=a[left];
while (i!=j){
//先从右往左开始找 第一个小于等于v的数据
while(less1(v,a[j])&&(i<j))
j--;
//从左往右找 第一个大于等于v的数据
while(less1(a[i],v)&&(i<j))
i++;
if(i<j){
exch(a,i,j);
}
}
//校准数据
exch(a,left,i);
quickSort(a,left,i-1);
quickSort(a,i+1,right);
}
归并排序
思想:讲一个数组排序,首先要将(递归的)分成两半分别进行排序,然后将结果归并起来。
原地归并
//归并排序要用的 把两个数组合并成一个数组的方法
public static void merge(Comparable[] a,int left,int mid,int right){
int i=left;
int j=mid+1;
Comparable[] aux=new Comparable[a.length];
int t=0;
while(i<=mid&&j<=right){
if(less(a[i],a[j])){
aux[t++]=a[i++];
}
else{
aux[t++]=a[j++];
}
}
while(i<=mid)//将左边剩余元素填充
aux[t++]=a[i++];
while(j<=right)//将右边剩余元素填充
aux[t++]=a[j++];
t=0;
while(left<=right)
a[left++]=aux[t++];
}
//归并排序
public static void mergSort(Comparable[] arr,int left,int right){
if(left<right){
int mid = (right+left)/2;
mergSort(arr,left,mid);//左边归并排序,使得左子序列有序
mergSort(arr,mid+1,right);//右边归并排序,使得右子序列有序
merge(arr,left,mid,right);//将两个有序子数组合并操作
}
}
调用实现
public static void main(String[] args) {
Comparable[] sort={1,2,4,3,0,8};
//insertSort(sort);
mergSort(sort,0,sort.length-1);
show(sort);
}
实验结果
快速排序
参考文章:https://blog.csdn.net/yuehailin/article/details/68961304