交换类排序:根据序列中两个元素关键字的比较结果来交换他俩在序列中的位置。
冒泡排序:假设待排序表长为n,从后往前(或从前往后)两两比较相邻元素的值,若为逆序(即A[i-1]>A[i])则交换他们,直到序列比较完。我们称它为一趟冒泡,结果将最小的元素交换到待排序序列的第一个位置。下一趟冒泡时,前一趟确定的最小元素不再参与比较,待排序列减少一个元素,每趟冒泡的结果把序列中最小元素放到了序列的最终位置,……,这样最多n-1趟冒泡就能把所有元素排好序。
void BubbleSort(ElemType A[],int n){ for(i=0;i<n-1;i++){ bool flag=false; //设置标志位 for(j=n-1;j>i;j--) //一趟冒泡过程 if(A[j-1].key>A[j].key){ //将较小的元素向上移动 ElemType temp=A[j-1].key; A[j-1].key=A[j].key; A[j].key=temp; flag=true; //发生了数据交换,修改标志位 } if(flag==false) return; //如果有一趟没有发生数据交换,表示序列已经完成了排序 } }
空间复杂度:O(1)。
时间复杂度:在最糟糕的情况下,初始序列是逆序的,时间复杂度为O(n2);在最好的情况下,初始序列是顺序的,时间复杂度为O(n)。
稳定性:当两个关键字相同,if的判断条件不成立,不会发生数据的移动,因此是稳定的。
快速排序:一种基于分治法的排序方法。每一趟快排选择序列中任一个元素作为枢轴(pivot)(通常选择第一个元素),将序列中比枢轴小的元素都移到枢轴前边,比枢轴大的元素都移到枢轴后边。其实现为:
int Partition(ElemType A[],int low,int high){ //一次快速排序,low是待排序起始下标,high是待排序末位下表 ElemType pivot=A[low]; //第一个元素作为枢轴 while(low<high){ while(low<high&&A[high]>=pivot) --high; //先从末尾往前找到第一个比枢轴小的元素 A[low]=A[high]; //用high的元素替换low的元素 while(low<high&&A[low]<=pivot) ++low; //再从开头往后找到第一个比枢轴大的元素 A[high]=A[low]; //用low的元素替换high的元素 } A[low]=pivot; //枢轴元素放在最终的位置 return low; //返回放枢轴的最终位置 } void QuickSort(ElemType A[],int low,int high){ if(low<high){ int pivopos=Partition(A,low,high); QuickSort(A,low,pivopos-1); //分治递归左半部分 QuickSort(A,pivopos+1,high); //分治递归右半部分 } }
时间复杂度:最好情况下O(nlogn),待排序数列越无序,算法效率越高;最坏情况下时间复杂度为O(n2),待排序序列越有序,算法效率越低。
稳定性:不稳定,存在交换关键字。