@MrXiao
2018-03-07T11:48:08.000000Z
字数 2769
阅读 1141
算法
我们通常所说的排序算法往往指的是内部排序算法,即数据记录在内存中进行排序。
排序算法大体可分为两种:

冒泡排序算法的运作如下:
由于它的简洁,冒泡排序通常被用来对于程序设计入门的学生介绍算法的概念。冒泡排序的代码如下:
/*** 冒泡排序算法:平均o(n^2) 稳定 相邻两个比较,最大或最小的移到最右边** @author xiaoyue* @created @2018年3月6日-下午7:16:01**/public class BubbleSort {public static void main(String[] args) {int A[] = { 6, 5, 3, 1, 8, 7, 2, 4 }; // 从小到大冒泡排序int size = A.length;for (int i = 0; i < size - 1; i++) {// 每次最大元素就像气泡一样"浮"到数组的最后for (int j = 0; j < size - 1 - i; j++) { //依次比较相邻的两个元素,使较大的那个向后移if (A[j] > A[j + 1]) { // 如果条件改成A[j] >= A[j + 1],则变为不稳定的排序算法int temp = A[j];A[j] = A[j + 1];A[j + 1] = temp;}}}for (int i = 0; i < size; i++) {System.out.print(A[i] + ", ");}}}
选择排序也是一种简单直观的排序算法。它的工作原理很容易理解:初始时在序列中找到最小(大)元素,放到序列的起始位置作为已排序序列;然后,再从剩余未排序元素中继续寻找最小(大)元素,放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。
注意选择排序与冒泡排序的区别:冒泡排序通过依次交换相邻两个顺序不合法的元素位置,从而将当前最小(大)元素放到合适的位置;而选择排序每遍历一次都记住了当前最小(大)元素的位置,最后仅需一次交换操作即可将其放到合适的位置。
public static void main(String[] args) {int A[] = { 8, 5, 2, 6, 9, 3, 1, 4, 0, 7 }; // 从小到大选择排序int size = A.length;for (int i = 0; i < size - 1; i++) {//循环比对次数,除了最后一个数int min = i;for (int j = i + 1; j < size; j++) {//选择用来比对的数,从当前下一位到最后一位if (A[j] < A[min]) {min = j;}}if (min != i) { //放到已排序序列的末尾,该操作很有可能把稳定性打乱,所以选择排序是不稳定的排序算法int temp = A[i];A[i] = A[min];A[min] = temp;}}for (int i = 0; i < size; i++) {System.out.print(A[i] + ", ");}}
具体算法描述如下:
public static void main(String[] args) {int A[] = { 6, 5, 3, 1, 8, 7, 2, 4 };// 从小到大插入排序int size = A.length;for (int i = 1; i < size; i++) {int get = A[i];// 右手抓到一张扑克牌int j = i - 1;// 拿在左手上的牌总是排序好的while (j >= 0 && A[j] > get) {// 将抓到的牌与手牌从右向左进行比较A[j + 1] = A[j];// 如果该手牌比抓到的牌大,就将其右移j--;}A[j + 1] = get;// 直到该手牌比抓到的牌小(或二者相等),将抓到的牌插入到该手牌右边//(相等元素的相对次序未变,所以插入排序是稳定的)}for (int i = 0; i < size; i++) {System.out.print(A[i] + ", ");}}
快速排序使用分治策略(Divide and Conquer)来把一个序列分为两个子序列。步骤为:
public static void main(String[] args) {int a[] = { 49, 37, 65, 97, 76, 13, 27, 49, 78 };int low = 0;int high = a.length-1;quickSort(a, low, high);for (int i = 0; i < a.length; i++) {System.out.print(a[i]+" ");}}private static void quickSort(int[] a, int low, int high) {int i = low,j = high;if (i > j) {return;}while (i < j) {while (i<j && a[j]>=a[low]) {//从后往前找小于基准数的位置j--;}while (i<j && a[i]<=a[low]) {//从前往后找大于基准数的位置i++;}if (i < j) {//注意,i,j不能相遇或交叉swap(a,i,j);}}swap(a, low, j);quickSort(a, low, j-1);quickSort(a, j+1, high);}
Java系统提供的Arrays.sort函数。对于基础类型,底层使用快速排序。对于非基础类型,底层使用归并排序。请问是为什么?
答:这是考虑到排序算法的稳定性。对于基础类型,相同值是无差别的,排序前后相同值的相对位置并不重要,所以选择更为高效的快速排序,尽管它是不稳定的排序算法;而对于非基础类型,排序前后相等实例的相对位置不宜改变,所以选择稳定的归并排序。