排序用到的结构与函数
#define MaxSize 100
typedef struct SqList{
int r[MaxSize];
int length;
}SqList;
void swap(SqList *L, int i, int j){
int temp=L->r[i];
L->r[i]=L->r[j];
L->r[j]=temp;
}
1.冒泡排序
void BubbleSort(SqList *L){
int i, j;
for(i=1; i<L->length; i++)
for(j=L->length-1; j>=i; j--)
if(L->r[j]>L->r[j+1])
swap(L,j,j+1);
}
冒泡排序改进版
void BubbleSort2(SqList *L){
int i, j;
bool flag=true;
for(i=1; i<L->length && flag; i++){
flag=false;
for(j=L->length-1; j>=i; j--)
if(L->r[j]>L->r[j+1]){
swap(L,j,j+1);
flag=true;
}
}
}
2.选择排序
void SelectSort(SqList *L){
int i, j, min;
for(i=1; i<L->length; i++){
min=i;
for(j=i+1; j<=L->length; j++)
if(L->r[min]>L->r[j])
min=j;
if(min!=i)
swap(L,i,min);
}
}
3.直接插入排序
void InsertSort(SqList *L){
int i, j;
for(i=2; i<=L->length; i++)
if(L->r[i]<L->r[i-1]){
L->r[0]=L->r[i]; //设置哨兵 或者也可以用一个tmp来记录
for(j=i-1; L->r[j]>L->r[0]; j--)
L->r[j+1]=L->r[j];
L->r[j+1]=L->r[0];
}
}
4.希尔排序
void ShellSort(SqList *L){
int i, j;
int increment=L->length;
do{
increment=increment/3+1;
for(i=increment+1; i<=L->length; i++)
if(L->r[i]<L->r[i-increment]){
L->r[0]=L->r[i]; //设置哨兵
for(j=i-increment; j>0 && L->r[j]>L->r[0]; j-=increment)
L->r[j+increment]=L->r[j];
L->r[j+increment]=L->r[0];
}
}while(increment>1);
}
5.堆排序
/* 已知L->r[s..m]中记录的关键字除L->r[s]之外均满足堆的定义*/
/* 本函数调整L->r[s]的关键字,使L->r[s..m]成为一个大顶堆*/
void HeapAdjust(SqList *L, int s, int m){
int temp, j;
temp = L->r[s];
for(j=2*s; j<=m; j*=2){
if(j<m && L->r[j]>L->r[j+1]) //看是否有右儿子
j++;
if(temp>L->r[j])
break;
L->r[s]=L->r[j];
s=j;
}
L->r[s]=temp;
}
void HeapSort(SqList *L){
int i;
for(i=L->length/2; i>0; i--)
HeapAdjust(L, i, L->length);
for(i=L->length; i>1; i--){
swap(L,1,i);
HeapAdjust(L,1,i-1);
}
}
6.归并排序
/*归并排序*/
void MergeSort(SqList *L){
Merge(L->r, L->r, 1, L->length);
}
/*将SR[s..t]归并排序为TR1[s..t]*/
void MSort(int SR[], int TR1[], int s, int t){
int m;
int TR2[MaxSize+1];
if(s==t) TR1[s]=SR[s];
else{
m=(s+t)/2;
MSort(SR,TR2,s,m);
MSort(SR,TR2,m+1,t);
Merge(TR2,TR1,s,m,t);//将TR2[s..m]和TR2[m+1..t]归并到TR1[s..t]
}
}
/*将有序的SR[i..m]和SR[m+1..n]归并为有序的TR[i..n]*/
void Merge(int SR[], int TR[], int i, int m, int n){
int j,k,l;
for(j=m+1, k=1; i<=m && j<=n; k++){
if(SR[i]<SR[j])
TR[k]=SR[i++];
else
TR[k]=SR[j++];
}
if(i<=m)
for(i; i<=m; i++)
TR[k++]=SR[i];
if(j<=n)
for(j; j<=n; j++)
TR[k++]=SR[j];
}
归并排序的非递归代码
/*对顺序表L作归并非递归排序*/
void MergeSort2(SqList *L){
int *TR=(int *)malloc(L->length * sizeof(int));
int k=1;
while(k<L->length){
MergePass(L->r, TR, k, L->length);
k=2*k;
MergePass(TR, L->r, k, L->length);
k=2*k;
}
}
/*将SR[]中相邻长度为s的子序列两两归并到TR[]*/
void MergePass(int SR[], int TR[], int s, int n){
int i=1;
int j;
while(i <= n-2*s+1){
Merge(SR, TR, i, i+s-1, i+2*s-1);
i=i+2s;
}
if(i<n-s+1) /*归并最后两个序列*/
Merge(SR, TR, i, i+s-1, n);
else
for(j=i; j<=n; j++)
TR[j]=SR[j];
}
7.快速排序
/*快速排序*/
void QuickSort(SqList *L){
QSort(L,1,L->length);
}
void QSort(SqList *L, int low, int high){
int pivot;
if(low<high){
pivot = partition(L,low,high);
QSort(L,low,pivot-1);
QSort(L,pivot+1,high);
}
}
/*交换顺序表L中的子表记录,使枢轴记录到位,并返回其所在位置*/
/*此时在它之前(后)的记录均不大(小)于它*/
void partition(SqList *L, int low, int high){
int pivotkey;
pivotkey = L->r[low];
while(low<high){
while(low<high && L->r[high]>=pivotkey)
--high;
swap(L,low,high);
while(low<high && L->r[low]<=pivotkey)
++low;
swap(L,low,high);
}
return low;
}
快速排序的优化
1.化选取枢轴(三数取中法 和 九数取中法)
int pivotkey;
int m = low + (high-low)/2;
if(L->r[low]>L->r[high]) swap(L,low,high);
if(L->r[m]>L->r[high]) swap(L,high,m);
if(L->r[m]>L->r[low]) swap(L,m,low);
/*此时L->r[low]已经为整个序列左中右三个关键字的中间值*/
pivotkey=L->r[low];
2.优化不必要的交换(用替换代替交换)
int partition1(SqList *L, int low, int high){
int pivotkey;
//这里省略三数取中代码
pivotkey=L->r[low];
L->r[0]=pivotkey; //将枢轴关键字备份到L->r[0]
while(low<high){
while(low<high && L->r[high]>=pivotkey)
high--;
L->r[low]=L->r[high];
while(low<high && L->r[low]<=pivotkey)
low++;
L->r[high]=L->r[low];
}
L->r[low] = L->r[0];
return low; //返回枢轴所在位置
}
3.优化小数组时的排序方案
#define MAX_LENGTH_INSERT_SORT 7 //数组长度阀值
void QSort(SqList &L, int low, int high){
int pivot;
if((high-low)>MAX_LENGTH_INSERT_SORT){
pivot=Partition(L,low,high);
QSort(L,low,pivot-1);
QSort(L,pivot,high);
}
else InsertSort(L);
}
4.优化递归操作
void QSort1(SqList *L, int low, int high){
int pivot;
if((high-low)>MAX_LENGTH_INSERT_SORT)
while(low<high){
pivot=Partition(L,low,high);
QSort(L,low,pivot);
low=pivot+1;
}
else InsertSort(L);
}