1、堆排序的过程
2、堆排序的另一种形式
#include <stdio.h>
#define MAXE 20 /*线性表中最多元素个数*/
typedef int KeyType;
typedef char InfoType[10];
typedef struct /*记录类型*/
{
KeyType key; /*关键字项*/
InfoType data; /*其他数据项,类型为InfoType*/
} RecType;
void DispHeap(RecType R[],int i,int n) /*以括号表示法输出建立的堆*/
{
if (i<=n)
printf("%d",R[i].key); /*输出根结点*/
if (2*i<=n || 2*i+1<n)
{
printf("(");
if (2*i<=n)
DispHeap(R,2*i,n); /*递归调用输出左子树*/
printf(",");
if (2*i+1<=n)
DispHeap(R,2*i+1,n); /*递归调用输出右子树*/
printf(")");
}
}
void Sift(RecType R[],int low,int high) /*调整堆*/
{
int i=low,j=2*i; /*R[j]是R[i]的左孩子*/
RecType temp=R[i];
while (j<=high)
{
if (j<high && R[j].key<R[j+1].key) /*若右孩子较大,把j指向右孩子*/
j++; /*变为2i+1*/
if (temp.key<R[j].key)
{
R[i]=R[j]; /*将R[j]调整到双亲结点位置上*/
i=j; /*修改i和j值,以便继续向下筛选*/
j=2*i;
}
else break; /*筛选结束*/
}
R[i]=temp; /*被筛选结点的值放入最终位置*/
}
void HeapSort(RecType R[],int n) /*对R[1]到R[n]元素实现堆排序*/
{
int i;
RecType temp;
for (i=n/2;i>=1;i--) /*循环建立初始堆*/
Sift(R,i,n);
printf(" 初始堆:");DispHeap(R,1,n);printf("\n"); /*输出初始堆*/
for (i=n;i>=2;i--) /*进行n-1次循环,完成推排序*/
{
printf(" 交换%d与%d,输出%d\n",R[i].key,R[1].key,R[1].key);
temp=R[1]; /*将第一个元素同当前区间内R[1]对换*/
R[1]=R[i];
R[i]=temp;
Sift(R,1,i-1); /*筛选R[1]结点,得到i-1个结点的堆*/
printf(" 筛选调整得到堆:");DispHeap(R,1,i-1);printf("\n"); /*输出每一趟的排序结果*/
}
}
int main()
{
int i,k,n=12;
KeyType a[]={142,543,123,65,453,879,572,434,111,242,811,102};
RecType R[MAXE];
for (i=1;i<=n;i++)
R[i].key=a[i-1];
printf("\n");
printf(" 初始关键字 ");
for (k=1;k<=n;k++)
printf("%2d",R[k].key);
printf("\n");
for (i=n/2;i>=1;i--) /*循环建立初始堆*/
Sift(R,i,n);
HeapSort(R,n);
printf(" 最终结果 "); /*输出最终结果*/
for (k=1;k<=n;k++)
printf("%d ",R[k].key);
printf("\n\n");
}
3、归并排序的过程
4、非递归的归并程序
#include<iostream>
using namespace std;
void Merge(int arr[],int low,int mid,int high)//递归和非递归均一样
{//将两个有序区归并为一个有序区
int i=low,j=mid+1,k=0;
int *temp=new(nothrow) int[high-low+1];
while(i<=mid&&j<=high)
{
if(arr[i]<=arr[j])
temp[k++]=arr[i++];
else
temp[k++]=arr[j++];
}
while(i<=mid) temp[k++]=arr[i++];
while(j<=high) temp[k++]=arr[j++];
for(i=low,k=0;i<=high;i++,k++)
arr[i]=temp[k];
delete []temp;
}
void MergeSort(int arr[],int n)//参数和递归略不同,n代表数组中元素个数,即数组最大下标是n-1
{//非递归实现
/*
int step = 1;
while(step<n) //当元素个数不是2的幂时可能会出错,未考虑第2个序列个数不足的情况
{
for(int i=0;i<=n-step-1;i+=2*step)
Merge(arr,i,i+step-1,i+2*step-1);
step*=2;
}*/
int size=1,low,mid,high;
while(size<=n-1)
{
low=0;
while(low+size<=n-1)
{
mid=low+size-1;
high=mid+size;
if(high>n-1)//第二个序列个数不足size
high=n-1;
Merge(arr,low,mid,high);//调用归并子函数
cout<<"low:"<<low<<" mid:"<<mid<<" high:"<<high<<endl;//打印出每次归并的区间
low=high+1;//下一次归并时第一关序列的下界
}
size*=2;//范围扩大一倍
}
}
int main()
{
int x[]={3,1,4,1,5,9,2,6};
MergeSort(x, 8);
for(int i=0;i<8;i++)
cout<<x[i]<<" ";
return 0;
}
5、希尔排序的过程