排序算法有很多,包括插入排序,冒泡排序,堆排序,归并排序,选择排序,计数排序,基数排序,桶排序,快速排序等。插入排序,堆排序,选择排序,归并排序和快速排序,冒泡排序都是比较排序,它们通过对数组中的元素进行比较来实现排序,其他排序算法则是利用非比较的其他方法来获得有关输入数组的排序信息。
一、冒泡排序
冒泡排序(Bubble Sort)是一种简单的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。
冒泡排序就是把小的元素往前调或者把大的元素往后调。比较是相邻的两个元素比较,交换也发生在这两个元素之间。所以,如果两个元素相等,我想你是不会再无聊地把他们俩交换一下的;如果两个相等的元素没有相邻,那么即使通过前面的两两交换把两个相邻起来,这时候也不会交换,所以相同元素的前后顺序并没有改变,所以冒泡排序是一种稳定排序算法。
代码实现:
/** * 冒泡排序 * @param scores */ public static void BubbleUPSort(int[] scores) { for (int i = 0; i < scores.length-1; i++) { for (int j = i+1; j < scores.length; j++) { if (scores[i]>scores[j]) { //-----------交换scores[i]与scores[j]的位置----------- int score=scores[j]; scores[j]=scores[i]; scores[i]=score; } } } //输出排序结果 for (int i = 0; i < scores.length; i++) { System.out.print(scores[i]+" "); } }二、选择排序
简单选择排序的基本思想:给定数组:int[] arr={里面n个数据};第1趟排序,在待排序数据arr[1]~arr[n]中选出最小的数据,将它与arrr[1]交换;第2趟,在待排序数据arr[2]~arr[n]中选出最小的数据,将它与r[2]交换;以此类推,第i趟在待排序数据arr[i]~arr[n]中选出最小的数据,将它与r[i]交换,直到全部排序完成。
选择排序是给每个位置选择当前元素最小的,比如给第一个位置选择最小的,在剩余元素里面给第二个元素选择第二小的,依次类推,直到第n-1个元素,第n个元素不用选择了,因为只剩下它一个最大的元素了。那么,在一趟选择,如果一个元素比当前元素小,而该小的元素又出现在一个和当前元素相等的元素后面,那么交换后稳定性就被破坏了。比较拗口,举个例子,序列5 8 5 2 9,我们知道第一遍选择第1个元素5会和2交换,那么原序列中两个5的相对前后顺序就被破坏了,所以选择排序是一个不稳定的排序算法。
代码实现
/** * 选择排序 * @param scores */ public static void SelectionSort(int[] scores) { for (int i = 0; i < scores.length-1; i++) { int minindex=i+1;//用于记录下最小值min的索引 //-------找出索引从i+1到scores.length-1中最小的一个值min--- for (int j = i+1; j < scores.length; j++) { if (scores[minindex]>scores[j]) { minindex=j; } } //-----------将min与scores[i]进行比较----------------- if (scores[i]>scores[minindex]) { int score=scores[i]; scores[i]=scores[minindex]; scores[minindex]=score; } } //输出排序结果 for (int i = 0; i < scores.length; i++) { System.out.print(scores[i]+" "); } }三、插入排序
有一个已经有序的数据序列,要求在这个已经排好的数据序列中插入一个数,但要求插入后此数据序列仍然有序,这个时候就要用到一种新的排序方法——插入排序法,插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得到一个新的、个数加一的有序数据,算法适用于少量数据的排序,时间复杂度为O(n^2)。是稳定的排序方法。插入算法把要排序的数组分成两部分:第一部分包含了这个数组的所有元素,但将最后一个元素除外(让数组多一个空间才有插入的位置),而第二部分就只包含这一个元素(即待插入元素)。在第一部分排序完成后,再将这个最后元素插入到已排好序的第一部分中。 插入排序的基本思想是:每步将一个待排序的纪录,按其关键码值的大小插入前面已经排序的文件中适当位置上,直到全部插入完为止。
插入排序非常类似于整扑克牌。
在开始摸牌时,左手是空的,牌面朝下放在桌上。接着,一次从桌上摸起一张牌,并将它插入到左手一把牌中的正确位置上。为了找到这张牌的正确位置,要将它与手中已有的牌从右到左地进行比较。无论什么时候,左手中的牌都是排好序的。
代码实现 /** * 插入排序 * @param scores */ public static void InsertSort(int[] scores) { for(int i=0;i<scores.length;i++) { int score=scores[i]; while(i>0 && score<scores[i-1]) { scores[i]=scores[i-1]; scores[i-1]=score; } } for (int i = 0; i < scores.length; i++) { System.out.print(scores[i]+" "); } }四、快速排序算法思想:基于分治的思想,是冒泡排序的改进型。首先在数组中选择一个基准点(该基准点的选取可能影响快速排序的效率,后面讲解选取的方法),然后分别从数组的两端扫描数组,设两个指示标志(lo指向起始位置,hi指向末尾),首先从后半部分开始,如果发现有元素比该基准点的值小,就交换lo和hi位置的值,然后从前半部分开始扫秒,发现有元素大于基准点的值,就交换lo和hi位置的值,如此往复循环,直到lo>=hi,然后把基准点的值放到hi这个位置。一次排序就完成了。以后采用递归的方式分别对前半部分和后半部分排序,当前半部分和后半部分均有序时该数组就自然有序了。
排序过程:
代码实现: /** * 快速排序 * @param a * @param left * @param right */ public static void QuickSort(int[] a, int left, int right) { int i, j, t, temp; if (left > right) { return; } temp = a[left]; // temp中存的就是基准数 i = left; j = right; while (i != j) { // 顺序很重要,要先从右边开始找 while (a[j] >= temp && i < j) j--; // 再找右边的 while (a[i] <= temp && i < j) i++; // 交换两个数在数组中的位置 if (i < j) { t = a[i]; a[i] = a[j]; a[j] = t; } } // 最终将基准数归位 a[left] = a[i]; a[i] = temp; QuickSort(a, left, i - 1);// 继续处理左边的,这里是一个递归的过程 QuickSort(a, i + 1, right);// 继续处理右边的 ,这里是一个递归的过程 } 完整代码: package mycompare; public class arrcompare { public static void main(String args[]) throws Exception { int[] scores=new int[]{100,51,31,72,88,99,75,64}; MySort.QuickSort(scores, 0, 7); for (int i = 0; i < scores.length; i++) { System.out.print(scores[i]+" "); } System.out.println(); MySort.BubbleUPSort(scores); System.out.println(); MySort.InsertSort(scores); System.out.println(); MySort.SelectionSort(scores); } } class MySort { /** * 冒泡排序 * * @param scores */ public static void BubbleUPSort(int[] scores) { for (int i = 0; i < scores.length - 1; i++) { for (int j = i + 1; j < scores.length; j++) { if (scores[i] > scores[j]) { // -----------交换scores[i]与scores[j]的位置----------- int score = scores[j]; scores[j] = scores[i]; scores[i] = score; } } } // 输出排序结果 for (int i = 0; i < scores.length; i++) { System.out.print(scores[i]+" "); } } /** * 选择排序 * * @param scores */ public static void SelectionSort(int[] scores) { for (int i = 0; i < scores.length - 1; i++) { int minindex = i + 1;// 用于记录下最小值min的索引 // -------找出索引从i+1到scores.length-1中最小的一个值min--- for (int j = i + 1; j < scores.length; j++) { if (scores[minindex] > scores[j]) { minindex = j; } } // -----------将min与scores[i]进行比较----------------- if (scores[i] > scores[minindex]) { int score = scores[i]; scores[i] = scores[minindex]; scores[minindex] = score; } } // 输出排序结果 for (int i = 0; i < scores.length; i++) { System.out.print(scores[i]+" "); } } /** * 插入排序 * * @param scores */ public static void InsertSort(int[] scores) { for (int i = 0; i < scores.length; i++) { int score = scores[i]; while (i > 0 && score < scores[i - 1]) { scores[i] = scores[i - 1]; scores[i - 1] = score; } } for (int i = 0; i < scores.length; i++) { System.out.print(scores[i]+" "); } } /** * 快速排序 * @param a * @param left * @param right */ public static void QuickSort(int[] a, int left, int right) { int i, j, t, temp; if (left > right) { return; } temp = a[left]; // temp中存的就是基准数 i = left; j = right; while (i != j) { // 顺序很重要,要先从右边开始找 while (a[j] >= temp && i < j) j--; // 再找右边的 while (a[i] <= temp && i < j) i++; // 交换两个数在数组中的位置 if (i < j) { t = a[i]; a[i] = a[j]; a[j] = t; } } // 最终将基准数归位 a[left] = a[i]; a[i] = temp; QuickSort(a, left, i - 1);// 继续处理左边的,这里是一个递归的过程 QuickSort(a, i + 1, right);// 继续处理右边的 ,这里是一个递归的过程 } } 输出: 31 51 64 72 75 88 99 100 31 51 64 72 75 88 99 100 31 51 64 72 75 88 99 100 31 51 64 72 75 88 99 100