程序员必知的8大排序
2016-04-14 13:07
471 查看
1, 直接插入排序
(1)基本思想:在要排序的一组数中,假设前面(n-1) [n>=2] 个数已经是排好顺序的,现在要把第n个数插到前面的有序数中,使得这n个数也是排好顺序的。如此反复循环,直到全部排好顺序。
(2)java实现
package sort; public class InsertSort { public static void main(String[] args) { int[] source={591,401,874,141,348,72,911,887,820,283}; sort(source); System.out.println(source[0]+","+source[1]+","+source[2]+","+source[3]+","+source[4]+","+source[5]+","+source[6]+","+source[7]+","+source[8]+","+source[9]); } public static void sort(int[] source){ for (int i = 1; i < source.length; i++) { int temp=source[i]; int j =i-1; for (; (j >=0&&source[j]>temp); j--) { source[j+1]=source[j]; } source[j+1]=temp; } } }
2,希尔排序
(1)基本思想:算法先将要排序的一组数按某个增量d(n/2,n为要排序数的个数)分成若干组,每组中记录的下标相差d.对每组中全部元素进行直接插入排序,然后再用一个较小的增量(d/2)对它进行分组,在每组中再进行直接插入排序。当增量减到1时,进行直接插入排序后,排序完成。希尔排序是不稳定的。
(2)java实现
package sort; public class ShellSort { public static void main(String[] args) { int[] source={591,401,874,141,348,72,911,887,820,283}; sort(source); System.out.println(source[0]+","+source[1]+","+source[2]+","+source[3]+","+source[4]+","+source[5]+","+source[6]+","+source[7]+","+source[8]+","+source[9]); } public static void sort(int[] source){ for (int h=source.length/2;h>0;h=h/2) { // 进行插入排序 for (int i = h; i < source.length; i+=h) { int temp=source[i]; int j =i-h; for (; (j >=0&&source[j]>temp); j-=h) { source[j+h]=source[j]; } source[j+h]=temp; } } } }
3,简单选择排序
(1)基本思想:在要排序的一组数中,选出最小的一个数与第一个位置的数交换;然后在剩下的数当中再找最小的与第二个位置的数交换,如此循环到倒数第二个数和最后一个数比较为止。
(2)java实现
package sort; public class selectSort { public static void main(String[] args) { int[] source={591,401,874,141,348,72,911,887,820,283}; sort(source); System.out.println(source[0]+","+source[1]+","+source[2]+","+source[3]+","+source[4]+","+source[5]+","+source[6]+","+source[7]+","+source[8]+","+source[9]); } public static void sort(int[] source){ for (int i = 1; i < source.length; i++) { int location=i-1; int min=source[i-1]; for (int j=i;j<source.length;j++) { if(source[j]<min){ min=source[j]; location=j; } } if(location!=i-1){ source[location]=source[i-1]; source[i-1]=min; } } } }
4,堆排序
(1)基本思想:采用最大堆的实现方式,k[i]>k[2i],k[i]>k[2i+1],k=[1,n/2]。java数字是从0开始的,所有对应规则为:k[i]>k[2i+1],k[i]>k[2i+2],k=[0,(n-1)/2]。
(2)java实现
package sort; import java.util.Arrays; public class HeapSort { public static void main(String[] args) { int a[] = {591,401,874,141,348,72,911,887,820,283}; heapSort(a); } public static void heapSort(int[] a) { int arrayLength = a.length; // 循环建堆 for (int i = 0; i < arrayLength - 1; i++) { // 建堆 buildMaxHeap(a, arrayLength - 1 - i); // 交换堆顶和最后一个元素 swap(a, 0, arrayLength - 1 - i); } System.out.println(Arrays.toString(a)); } private static void swap(int[] data, int i, int j) { // TODO Auto-generated method stub int tmp = data[i]; data[i] = data[j]; data[j] = tmp; } // 对data数组从0到lastIndex建大顶堆 private static void buildMaxHeap(int[] data, int lastIndex) { // 从lastIndex处节点(最后一个节点)的父节点开始 for (int i = (lastIndex) / 2; i >= 0; i--) { // k保存正在判断的节点 int k = i; // 如果当前k节点的子节点存在 while (k * 2 + 1 <= lastIndex) { // k节点的左子节点的索引 int biggerIndex = 2 * k + 1; // 如果biggerIndex小于lastIndex,即biggerIndex+1代表的k节点的右子节点存在 if (biggerIndex < lastIndex) { // 若果右子节点的值较大 if (data[biggerIndex] < data[biggerIndex + 1]) { // biggerIndex总是记录较大子节点的索引 biggerIndex++; } } // 如果k节点的值小于其较大的子节点的值 if (data[k] < data[biggerIndex]) { // 交换他们 swap(data, k, biggerIndex); // 将biggerIndex赋予k,开始while循环的下一次循环,重新保证k节点的值大于其左右子节点的值 k = biggerIndex; } else { break; } } } } }
5,冒泡排序
(1)基本思想:它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。每次走访都将最大或者最小值放到了数字中最后一个位置,然后对之前的数据在进行走访。
(2)java实现
package sort; public class BubbleSort{ public static void main(String[] args) { int[] source={591,401,874,141,348,72,911,887,820,283}; sort(source); System.out.println(source[0]+","+source[1]+","+source[2]+","+source[3]+","+source[4]+","+source[5]+","+source[6]+","+source[7]+","+source[8]+","+source[9]); } public static void sort(int[] source){ for (int i = 0; i < source.length-1; i++) { for ( int j=0; j < source.length-1-i; j++) { if(source[j]<source[j+1]){ swap(source, j, j+1); } } } } private static void swap(int[] data, int i, int j) { int tmp = data[i]; data[i] = data[j]; data[j] = tmp; } }
6,快速排序
(1)基本思想:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
(2)java实现
package sort; public class QuickSort { public static void main(String[] args) { int[] source={591,401,874,141,348,72,911,887,820,283}; quickSort(source); System.out.println(source[0]+","+source[1]+","+source[2]+","+source[3]+","+source[4]+","+source[5]+","+source[6]+","+source[7]+","+source[8]+","+source[9]); } public static void quickSort(int[] array){ if(array != null){ quickSort(array, 0, array.length-1); } } private static void quickSort(int[] array,int beg,int end){ if(beg >= end || array == null) return; int p = partition(array, beg, end); quickSort(array, beg, p-1); quickSort(array, p+1, end); } private static int partition(int[] array, int beg, int end) { int first = array[beg]; int i = beg, j = end; while (i < j) { while (array[i] <= first && i < end) { i++; } while (array[j] > first && j >= beg) { j--; } if (i < j) { array[i] = array[i] ^ array[j]; array[j] = array[i] ^ array[j]; array[i] = array[i] ^ array[j]; } } if (j != beg) { array[j] = array[beg] ^ array[j]; array[beg] = array[beg] ^ array[j]; array[j] = array[beg] ^ array[j]; } return j; } }
7,归并排序
(1)基本思想:假设初始序列有n个记录,则可以看成是n个有序的子序列,每一个子序列的长度为1,然后两两归并,得到[n/2]个长度为2或者1的有序子序列;再两两归并......,如此重复,知道得到一个长度为n的有序序列为止。
(2)java实现
package sort; import java.util.Arrays; public class MergeSort { /** * 归并排序 * 简介:将两个(或两个以上)有序表合并成一个新的有序表 即把待排序序列分为若干个子序列,每个子序列是有序的。然后再把有序子序列合并为整体有序序列 * 时间复杂度为O(nlogn) * 稳定排序方式 * @param nums 待排序数组 * @return 输出有序数组 */ public static int[] sort(int[] nums, int low, int high) { int mid = (low + high) / 2; if (low < high) { // 左边 sort(nums, low, mid); // 右边 sort(nums, mid + 1, high); // 左右归并 merge(nums, low, mid, high); } return nums; } public static void merge(int[] nums, int low, int mid, int high) { int[] temp = new int[high - low + 1]; int i = low;// 左指针 int j = mid + 1;// 右指针 int k = 0; // 把较小的数先移到新数组中 while (i <= mid && j <= high) { if (nums[i] < nums[j]) { temp[k++] = nums[i++]; } else { temp[k++] = nums[j++]; } } // 把左边剩余的数移入数组 while (i <= mid) { temp[k++] = nums[i++]; } // 把右边边剩余的数移入数组 while (j <= high) { temp[k++] = nums[j++]; } // 把新数组中的数覆盖nums数组 for (int k2 = 0; k2 < temp.length; k2++) { nums[k2 + low] = temp[k2]; } } // 归并排序的实现 public static void main(String[] args) { int[] source={591,401,874,141,348,72,911,887,820,283}; sort(source, 0, source.length-1); System.out.println(Arrays.toString(source)); } }
相关文章推荐
- 黑马程序员基础评测:Java编程基础
- 2016/4/14腾讯Android实习面试
- LeetCode(56)-Add Binary
- Android常见面试题目
- Hypertable - 程序员指南
- 剑指offer-面试题43:n个骰子的点数
- LeetCode(55)- Palindrome Linked List
- Android面试总结持续更新中
- 那些著名或非著名的iOS面试题(上)
- Web前端开发笔试&面试_02(others)
- IOS 面试题总结
- 面试题84:结点和最大的子树
- 10倍效率的程序员有哪些好习惯?
- 一道有趣的面试题
- iOS程序员须知
- 程序员欢呼:微软Bing开始支持搜索源码、可直接运行
- 大部分人都会做错的经典JS闭包面试题
- 大数据处理面试题
- 个人职业规划
- 前端面试(css篇)