排序总结(1)---冒泡排序、选择排序、插入排序、希尔排序
2017-05-05 19:52
633 查看
排序总结(1)—冒泡排序、选择排序、插入排序、希尔排序
最近温习一下各排序算法,代码块中有详细的注释,test函数在结尾处先来总结一下排序的时间复杂度、空间复杂度、稳定性
稳定的排序
稳定的排序 | 时间复杂度 | 空间复杂度 |
---|---|---|
冒泡排序 | 最差、平均都是O(n2),最好是O(n) | 1 |
双向冒泡排序 | 最差、平均都是O(n2),最好是O(n) | 1 |
插入排序 | 最差、平均都是O(n2),最好是O(n) | 1 |
归并排序 | 最差、平均、最好都是O(nlogn) | O(n) |
桶排序 | O(n) | O(k) |
基数排序 | O(dn),d为常数 | O(n) |
二叉树排序 | O(nlogn) | O(n) |
图书馆排序 | O(nlogn),最坏O(n2) | O(n) |
不稳定的排序 | 时间复杂度 | 空间复杂度 |
---|---|---|
选择排序 | 最差、平均都是O(n2) | 1 |
希尔排序 | O(nlogn) | 1 |
堆排序 | 最差、平均、最好情况都是O(nlogn) | 1 |
快速排序 | 平均是O(nlogn),最坏情况是O(n2) | O(nlogn) |
/** * @ClassName BublleSort * @Description 冒泡排序 最好的时间复杂度:O(n) 最坏的时间的复杂度O(n2) 平均时间复杂度O(n2) * 算法为就地排序,是稳定的排序算法 * @author yj */ public class BubbleSort { /** * 冒泡排序 * @param source needed sort array */ public static void bubbleSort(int[] source){ for(int i = 0;i < source.length-1;i++){//循环每一趟排序 for(int j = 0;j<source.length -i-1;j++){//一趟排序中 if(source[j]>source[j+1])swap(source,j,j+1); } } } /** * 升级的冒泡排序<br> * 加入了交换标识的冒泡排序,如果一趟排序中没有发生数据交换说明已经排序完成, * 此时交换标识为false,在这一趟排序后提前终止算法 * @param source */ public static void bubbleSort2(int[] source){ boolean exchange;//交换标识,如果没有发生交换说明已经排序完成 for(int i = source.length-1;i>0;i--){//一趟排序 exchange = false;//每一次排序前设置为false for(int j = 0;j<i;j++){ if(source[j]>source[j+1]){ swap(source,j,j+1); exchange = true;//发生交换就设置为true } } if(!exchange)//没有发生交换,终止 return ; } } /** * swap to number in the array * @param source 需要交换的数组数据 * @param x the index of the number who needed swap in the array * @param y 需要交换的数据在source中的位置 */ public static void swap(int[] source,int x, int y){ int temp = source[x]; source[x] = source[y]; source[y] = temp; } }
选择排序:
/** * 选择排序<br> * 平均复杂度为O(n2),不稳定的排序 * @author hp * */ public class SelectSort { /** * 每次循环找出最小值并记录下标index,如果标志位index与i不同, * 就将位置为index的数据与位置为i的数据交换 * @param source */ public static void selectSort(int[] source) { int index;// 下标标识,记录未排序序列中最小值 for (int i = 0; i < source.length - 1; i++) {//每次循环找出最小值并记录下标 index = i;// 记录未排序的第一个开始位置,进行比较 for (int j = i + 1; j < source.length; j++) {//循环找出未排序最小值记录到index if(source[j]<source[index])index = j; } if(index != i){//如果标识不等于当前循环未排序的首位,说明有比首位更小的数字,进行交换 swap(source,i,index); } } } /** * swap to number in the array * * @param source 需要交换的数组数据 * @param x the index of the number who needed swap in the array * @param y 需要交换的数据在source中的位置 */ public static void swap(int[] source, int x, int y) { int temp = source[x]; source[x] = source[y]; source[y] = temp; } }
插入排序:
/** * 平均算法复杂度O()n2 * @author hp * */ public class InsertSort { /** * 插入排序 * @param source */ public static void insertSort(int[] source){ for(int i = 1;i<source.length;i++){//从第二个元素开始,将其插入到前面合适位置 for(int j = i;(j>0)&&(source[j]<source[j-1]);j--){//每次向前移动直到到达合适位置 swap(source,j,j-1); } } } /** * swap to number in the array * * @param source 需要交换的数组数据 * @param x the index of the number who needed swap in the array * @param y 需要交换的数据在source中的位置 */ public static void swap(int[] source, int x, int y) { int temp = source[x]; source[x] = source[y]; source[y] = temp; } }
希尔排序:
为了更清晰体现希尔排序的过程,在算法中插入了打印函数,每次数据交换都能清晰明了
/** * 时间复杂度O(nlogn),不稳定排序 * 先取一个小于n的整数d1作为第一个增量,把文件的全部记录分组。 * 所有距离为d1的倍数的记录放在同一个组中。先在各组内进行直接插入排序; * 然后,取第二个增量d2<d1重复上述的分组和排序, * 直至所取的增量 =1( < …<d2<d1),即所有记录放在同一组中进行直接插入排序为止。 * @author hp * */ public class ShellSort { public static void shellSort(int[] source){ int len = source.length; for(len = len/2;len!=0;len/=2){//初始时取长度的一半为间隔长度,每次减半直到为0 for(int i = len;i<source.length;i++){//从每组的第二个位置开始,依次向前插入操作,然后循环到每组的第三个位置。。。 for(int j = i;(j-len)>=0&&source[j-len]>source[j];j-=len){//插入排序中的核心部分---向前比较、判断条件是否成立并交换 swap(source,j-len,j); spy(source);//观察每次交换的情况 } } } } /** * 方便观察每次排序的,可以窥探数组排序的情况 * @param source */ public static void spy(int[] source){ for(int k = 0;k<source.length;k++){ System.out.printf("%3s ",source[k]); } System.out.println(); } /** * swap to number in the array * * @param source 需要交换的数组数据 * @param x the index of the number who needed swap in the array * @param y 需要交换的数据在source中的位置 */ public static void swap(int[] source, int x, int y) { int temp = source[x]; source[x] = source[y]; source[y] = temp; } }
测试一下:
public static void main(String[] args) { int a[] = {4,2,1,6,3,6,0,-5,1,1}; System.out.println("排序前: "); for(int i = 0; i < 10; i++){ System.out.print(a[i]+" "); } System.out.println("\n排序后:"); ShellSort.shellSort(a); }
希尔排序的运行结果
相关文章推荐
- 各种排序算法总结----基数排序、归并排序、插入排序、冒泡排序、选择排序、快速排序、堆排序、希尔排序
- C#的四种排序算法:冒泡排序、选择排序、插入排序和希尔排序
- 排序的四种写法包括(冒泡排序,选择排序,插入排序,希尔排序)
- 【C#算法】冒泡排序 选择排序 插入排序 希尔排序--转
- 几种常用的排序算法的分析及java实现(希尔排序,堆排序,归并排序,快速排序,选择排序,插入排序,冒泡排序)
- 选择排序、快速排序、希尔排序、堆排序不是稳定的排序算法,而冒泡排序、插入排序、归并排序和基数排序是稳定的排序算法。
- C#冒泡排序、选择排序、插入排序和希尔排序
- 快速排序、希尔排序、插入排序、选择排序、归并排序、堆排序总结
- C#的四种排序算法:冒泡排序、选择排序、插入排序和希尔排序
- 冒泡排序,选择排序,插入排序,希尔排序,合并排序,快速排序算法
- 【算法】希尔排序,快速排序,选择排序,插入排序,冒泡排序
- C++各种常见排序算法 冒泡排序,插入排序,快排序,选择排序,希尔排序
- C#实现所有经典排序算法(选择排序,冒泡排序,快速排序,插入排序,希尔排序)
- 快速排序、希尔排序、插入排序、选择排序、归并排序、堆排序总结
- C#的四种排序算法:冒泡排序、选择排序、插入排序和希尔排序
- C#的排序算法:冒泡排序、选择排序、插入排序和希尔排序
- C#的四种排序算法:冒泡排序、选择排序、插入排序和希尔排序
- C#的四种排序算法:冒泡排序、选择排序、插入排序和希尔排序
- C#排序算法:冒泡排序 选择排序 插入排序 希尔排序
- 算法导论之插入排序,选择排序,归并排序,冒泡排序,希尔排序,堆排序,快速排序的c语言实现