选择排序学习总结
选择排序:
第一趟:从n个元素中选择1个最小元素,放到序列的第一个位置;
第二趟:从n-1个元素中选择1个次小元素,放到序列的第二个位置;
…
第n-1趟:从2个元素中选择1个元素,放到序列倒数第二个位置。
结束。
1.简单选择排序
void SelectSort(ElemType A[],int n)
{
for(int i=1;i<=n-1;i++) //共进行n-1趟排序
{
int min=i-1; //记录最小元素的位置
for(int j=i;j<n;j++) //在A[i]~A[n]中查找是否有比A[i-1]更小的元素
{
if(a[min]>a[j])
min=j; //不断更新最小元素位置
}
if(min!=j-1)
swap(a[i-1],a[min]);
}
}
分析:
①空间复杂度:O(1);
②时间复杂度:比较次数:(n-1)+(n-2)+…+2+1=n(n-1)/2固定不变,所以O(n2);
③不稳定。
2.堆排序(树形选择排序)
思想:将L[1~n]的一个序列看成是完全二叉树的顺序存储结构,利用双亲节点与孩子节点之间的关系,在无序区中选择最大或最小元素。
概念一:小根堆(L[i]<=L[2i]&&L[i]<=L[2i+1])
概念二:大根堆(L[i]>=L[2i]&&L[i]>=L[2i+1])
其中:1<=i<=⌊n/2⌋
问题1:给定一个序列,建立小根堆。
{23,17,72,60,25,8,68,71,52}
问题2:堆的插入操作(插入到堆的末尾)。
问题2:堆的删除操作(删除堆顶元素)。
步骤:将堆的最后一个元素放到堆顶,逐步进行向下调整。
算法描述:
//建立大根堆的算法
void BuildMaxHeap(ElemType A[],int n)
{
for(int i=n/2;i>=1;i--)
AdjustDown(A,i,n);
}
//向下调整算法
void AdjustDown(ElemType A[],int k,int n)
{
A[0]=A[k]; //将要调整的节点值暂时存放在A[0]中
for(int i=2k;i<n;i=2i)
{
if(A[i]<A[i+1])
i++; //A[i]里要存放两个子节点中的较大值
if(A[0]>A[i]) //此时,已经满足:要调整的节点值>子节点中的较大值,
break; 即满足大根堆的要求,则不需调整,结束循环
else //要调整的节点值<子节点中的较大值。
A[k]=A[i]; //将子节点中的较大节点上移
k=i; ///要调整的节点位置下移
}
A[k]=A[0]; //将要调整的节点值放在最终位置
}
//堆排序算法
void HeapSort(ElemType A[],int n)
{
BuildMaxHeap(A,n);
for(i=n;i>1;i--) //进行n-1趟
printf(A[i]); //输出堆顶元素
AdjustDown(A,1,i-1); //将剩下的i-1个元素整理成堆
}
分析:
①空间复杂度:O(1);
②时间复杂度:
建堆时间为:O(n);
调整趟数:n-1;
一趟调整时间是O(h),即log2n。
所以时间复杂度为:O(nlog2n)。——不存在好坏情况
③不稳定。