八大排序总结

来源:互联网 发布:天小猫淘宝信誉查询 编辑:程序博客网 时间:2024/06/03 19:03

1. 插入排序—直接插入排序(Straight Insertion Sort)

顾名思义,直接插入排序就是将一个记录插入一个已经排好序的数组中,使原本排好序的数组添加了一个记录并且继续保持排好序。如果在比较时两个记录相等,则把插入的记录放到原先记录的后面,所以插入排序是稳定的。

时间复杂度:O(n^2)

void InsertSort(int a[], int n)  {      for(int i= 1; i<n; i++){        int j= i;//插入位置         int x = a[i];//插入有序数组的记录         while(x < a[j - 1]){//比较,查找在有序数组的插入位置              a[j] = a[j - 1];//数组后边的记录后移             j--;//新记录前移        }          a[j] = x;//找到正确的位置,插入    }  }  

2. 快速排序(Quick Sort)

快排的基本思路不难理解,主要是优化方面比较难。

基本思路:在数组选出一个基准点 key ,把它放在一个位置使得在它后边的数都比它大(或者相等),在它前边的数都比它小(或者相等)。在这里我们选取数组的第一个记录作为 key ,然后把它拿出来,这样就空下一个位了,我们设置两个”寻找者“---- first 和 last,初始化为数组头和数组尾,因为第一个空位在数组前,那么我们就从数组尾找,last 就从尾部开始找,当找到了一个比 key 小的数(或者等于),那么就可以把它移到原先的空位,同时也产生了一个新的空位,同样地,我们就让 first 寻找合适的数来填上,当 last == first 时,那个位置就是 key 的咯。这样第一轮就结束了,接着,把数组分成两份再次用同样的方法进行寻找(其实这种就是分治的思路),直到数组被分得只有一个。

复杂度分析:当每次找得的 key 都是数组的中间位置,那么复杂度就最好的咯,也就是 O(nlogn),如果每次找得的 key 都是数组的第一个位置(也就是数组已经是排好序的),那么复杂度就是最差的,O(n²)。因此,key的选取关系到复杂度,很多优化都是围绕 key 的选取,有的选取数组第一,中间,末尾三个位置的中间值(三平均分区法),也有的让 key 随机选取(随机化快排)等等。快排过程中相同值的记录有可能调换位置,所以快排是不稳定的。


void Qsort(int a[], int low, int high){if(low < high){int first = low;int last = high;int key = a[first];while(first < last){while(first < last && a[last] >= key){last--;}a[first] = a[last];while(first < last && a[first] <= key){first++;}a[last] = a[first];}a[first] = key;Qsort(a, low, first - 1);Qsort(a, first + 1, high);}} 


3. 归并排序(Quick Sort)

归并排序同样也是利用分治的思想,相比快排,其复杂度是稳定的。

基本思路:将数组分成两个排好序的数组,分别储存在两个其他数组中,然后把它们归并到原来的数组中(因为两个数组都是排好序的,所以很容易实现)。那么如何将原来的数组得到两个排好序的数组呢?就是使用分治,把数组分成两半,每一部分都是利用相似的办法处理,最终 dfs 回来的就是一个排好序的数组。在归并过程中可以使相同值的记录保持原来的排序,所以该算法是稳定的。

复杂度分析:各种请况的复杂度都是一样的,即是O(nlogn)



int L[N], R[N];void MergeSort(int a[], int p, int q){if(p < q){int m = (q - p) / 2 + p;MergeSort(a, p, m);MergeSort(a, m + 1, q);int l = 0, r = 0;for(int i = p; i <= m; i++){L[l++] = a[i];}L[l] = INT_MAX;for(int i = m + 1; i <= q; i++){R[r++] = a[i];}R[r] = INT_MAX;l = 0; r = 0;for(int i = p; i <= q; i++){if(L[l] <= R[r]){a[i] = L[l++];}else{a[i] = R[r++];}}}}


4. 选择排序(Selection Sort)

选择排序比较简单,比较好理解。

基本思路:每次找出最小值,然后进行交换。但交换过程有可能把相同值的记录的相对位置交换,导致算法不稳定(比如:5,4, 5, 2, 3 这一组,第一轮交换把第一个 5 和 2 交换,导致两个 5 的相对位置变了)

复杂度分析:算是一种朴素的算法,复杂度为 O(n²)


void SelectionSort(int a[], int p, int q){for(int i = p; i <= q; i++){int min = i;for(int j = i + 1; j <= q; j++){if(a[min] > a[j]){min = j;}}swap(a[i], a[min]);}}


其他的以后再补充。。。
原创粉丝点击