数据结构常用内排序
插入排序
直接插入排序:依次将待排序序列中的每一条记录插入到一个已经排好序的序列中,直到全部的记录都排好序。
在最好情况下,待排序序列为正序,每趟只需与有序序列的最后一个记录的关键码比较。总的比较次数为n-1,因此,时间复杂度为O(n)。在最坏情况下,待排序序列为逆序,第i个记录必须与前i-1个记录的关键码做比较,并且每比较一次就要做一次记录的移动,则移动的次数为 : $\sum_{i=1}^n n= \frac{n(n-1)}{2}$,因此,时间复杂度为$O(n^2)$。 直接插入排序是一种稳定的排序方法12345678910void InsertSort(int r[],int len){for(int i = 1;i<len;i++){int temp = r[i];int j;for(j = i-1;j>=0&&r[j]>temp;j--){r[j+1] = r[j];}r[j+1] = temp;}}希尔排序:先将整个待排序记录序列分割成若干个子序列,在子序列内分别进行直接插入排序,待整个序列基本有序时,再对全体记录进行一次直接插入排序。希尔排序算法的时间性能分析是一个复杂的问题,因为它是所取增量的函数。有人在大量实验的基础上指出,希尔排序的时间性能在$O(n^2)$和O(nlog2n)。希尔排序是一种不稳定的排序方法
123456789101112void ShellSort(int r[],int n){for(int d = n/2;d>=1;d = d/2){for(int j = d;j<=n;j++){int temp = r[j];int i;for(i = j-d;i>=0&&r[i]>temp;i = i-d){r[i+d] = r[i];}r[i+d] = temp;}}}
交换排序
起泡排序:两两比较相邻记录的关键码,如果反序则交换,直到没有反序的记录为止。在最好的情况下,待排序的记录为正序时,算法只执行一趟,进行了n-1次关键码的比较,不需要移动记录,时间复杂度为O(n),在最坏的情况下,待排序的记录为反序,每趟排序在无序序列中只有一个最大的记录被交换到最终位置,故算法执行n-1趟,第i(1<=i<n)趟排序执行了n-i次关键码的比较和n-i次记录的交换,这样,关键码的比较次数为$\sum_{i=1}^{n-1} (n-i)= \frac{n(n-1)}{2}$,因此,时间复杂度为$O(n^2)$。起泡排序是一种稳定的排序方法。
123456789101112131415void Bubble(int r[],int len){int exchange = len;while(exchange!=0){int bound = exchange;exchange = 0;for(int i = 0;i<bound-1;i++){if(r[i]>r[i+1]){int temp = r[i];r[i] = r[j+1];r[j+1] = temp;exchange = i+1;}}}}快速排序:首先选取一个轴值(即比较的基准),将待排序的记录划分为两个独立的两部分,左侧记录的关键码均小于或等于轴值,右侧记录的关键码均大于或等于轴值,然后分别对这两部分重复上述过程。快速排序的平均复杂度为O(nlog2n) 快速排序是一种不稳定的排序方法
123456789101112131415161718192021222324252627282930/*快速排序的一次划分算法*/int partition(int r[],int first,int end){int i = first,j = end-1;while(i<j){while(i<j&&r[i]<=r[j]) j--;if(i<j){int temp = r[i];r[i] = r[j];r[j] = temp;i++;}while(i<j&&r[i]<r[j]) i++;if(i<j){int temp = r[i];r[i] = r[j];r[j] = temp;j--;}}}/*快速排序算法*/void quickSort(int r[],int len){int pivot = partition(r,0,len-1);quickSort(r,0,pivot-1);quickSort(r,pivot+1,len-1);}
选择排序
简单选择排序:第i趟排序在待排序序列r[i]~rn中选取关键码最小的记录,并和第i个记录交换作为有序序列的第i个记录。平均复杂度为$O(n^2)$,选择排序是一种不稳定的排序方法
123456789101112131415void selectSort(int r[],int len){for(int i = 0;i<len-1;i++){int index = i;for(int j = i+1;j<len;j++){if(r[j]>r[index]){index = j;}}if(index!=i){int temp = r[i];r[i] = r[index];r[index] = temp;}}}堆排序:首先将待排序的记录序列构造成一个堆,此时,选出了堆中所有记录的最大值即堆顶记录,然后将该堆顶记录移走,并将剩余的记录再调整成堆,这样又找出了次大的记录。依次类推,直到堆中只有一个记录为止。总的时间复杂度为O(nlog2n)。 堆排序是一种不稳定的排序方法
1234567891011121314151617181920212223242526void shift(int r[],int k,int m){int i = k,j = 2*i;while(j<m){if(r[j]<r[j+1]) j++;if(r[i]>r[j]) break;else{int temp = r[i];r[i] = r[j];r[j] = temp;i = j;j = 2*i;}}}void HeapSort(int r[], int n){for(int i = n/2;i>=1;i--){shift(r,i,n);}for(int i = 1;i<n;i++){int temp = r[1];r[1] = r[n-i+1];r[n-i+1] = temp;shift(r,1,n-i);}}