1. 快速排序
void qsort(int low, int high, int a[])
{
int x = a[low];
int i = low, j = high;
if(low>=high)
return;
while(i<j)
{
while(i<j&&a[j]>=x)
j--;
a[i] = a[j];
while(i<j&&a[i]<=x)
i++;
a[j] = a[i];
}
a[i] = x;
qsort(low, i-1, a);
qsort(i+1, high, a);
}
2.归并排序
归并排序其实要做两件事:
(1)“分解”——将序列每次折半划分。
(2)“合并”——将划分后的序列段两两合并后排序。
void Merge(int a[], int low, int mid, int high)
{
int i = low;//第一段序列的下标
int j = mid + 1;//第二段序列的下标
int k = 0;//暂存数组的下标
int *b = (int *)malloc((high - low + 1)*sizeof(int));//暂存数组动态分配内存
while(i<=mid&&j<=high)// 判断第一段和第二段取出的数哪个更小,将其存入合并序列,并继续向下遍历
{
if(a[i]<a[j])
b[k++] = a[i++];
else
b[k++] = a[j++];
}
while(i<=mid)// 若第一段序列还没遍历完,将其剩余全部复制到合并序列
b[k++] = a[i++];
while(j<=high)// 若第二段序列还没遍历完,将其剩余全部复制到合并序列
b[k++] = a[j++];
for(k=0, i=low; i<=high; i++, k++)// 将合并序列复制到原始序列中
a[i] = b[k];
}
void mergesort(int a[], int low, int high)
{
int mid;
if(low<high)
{
mid = (low + high)/2;
mergesort(a, low, mid); //递归划分并归并
mergesort(a, mid+1, high);
Merge(a, low, mid, high);
}
}
3. 希尔排序:将无序数组分割为若干个子序列,子序列不是逐段分割的,而是相隔特定的增量的子序列,对各个子序列进行插入排序;
然后再选择一个更小的增量,再将数组分割为多个子序列进行排序,最后选择增量为1,即使用直接插入排序,使最终数组成为有序数组。
void shellsort(int a[], int n)
{
int i, j, d, t;
for(d = n/2; d>0; d/=2)
for(i = d; i<n; i++)
for(j = i-d; j>=0; j-=d)
{
if(a[j]>a[j+d])
{
t = a[j];
a[j] = a[j+d];
a[j+d] = t;
}
}
}
4. 堆排序
筛选:
(1). 根节点与最后一个节点元素交换;
(2). 左右子树比较选择较大者与堆顶记录数比较,取最大值置于根节点;
(3). 依次遍历改变后的子树的结点,将左右子树较大者与堆顶记录数进行比较, 取最大值置于结点处;
建堆:
(1). 建大顶堆,从最后一个有子树的结点起逐渐向上调整;
(2). 依次进行筛选直到堆顶记录数取遍所有元素;
void HeapAdjust (int a[], int s, int m) //筛选
{
int j;
int rc=a[s];//根节点(堆顶记录数)
for (j=2*s; j<=m; j*=2)//从每个节点的左子树开始遍历
{
if (j<m&&a[j]<a[j+1]) //比较左右子树取较大值
++j;
if (rc>a[j]) //若当前节点大于其左右子树则无需交换
break;
a[s] = a[j];
s=j;
}
a[s] = rc; //将堆顶记录数存到最后一个比较的位置
} // HeapAdjust
void HeapSort (int a[])
{
int i, t;
for (i=n/2; i>0; --i) //建大顶堆,从最后一个有子树的节点起逐渐向上调整
HeapAdjust (a, i, n);
printf("%d", a[1]);
for (i=n; i>1; --i) //依次进行筛选
{
t = a[1];
a[1] = a[i];
a[i] = t; //将堆顶元素与当前未经排序的序列的最后一个元素进行交换
HeapAdjust (a, 1, i-1);
printf(" %d", a[1]);
}
}