1、LintCode整数排序
给一组整数,按照升序排序,使用选择排序,冒泡排序,插入排序或者任何 O(n2) 的排序算法。
您在真实的面试中是否遇到过这个题?
样例
对于数组 [3, 2, 1, 4, 5]
, 排序后为:[1, 2, 3, 4, 5]
。
(1)冒泡排序:从头开始,比较相邻的两个元素,大的放在后面。一轮结束之后,最大的数沉底,不参与下一轮比较。重复 直至待排序的元素个数为1。O(n2)
public class Test1 { public static void sort(int[] a){
if(a.size()!=0){ for(int i=0;i<a.length-1;i++){ for(int j=0;j<a.length-1-i;j++){ if(a[j]>a[j+1]){ int temp=a[j]; a[j]=a[j+1]; a[j+1]=temp; } } }
} } public static void main(String[] args) { int a[]={4,8,6,2,1}; sort(a); for(int i=0;i<a.length;i++){ System.out.println(a[i]); } } }
(2)插入排序:第一个元素是有序队列,从第二个元素开始向有序队列中插入,插入完成后将第三个元素向有序队列中插入,依次进行,直到将最后一个元素插入完毕。
public class Test1 { public static void InsertSort(int[] source) { int i, j; int insertNode;// 要插入的数据 // 从数组的第二个元素开始循环将数组中的元素插入 for (i = 1; i < source.length; i++) { // 设置数组中的第2个元素为第一次循环要插入的数据 insertNode = source[i]; j = i - 1; // 如果要插入的元素小于第j个元素,就将第j个元素向后移 while ((j >= 0) && insertNode < source[j]) { source[j + 1] = source[j]; j--; } // 直到要插入的元素不小于第j个元素,将insertNote插入到数组中 source[j + 1] = insertNode; System.out.print("第" + i + "趟排序:"); printArray(source); } } private static void printArray(int[] source) { for (int i = 0; i < source.length; i++) { System.out.print(" " + source[i]); } System.out.println(); } public static void main(String[] args) { int source[] = new int[] { 53, 27, 36, 15, 69, 42 }; System.out.print("初始关键字:"); printArray(source); System.out.println(""); InsertSort(source); System.out.print(" 排序后结果:"); printArray(source); } }
(3)快读排序:
对于一组给定的记录,通过一趟排序后,将原序列分为两部分,其中前一部分的所有记录均比后一部分的所有记录小,然后再依次对前后两部分的记录进行快速排序,递归该过程,直到序列中的所有记录均有序为止。
public class Test2 { public static void main(String[] args) { int[] a = { 4,8,1,3,5 }; System.out.println("排序前:"); for (int i = 0; i < a.length; i++) { System.out.println(a[i]); } quickSort(a); System.out.println("排序后:"); for (int i = 0; i < a.length; i++) { System.out.println(a[i]); } } public static void quickSort(int[] a){ if(a.length>0){ sort(a,0,a.length-1); } } public static void sort(int[] a,int low,int high) { int start = low; int end = high; int key = a[low]; while (end > start) { // 从后往前比较 while (end > start && a[end] >= key) // 如果没有比关键值小的,比较下一个,直到有比关键值小的交换位置,然后又从前往后比较 end--; if (a[end] <= key) { int temp = a[end]; a[end] = a[start]; a[start] = temp; } // 从前往后比较 while (end > start && a[start] <= key)// 如果没有比关键值大的,比较下一个,直到有比关键值大的交换位置 start++; if (a[start] >= key) { int temp = a[start]; a[start] = a[end]; a[end] = temp; } // 此时第一次循环比较结束,关键值的位置已经确定了。左边的值都比关键值小,右边的值都比关键值大,但是两边的顺序还有可能是不一样的,进行下面的递归调用 } // 递归 if (start > low) sort(a, low, start - 1);// 左边序列。第一个索引位置到关键值索引-1 if (end < high) sort(a, end + 1, high);// 右边序列。从关键值索引+1到最后一个 }
(4)选择排序:
对于给定的一组记录,经过第一轮比较后得到最小的记录,然后将该记录与第一个记录的位置进行交换;接着对不包括第一个记录以外的其他记录进行第二轮比较,得到最小的记录并与第二个记录进行位置交换;重复该过程,直到进行比较的记录只有一个时为止。
public class Test2 { /** * 平均O(n^2),最好O(n^2),最坏O(n^2);空间复杂度O(1);不稳定;简单 */ public static void selectSort(int[] a){ for(int i=0;i<a.length-1;i++){ int k=i; for(int j=k+1;j<a.length;j++){ if(a[j]<a[k]){ k=j;//记下目前找到的最小值所在的位置 } } if(i!=k){ int temp=a[i]; a[i]=a[k]; a[k]=temp; } } } public static void main(String[] args) { int a[]={7,55,8,4,2,5}; selectSort(a); for(int i=0;i<a.length;i++){ System.out.println(a[i]); } } }