【DS】12.排序
概念
1.排序算法等我穩定性:如果a=b,在排序之前,a在b的前面,如果排序之后,a仍然在b的前面,那么算法就是穩定的,否在算法就是不穩定的;
2.內排序和外排序:排序方法根基在排序過程是否完全在內存,分為內排序和外排序。內排序是指在排序期間數據元素全部存放在內存的排序;外排序是指排序期間的全部元素個數太多,不能同時存放在內存,必須根據排序過程的要求,不斷在內存外存之間移動的排序。適用于內部排序的排序方法稱為內部排序方法,反之則為外部排序方法;
?
性能評估
排序的時間開銷可用算法執行的數據比較次數和數據移動次數來衡量。
?
排序算法
插入排序
基本方法:每步將一個待排序的元素,按其排序碼的大小,插入到前面已經排好序的一組元素的適當位置上去,直到元素全部插入位置。可以選擇不同的方法在已經排好序的有序數據表中尋找插入位置。依據查找方法的不同,有多種插入排序法:
1)直接插入排序:假設升序排列,V[2], V[0], V[1]逐漸增大,現在V[3]要參與排序,則先比較V[3],V[1],如果V[3]<V[1],則讓[V3]=V[1],實現將V[3]置于temp中,元素比temp大,就順次往后移動,直到找到插入位置;
2)折半插入排序:折半搜索比順序搜索快,因此折半插入就平均性能來說比直接插入排序要快。在元素的初始排列已經按排好序或者接近有序時,直接插入排序比折半插入排序的排序碼比較次數要少。折半插入排序的元素移動次數與直接插入排序相同,依賴于元素的初始排列。折半插入排序是一個穩定的排序方法。
3)希爾排序:又稱為縮小增量排序。基本思想:設待排序元素序列有n個元素,首先取一個gap<n作為間隔,將全部元素分為gap個自子序列,所有距離為gap的元素放在同一個子序列中,在每一個自序列中分別施行直接插入排序。然后縮小間隔gap,例如取gap=gap/2,重復上述的子序列劃分和排序工作。直到最后gap=1,將所有的元素放在同一個序列中排序為止。整個排序的排序碼比較次數和元素移動次數都比直接插入排序少。它是一種不穩定的排序算法。很多排序應用程序都選用了希爾排序算法。
?
快速排序
也叫分區排序,是目前應用最廣泛的排序,它是不穩定的。快速哦排序算法采用分治法進行排序,其基本思想:任取待排序元素序列中的某個元素(例如第一個元素)作為基準,按照該元素的排序碼大小,將整個元素序列劃分為左右兩子序列,左側子序列中的元素都小于基準元素的排序碼,右側子序列中所有的元素都大于或者等于基準元素的排序碼,基準元素則排在兩個子序列之間。分別對這兩個子序列重復以上的方法,知道所有的元素都排在相應的位置上為止。
此處的元素移動使用的是交換元素的方法。
快速排序源碼:
?
//快速排序法 public class QuickSort {public static void main(String[] args) {// TODO Auto-generated method stubint list[] = {10, 4, 12, 3, 7, 9, 1, 21, 16, 14, 25, 13, 48, 23, 27, 32};//快速排序所用序列int length = list.length;for(int i = 0; i < length; i++){System.out.print(list[i] + " ");}System.out.println();quickSort(list, 0, length-1);for(int i = 0; i < length; i++){System.out.print(list[i] + " ");}}public static void quickSort(int list[], int left, int right){if(left >= right)return;int index = left;int base = list[left];//以left為基準int temp = 0;for(int i = left+1; i <= right; i++){if(list[i] < base){//交換temp = list[i];list[i] = list[index];list[index] = temp;index++;}}list[index] = base;quickSort(list, left, index-1);quickSort(list, index+1, right);} }選擇排序
基本思想:每一趟在后面n-i個待排序元素中選出排序碼最小的元素作為有序元素序列的第i個元素。待到第n-2趟作完,待排序元素只剩下一個就不用再選了。下面是三種選擇排序方法:
1)直接選擇排序:基本步驟:
a)在一組元素V[i]~V[i-1]中選擇具有最小排序碼的元素;
b)若它不是這組元素中的第一個元素,則將它與這一組的第一個元素對調;
c)在這組元素中剔除這個具有最小排序碼的元素,在剩下的元素V[i+1]~V[n-1]中重復執行第a)b)步,直到剩余元素只有一個為止。直接選擇排序是一種不穩定的排序方法;
2)錦標賽排序;
3)堆排序:根據要排序的建立最大(小)堆,然后操作堆,通過刪除元素,調整堆得到排序的結果。
?
歸并排序
歸并排序也是基于分治法的,歸并排序將待排序的元素序列分成兩個長度相等的子序列,為每一個子序列排序,然后再將它們合并成一個序列,合并兩個子序列的過程稱為兩路歸并。歸并算法描述:在執行兩路歸并算法時,先把待歸并元素序列L1復制到輔助數組L2中,再從L2歸并到L1中。在歸并過程中,用變量s1,s2分別做L2中兩個表的當前檢測指針,用變量t做歸并后在L1中的當前存放指針。當S1和S2都在兩個表的表長內變化的時候,根據L2.Vector[s1]與L2.Vector[s2]的排序碼的大小,依次把排序碼小的元素排放到新表L1.Vector[t]中,當S1與S2中有一個已經超出表長時,將另一個表中剩余的部分照抄到新表L1.Vector[]中。
歸并排序的主要問題是它需要一個與原數組一樣大的輔助數組空間。歸并排序是一種穩定的排序方法。
源碼:
public class MergeSort {public static void main(String[] args) {// TODO Auto-generated method stubint list[] = {10, 4, 12, 3, 7, 9, 1, 21, 16, 14, 25, 13, 48, 23, 27, 32};//歸并排序所用序列System.out.print("原先:");for(int i = 0; i < list.length; i++){System.out.print(list[i] + " ");}System.out.println();int arrayTemp[] = new int[list.length];mergeSort(list, arrayTemp, 0, list.length-1);System.out.print("排序:");for(int i = 0; i < list.length; i++){System.out.print(list[i] + " ");}}public static void mergeSort(int originList[], int tempList[], int start, int end){if(start != end){int mid = (start + end) / 2;mergeSort(originList, tempList, start, mid);mergeSort(originList, tempList, mid+1, end);//等于說左邊也排好了,右邊也排好了merge(originList, tempList, start, end);}else{return;}}public static void merge(int originList[], int tempList[], int start, int end){for(int i = 0; i < originList.length; i++){tempList[i] = originList[i];//先復制}int mid = (start + end ) / 2;int indexA = start;int indexB = mid+1;int index = start;while(indexA <= mid && indexB <= end){if(tempList[indexA] < tempList[indexB]){originList[index] = tempList[indexA];indexA++;index++;}else{originList[index] = tempList[indexB];index++;indexB++;}}//完畢的時候while(indexA <= mid){originList[index] = tempList[indexA];index++;indexA++;}while(indexB <= end){originList[index] = tempList[indexB];index++;indexB++;}} }
?
轉載于:https://www.cnblogs.com/lqminn/archive/2012/08/31/2665043.html
總結
- 上一篇: ie6 z-index bug
- 下一篇: android网络编程——HttpGet