选择排序
1、基本思想:首先在待排序序列中选出最小记录,然后将这个最小的数据元素与第一个记录交换,第一个记录到位后即为第一趟排序;第二趟则为第二个记录到最后一个记录中选最小的记录,之后将所选的最小的记录与第二个记录交换。以此类推,进行n-1趟。即第i趟选择排序是在n-i+1(1=1,2,…,n-1)个记录中进行选择。
2、稳定性:稳定
3、时间复杂度:O(n²),空间复杂度:O(1)
4、代码实现:
#include<stdio.h>
#define MAX 100
void SelectSort(int array[],int n);
int main()
{
int array[MAX];
int n,s,q;
printf("请输入待排序数的个数:\n");
scanf("%d",&n);
printf("请输入待排序的数据:\n");
for(s=0;s<n;s++)
scanf("%d",&array[s]);
SelectSort(array,n);/*函数调用*/
printf("选择排序结果为:\n");
for(s=0;s<n;s++) /*输出排序后节点序列*/
printf("%d",array[s]);
}
void SelectSort(int array[],int n)
{
int k,q,s,temp;
for(s=0;s<n;s++)
{
k=s; /*k用来记录最小元素位置*/
for(q=s+1;q<n;q++)
if(array[k]>array[q])
k=q;
temp=array[s];
array[s]=array[k];
array[k]=temp;
}
}
堆排序——树形选择排序的改进
树形选择排序(锦标赛排序)
1、基本思想:首先对n个记录的关键字进行两两比较,然后在n/2个较小者之间再进行两两比较,如此重复,直至选出最小的记录为止。
2、方法说明:这个过程可用一棵有n个结点的树表示。每个非终端结点中的数均等于其左右孩子结点中较小的数值,则根结点中的数即为叶子结点的最小数。在输出最小数之后,想选出次小数,仅需将叶子结点中的最小数设为∞,再进行刚才的比较,直至所有记录全部输出为止。(即每一次最小数的选择所形成的树建立过程从最末端叶子开始,根节点即为一次选择所求)
3、时间复杂度:O(n lbn)
4、缺点:辅助存储空间较多、和∞进行多余比较等缺点。
堆排序(原地排序)
1、堆:设有n个元素的序列{k1,k2,…,kn},当且仅当,满足下关系之一时,称之为堆。(ki <= k2i且ki <= k2i+1)或者(ki >= k2i且ki >= k2i+1), (i = 1,2,3,4…n/2)。若某数列为堆,则k1(堆顶元素)必为数列中最小值或最大值,堆顶元素最小的序列称为小堆顶,反之为大堆顶。 若将堆看成一个完全二叉树则根节点为整棵二叉树中的最小或最大值。
2、堆排序基本思想:先将序列建成堆,以根节点与第n个结点交换,调整前n-1个结点重新构造成一个堆,再以根节点与第一个n-1个结点交换。反复执行,直至序列有序。 其中,将n-1个元素建成新堆的过程称为筛选。初始序列建堆过程则为反复进行筛选的过程。
3、时间复杂度(最坏): O(n lbn)
4、稳定性:不稳定
5、代码实现:
void PercDown(int array[],int s,int n)/*序列调整为堆*/
{
int q;
int t;
t=array[s];
while((q=2*s+1)<n) /*有左孩子*/
{
if(q<n-1&&array[q]<array[q+1])
q++;
if(t<array[q])
{
array[(q-1)/2]=array[q];
s=q;
}
else
break;
}
array[(q-1)/2]=t ; /*t放在最后一个位置*/
}
void HeapSort(int array[],int n) /*堆排序*/
{
int s;
int t;
s=(n-1)/2;
while(s>=0)
{
PercDown(array,s,n);
s--;
}
s=n-1;
while(s>0)
{
t=array[0]; /*交换结点*/
array[0]=array[s];
array[s]=t;
PercDown(array,0,s);
s-- ;
}
}