简单选择排序
基本操作
1.首先通过n-1次关键字比较,从n个记录中找出关键字最小的记录,将它与第一个记录交换
2.再通过n-2次比较,从剩余的n-1个记录中找出关键字次序最小的记录,将它与第二个记录交换
3.重复上面操作,共进行n-1趟排序后,排序结束
代码
void Select_Sort(Sq_List& L)
{
for(int i=0;i<n;i++)
{
//找最小值并记录
int k=i;
for(int j=i+1;j<n;j++)
{
if(L.r[k].key>L.r[j].key)
k=j;
}
//交换
if(k!=i)
{
Red_Type temp=L.r[i];
L.r[i]=L.r[k];
L.r[k]=temp;
}
}
}
堆排序
基本操作
大根堆的排序:
1.输出堆顶元素,以堆中最后一个元素代替之
2.然后又将根结点与左、右子树的根结点进行比较,并与其中大者进行交换
3.重复上述操作,直至叶子结点,将得到新的堆,称这个从堆顶至叶子的调整过程为“筛选”
堆建立:
单结点的二叉树是堆
在完全二叉树中所有以叶子结点(序号i>n/2)为根的子树是堆
这样,我们只需一次将以序号为n/2,n/2-1……1的结点为根的子树调整为堆即可
(对应由n个元素组成的无序序列,“筛选”只需从第n/2个元素开始)
代码
//堆调整
//已知R[s...m]中记录的关键字除R[s]之外均满足堆的定义
//本函数调整R[s]的关键字,使R[s...m]成为一个大根堆
void Heap_Adjust(T R[],int s,int m)
{
T rc=R[s]; //不满足堆定义的R[s]拿出来
//j是R[s]的左孩子,j+1是右孩子,m是终止结点
//每次调整要到叶子结点为止
for(int j=2*s,j<=m;j=2*j)
{
//j在范围内,找比较大的j
if(j<m&&R[j]<R[j+1])
j++; //j是两个孩子中key最大的
if(rc>=R[j])//rc是R[s],R[s]>=R[j],满足堆定义,跳出
break;
R[s]=R[j];//将R[s]和R[j]交换
s=j; //将光标移到j上
}
R[s]=rc; //此时s的值变化了,相当于做交换
}
void Heap_Sort(T R[])
{
int i;
//堆的建立
for(int i=n/2;i>=1;i--)
{
Heap_Adjust(R,i,n);
}
//调整+排序
//进行n-1次排序
for(i=n;i>1;i--)
{
Swap(R[1],R[i]); //将根与最后一个元素交换
Heap_Adjust(R,1,i-1); //重新调整为堆
}
}
//交换
void Swap(T &a,T &b)
{
T temp=a;
a=b;
b=temp;
}