几种排序算法的性能比较
1. 从计算复杂度角度:
排序数据量的大小为n

2. 从系统资源的占用角度:
大部分排序算法都只需要使用1个元素的存储单元用来交换数据。而合并排序算法需要使用与原始序列一样长的n个元素的存储单元来保存多遍合并操作。
3. 从是不是稳定排序算法角度:
稳定排序算法:对于两个有相等关键字的数据D1和D2,在待排序的数据中D1出现在D2之前,在排序后的数据中D1也在D2之前,那么这就是一个稳定的排序算法。
冒泡排序算法、插入排序算法和合并排序算法都是稳定排序算法。而选择排序、Shell排序、快速排序、和堆排序算法都是不稳定排序算法。
4. 使用场合:
如果数据量n较小,可以采用插入排序或选择排序法;
当数据量n较大时,则采用时间复杂度为O(nlogn)的排序算法,如快速排序、堆排序、或合并排序;
如果待排序的原始数据呈随机分布,那么快速排序算法的平均时间最短。
代码实现:
1.冒泡排序
/*冒泡排序*/ public class P4_1 { static final int SIZE=10; public static void bubbleSort(int[] a) { int temp; for (int i = 1; i < a.length; i++) { //将相邻两个数进行比较,较大的数往后冒泡 for (int j = 0; j < a.length - i; j++) { if (a[j] > a[j + 1]) { //交换相邻两个数 temp=a[j]; a[j]=a[j+1]; a[j+1]=temp; } } System.out.print("第"+i+"步排序结果:"); //输出每步排序的结果 for(int k=0;k<a.length;k++) { System.out.print(" "+a[k]); // 输出 } System.out.print("\n"); } } public static void main(String[] args) { int[] shuzu=new int[SIZE]; int i; for(i=0;i<SIZE;i++) { shuzu[i]=(int)(100+Math.random()*(100+1)); //初始化数组 } System.out.print("排序前的数组为:\n"); //输出排序前的数组 for(i=0;i<SIZE;i++) { System.out.print(shuzu[i]+" "); } System.out.print("\n"); bubbleSort(shuzu); //排序操作 System.out.print("排序后的数组为:\n"); for(i=0;i<SIZE;i++) { System.out.print(shuzu[i]+" "); //输出排序后的数组 } System.out.print("\n"); } }运行结果:
排序前的数组为: 175 179 101 141 126 148 166 129 179 189 第1步排序结果: 175 101 141 126 148 166 129 179 179 189 第2步排序结果: 101 141 126 148 166 129 175 179 179 189 第3步排序结果: 101 126 141 148 129 166 175 179 179 189 第4步排序结果: 101 126 141 129 148 166 175 179 179 189 第5步排序结果: 101 126 129 141 148 166 175 179 179 189 第6步排序结果: 101 126 129 141 148 166 175 179 179 189 第7步排序结果: 101 126 129 141 148 166 175 179 179 189 第8步排序结果: 101 126 129 141 148 166 175 179 179 189 第9步排序结果: 101 126 129 141 148 166 175 179 179 189 排序后的数组为: 101 126 129 141 148 166 175 179 179 189
2.选择排序
/*选择排序*/ public class P4_2 { static final int SIZE=10; public static void selectSort(int[] a) { int index,temp; for (int i = 0; i < a.length-1; i++) { index = i; for (int j = i+1; j <a.length; j++) { if (a[j] < a[index]) { index = j; } } //交换两个数 if(index!=i) { temp=a[i]; a[i]=a[index]; a[index]=temp; } System.out.print("第"+i+"步排序结果:"); //输出每步排序的结果 for(int h=0;h<a.length;h++) { System.out.print(" "+a[h]); //输出 } System.out.print("\n"); } } public static void main(String[] args) { int[] shuzu=new int[SIZE]; int i; for(i=0;i<SIZE;i++) { shuzu[i]=(int)(100+Math.random()*(100+1)); //初始化数组 } System.out.print("排序前的数组为:\n"); //输出排序前的数组 for(i=0;i<SIZE;i++) { System.out.print(shuzu[i]+" "); } System.out.print("\n"); selectSort(shuzu); //排序操作 System.out.print("排序后的数组为:\n"); for(i=0;i<SIZE;i++) { System.out.print(shuzu[i]+" "); //输出排序后的数组 } System.out.print("\n"); } }运行结果:
排序前的数组为: 185 109 113 132 186 176 103 190 114 180 第0步排序结果: 103 109 113 132 186 176 185 190 114 180 第1步排序结果: 103 109 113 132 186 176 185 190 114 180 第2步排序结果: 103 109 113 132 186 176 185 190 114 180 第3步排序结果: 103 109 113 114 186 176 185 190 132 180 第4步排序结果: 103 109 113 114 132 176 185 190 186 180 第5步排序结果: 103 109 113 114 132 176 185 190 186 180 第6步排序结果: 103 109 113 114 132 176 180 190 186 185 第7步排序结果: 103 109 113 114 132 176 180 185 186 190 第8步排序结果: 103 109 113 114 132 176 180 185 186 190 排序后的数组为: 103 109 113 114 132 176 180 185 186 190
3.插入排序
/*插入排序*/ public class P4_3 { static final int SIZE=10; static void insertionSort(int[] a) //插入排序 { int i,j,t,h; for (i=1;i<a.length;i++) { t=a[i]; j=i-1; while(j>=0 && t<a[j]) { a[j+1]=a[j]; j--; } a[j+1]=t; System.out.print("第"+i+"步排序结果:"); //输出每步排序的结果 for(h=0;h<a.length;h++) { System.out.print(" "+a[h]); //输出 } System.out.print("\n"); } } public static void main(String[] args) { int[] shuzu=new int[SIZE]; int i; for(i=0;i<SIZE;i++) { shuzu[i]=(int)(100+Math.random()*(100+1)); //初始化数组 } System.out.print("排序前的数组为:\n"); //输出排序前的数组 for(i=0;i<SIZE;i++) { System.out.print(shuzu[i]+" "); } System.out.print("\n"); insertionSort(shuzu); //排序操作 System.out.print("排序后的数组为:\n"); for(i=0;i<SIZE;i++) { System.out.print(shuzu[i]+" "); //输出排序后的数组 } System.out.print("\n"); } }运行结果:
排序前的数组为: 152 109 126 135 189 157 134 166 192 178 第1步排序结果: 109 152 126 135 189 157 134 166 192 178 第2步排序结果: 109 126 152 135 189 157 134 166 192 178 第3步排序结果: 109 126 135 152 189 157 134 166 192 178 第4步排序结果: 109 126 135 152 189 157 134 166 192 178 第5步排序结果: 109 126 135 152 157 189 134 166 192 178 第6步排序结果: 109 126 134 135 152 157 189 166 192 178 第7步排序结果: 109 126 134 135 152 157 166 189 192 178 第8步排序结果: 109 126 134 135 152 157 166 189 192 178 第9步排序结果: 109 126 134 135 152 157 166 178 189 192 排序后的数组为: 109 126 134 135 152 157 166 178 189 192
4.Shell排序
/*Shell排序*/ public class P4_4 { static final int SIZE=10; static void shellSort(int[] a) //Shell排序 { int i,j,h; int r,temp; int x=0; for(r=a.length/2;r>=1;r/= 2) //划组排序 { for(i=r;i<a.length;i++) { temp=a[i]; j=i-r; while(j>=0 && temp<a[j]) { a[j+r]=a[j]; j-=r; } a[j+r]=temp; } x++; System.out.print("第"+x+"步排序结果:"); //输出每步排序的结果 for(h=0;h<a.length;h++) { System.out.print(" "+a[h]); //输出 } System.out.print("\n"); } } public static void main(String[] args) { int[] shuzu=new int[SIZE]; int i; for(i=0;i<SIZE;i++) { shuzu[i]=(int)(100+Math.random()*(100+1)); //初始化数组 } System.out.print("排序前的数组为:\n"); //输出排序前的数组 for(i=0;i<SIZE;i++) { System.out.print(shuzu[i]+" "); } System.out.print("\n"); shellSort(shuzu); //排序操作 System.out.print("排序后的数组为:\n"); for(i=0;i<SIZE;i++) { System.out.print(shuzu[i]+" "); //输出排序后的数组 } System.out.print("\n"); } }运行结果:
排序前的数组为: 112 176 110 109 182 149 134 184 199 168 第1步排序结果: 112 134 110 109 168 149 176 184 199 182 第2步排序结果: 110 109 112 134 168 149 176 182 199 184 第3步排序结果: 109 110 112 134 149 168 176 182 184 199 排序后的数组为: 109 110 112 134 149 168 176 182 184 199
5.快速排序
/*快速排序*/ public class P4_5 { static final int SIZE=18; static void quickSort(int[] arr,int left,int right) //快速排序算法 { int f,t; int rtemp,ltemp; ltemp=left; rtemp=right; f=arr[(left+right)/2]; //分界值 while(ltemp<rtemp) { while(arr[ltemp]<f) { ++ltemp; } while(arr[rtemp]>f) { --rtemp; } if(ltemp<=rtemp) { t=arr[ltemp]; arr[ltemp]=arr[rtemp]; arr[rtemp]=t; --rtemp; ++ltemp; } } if(ltemp==rtemp) { ltemp++; } if(left<rtemp) { quickSort(arr,left,ltemp-1); //递归调用 } if(ltemp<right) { quickSort(arr,rtemp+1,right); //递归调用 } } public static void main(String[] args) { int[] shuzu=new int[SIZE]; int i; for(i=0;i<SIZE;i++) { shuzu[i]=(int)(100+Math.random()*(100+1)); //初始化数组 } System.out.print("排序前的数组为:\n"); //输出排序前的数组 for(i=0;i<SIZE;i++) { System.out.print(shuzu[i]+" "); } System.out.print("\n"); quickSort(shuzu,0,SIZE-1); //排序操作 System.out.print("排序后的数组为:\n"); for(i=0;i<SIZE;i++) { System.out.print(shuzu[i]+" "); //输出排序后的数组 } System.out.print("\n"); } }运行结果:
排序前的数组为: 131 157 132 167 109 153 150 107 111 127 127 175 129 167 109 199 104 118 排序后的数组为: 104 107 109 109 111 118 127 127 132 129 131 150 153 157 167 167 175 199
6.堆排序
/*堆排序*/ public class P4_6 { static final int SIZE=10; static void heapSort(int a[],int n) //堆排序 { int i,j,h,k; int t; for(i=n/2-1;i>=0;i--) //将a[0,n-1]建成大根堆 { while(2*i+1<n) //第i个结点有右子树 { j=2*i+1 ; if((j+1)<n) { if(a[j]<a[j+1]) //右左子树小于右子树,则需要比较右子树 j++; //序号增加1,指向右子树 } if(a[i]<a[j]) //比较i与j为序号的数据 { t=a[i]; //交换数据 a[i]=a[j]; a[j]=t; i=j ; //堆被破坏,需要重新调整 } else //比较左右子结点均大则堆未破坏,不再需要调整 { break; } } } //输出构成的堆 System.out.print("原数据构成的堆:"); for(h=0;h<n;h++) { System.out.print(" "+a[h]); //输出 } System.out.print("\n"); for(i=n-1;i>0;i--) { t=a[0]; //与第i个记录交换 a[0] =a[i]; a[i] =t; k=0; while(2*k+1<i) //第i个结点有右子树 { j=2*k+1 ; if((j+1)<i) { if(a[j]<a[j+1]) //右左子树小于右子树,则需要比较右子树 { j++; //序号增加1,指向右子树 } } if(a[k]<a[j]) //比较i与j为序号的数据 { t=a[k]; //交换数据 a[k]=a[j]; a[j]=t; k=j ; //堆被破坏,需要重新调整 } else //比较左右子结点均大则堆未破坏,不再需要调整 { break; } } System.out.print("第"+(n-i)+"步排序结果:"); //输出每步排序的结果 for(h=0;h<n;h++) { System.out.print(" "+a[h]); //输出 } System.out.print("\n"); } } public static void main(String[] args) { int[] shuzu=new int[SIZE]; int i; for(i=0;i<SIZE;i++) { shuzu[i]=(int)(100+Math.random()*(100+1)); //初始化数组 } System.out.print("排序前的数组为:\n"); //输出排序前的数组 for(i=0;i<SIZE;i++) { System.out.print(shuzu[i]+" "); } System.out.print("\n"); heapSort(shuzu,SIZE); //排序操作 System.out.print("排序后的数组为:\n"); for(i=0;i<SIZE;i++) { System.out.print(shuzu[i]+" "); //输出排序后的数组 } System.out.print("\n"); } }运行结果:
排序前的数组为: 181 106 184 144 122 139 161 136 173 161 原数据构成的堆: 184 173 181 144 161 139 161 136 106 122 第1步排序结果: 181 173 161 144 161 139 122 136 106 184 第2步排序结果: 173 161 161 144 106 139 122 136 181 184 第3步排序结果: 161 144 161 136 106 139 122 173 181 184 第4步排序结果: 161 144 139 136 106 122 161 173 181 184 第5步排序结果: 144 136 139 122 106 161 161 173 181 184 第6步排序结果: 139 136 106 122 144 161 161 173 181 184 第7步排序结果: 136 122 106 139 144 161 161 173 181 184 第8步排序结果: 122 106 136 139 144 161 161 173 181 184 第9步排序结果: 106 122 136 139 144 161 161 173 181 184 排序后的数组为: 106 122 136 139 144 161 161 173 181 184
7.合并排序
/*合并排序*/ public class P4_7 { static final int SIZE=15; static void mergeOne(int a[],int b[],int n,int len) //完成一遍合并的函数 { int i,j,k,s,e; s=0; while(s+len<n) { e=s+2*len-1; if(e>=n) //最后一段可能少于len个结点 { e=n-1; } //相邻有序段合并 k=s; i=s; j=s+len; while(i<s+len && j<=e) //如果两个有序表都未结束时,循环比较 { if(a[i]<=a[j]) //如果较小的元素复制到数组b中 { b[k++]=a[i++]; } else { b[k++]=a[j++]; } } while(i<s+len) //未合并的部分复制到数组b中 { b[k++]=a[i++]; } while(j<=e) { b[k++]=a[j++]; //未合并的部分复制到数组b中 } s=e+1; //下一对有序段中左段的开始下标 } if(s<n) //将剩余的一个有序段从数组A中复制到数组b中 { for(;s<n;s++) { b[s]=a[s]; } } } static void mergeSort(int a[],int n) //合并排序 { // int *p; int h,count,len,f; count=0; //排序步骤 len=1; //有序序列的长度 f=0; //变量f作标志 // if(!(p=(int *)malloc(sizeof(int)*n))) //分配内存空间 // { // printf("内存分配失败!\n"); // exit(0); // } int[] p=new int[n]; while(len<n) { if(f==1) //交替在A和P之间合并 { mergeOne(p,a,n,len); //p合并到a } else { mergeOne(a,p,n,len); //a合并到p } len=len*2; //增加有序序列长度 f=1-f; //使f值在0和1之间切换 count++; System.out.printf("第"+count+"步排序结果:"); //输出每步排序的结果 for(h=0;h<SIZE;h++) { System.out.printf(" "+a[h]); //输出 } System.out.print("\n"); } if(f==1) //如果进行了排序 { for(h=0;h<n;h++) //将内存p中的数据复制回数组a { a[h]=p[h]; } } // free(p); //释放内存 } public static void main(String[] args) { int[] shuzu=new int[SIZE]; int i; for(i=0;i<SIZE;i++) { shuzu[i]=(int)(100+Math.random()*(100+1)); //初始化数组 } System.out.print("排序前的数组为:\n"); //输出排序前的数组 for(i=0;i<SIZE;i++) { System.out.print(shuzu[i]+" "); } System.out.print("\n"); mergeSort(shuzu,SIZE); //排序操作 System.out.print("排序后的数组为:\n"); for(i=0;i<SIZE;i++) { System.out.print(shuzu[i]+" "); //输出排序后的数组 } System.out.print("\n"); } }运行结果:
排序前的数组为: 133 120 148 135 106 125 122 172 199 108 112 151 168 107 194 第1步排序结果: 133 120 148 135 106 125 122 172 199 108 112 151 168 107 194 第2步排序结果: 120 133 135 148 106 122 125 172 108 112 151 199 107 168 194 第3步排序结果: 120 133 135 148 106 122 125 172 108 112 151 199 107 168 194 第4步排序结果: 106 107 108 112 120 122 125 133 135 148 151 168 172 194 199 排序后的数组为: 106 107 108 112 120 122 125 133 135 148 151 168 172 194 199