本次介绍选择排序,选择排序共有两个排序方法:
1、简单选择排序——不稳定的排序方法
2、推排序——不稳定的排序方法
首先,还是简单了解一下选择排序的思想:每次从待排序的记录中选出最小的记录,然后把它放在已经有序序列的最前面
然后,同其他排序方法相同,数据存储的结构为:
typedef struct{
int key;
}ElemType;
typedef struct{
ElemType r[MAXSIZE+1];
int length;
}SqList;
简单选择排序一共需要进行n-1趟,每趟比较n-i次,比较出最小的记录,如果不是H.r[i],则进行交换。
简单选择排序的算法如下:
void SimpleSelectSort(SqList &H)
{
int i,j,k;
for(i=1;i<H.length;i++)
{
k=i;
for(j=i+1;j<=H.length;j++)
{
if(H.r[j].key<H.r[k].key)
k=j;
}
if(k!=i)
{
H.r[0]=H.r[i];
H.r[i]=H.r[k];
H.r[k]=H.r[0];
}
}
}
简单选择排序的时间复杂度和空间复杂度为:
T(n)=O(n^2)
S(n)=O(1)
接下来介绍堆排序,堆排序分为小顶堆和大顶堆。
小顶堆选择排序后 -> 非递增序列
大顶堆选择排序后 -> 非递减序列
如果想要运用堆排序,现需要进行初建堆操作。如果把记录看成一个完全二叉树的话,我们应该先寻找第一个非叶子结点,然后从第一个非叶子结点到最后一个结点进行堆排序。第一个非叶子结点为:H.length/2。
初建堆完成以后,进行排序操作,把第一个记录和最后一个记录进行交换,然后把第一个结点和他的左右孩子(假设第一个结点为s,左孩子就为2s,右孩子为2s+1)的关键字大小进行比较,把其中较大的记录放到堆顶,然后依次类推,直到确定最小的记录的位置。
下面为推排序的算法:
void HeapAdjust(SqList &H,int s,int m)
{
ElemType rc;
rc=H.r[s];
int j;
for(j=2*s;j<=m;j*=2)
{
if(j<m&&H.r[j].key<H.r[j+1].key)
j++;
if(rc.key>H.r[j].key)
break;
H.r[s]=H.r[j];
s=j;
}
H.r[s]=rc;
}
void Heap(SqList &H)
{
int i;
for(i=H.length/2;i>0;i--)//从第一个非叶子结点开始
HeapAdjust(H,i,H.length);//先把顺序表排序成为大顶堆
for(i=H.length;i>1;i--)
{
H.r[0]=H.r[1];
H.r[1]=H.r[i];
H.r[i]=H.r[0];
HeapAdjust(H,1,i-1);
}
}
堆排序的时间复杂度和空间复杂度:
T(n)=O(nlog2n)
S(n)=O(1)
选择排序完整的程序如下:
#include<stdio.h>
#include<iostream>
using namespace std;
#define MAXSIZE 20
typedef struct{
int key;
}ElemType;
typedef struct{
ElemType r[MAXSIZE+1];
int length;
}SqList;
SqList H;
void SimpleSelectSort(SqList &H)
{
int i,j,k;
for(i=1;i<H.length;i++)
{
k=i;
for(j=i+1;j<=H.length;j++)
{
if(H.r[j].key<H.r[k].key)
k=j;
}
if(k!=i)
{
H.r[0]=H.r[i];
H.r[i]=H.r[k];
H.r[k]=H.r[0];
}
}
}
void HeapAdjust(SqList &H,int s,int m)
{
ElemType rc;
rc=H.r[s];
int j;
for(j=2*s;j<=m;j*=2)
{
if(j<m&&H.r[j].key<H.r[j+1].key)
j++;
if(rc.key>H.r[j].key)
break;
H.r[s]=H.r[j];
s=j;
}
H.r[s]=rc;
}
void Heap(SqList &H)
{
int i;
for(i=H.length/2;i>0;i--)//从第一个非叶子结点开始
HeapAdjust(H,i,H.length);//先把顺序表排序成为大顶堆
for(i=H.length;i>1;i--)
{
H.r[0]=H.r[1];
H.r[1]=H.r[i];
H.r[i]=H.r[0];
HeapAdjust(H,1,i-1);
}
}
int main()
{
int i,output,input=1;
while(input)
{
cout<<"*********************************************************************"<<endl;
cout<<"请输入想要执行命令的序号:"<<endl;
cout<<"0:退出程序"<<endl;
cout<<"1:执行简单选择排序操作"<<endl;
cout<<"2:执行堆排序操作"<<endl;
cout<<"*********************************************************************"<<endl;
cin>>output;
switch(output)
{
case 0:
input=0;
break;
case 1:
cout<<"执行简单选择排序操作"<<endl;
cout<<"请输入顺序表表长:"<<endl;
cin>>H.length;
cout<<"请依次输入顺序表的元素:"<<endl;
for(i=1;i<=H.length;i++)
cin>>H.r[i].key;
SimpleSelectSort(H);
cout<<"执行简单选择排序操作后的结果为:"<<endl;
for(i=1;i<=H.length;i++)
cout<<H.r[i].key<<" ";
cout<<endl;
break;
case 2:
cout<<"执行堆排序操作"<<endl;
cout<<"请输入顺序表表长:"<<endl;
cin>>H.length;
cout<<"请依次输入顺序表的元素:"<<endl;
for(i=1;i<=H.length;i++)
cin>>H.r[i].key;
Heap(H);
cout<<"执行堆排序操作后的结果为:"<<endl;
for(i=1;i<=H.length;i++)
cout<<H.r[i].key<<" ";
cout<<endl;
break;
}
}
}
EG: 49 38 65 97 76 13 27 49
运行结果如下图所示: