7.4选择类排序

7.4选择类排序

算法思想:每一趟(例如第i趟)在后面n-i+2(i=1,2,3,…,n-1)个待排序的元素中选取关键字最小的元素,作为有序子序列的第i个元素,直到第n-1趟做完,待排序的元素只剩一个,就不用再选了。

包括简单排序和堆排序。

简单排序:

void SelctSort(ElemType A[],int n){
    for(int i=0;i<n-1;i++){ //依次从后面的序列中选择当前最小元素作为第i个元素,最后一个元素不用排
		min=i;
        for(int j=i+1;j<n;j++) //从第i个元素往后找,一直找到最后一个元素
			if(A[j]<A[min])
                min=j;
        if(min!=i){
			ElemType temp =A[i];
             A[i]=A[ming];
             A[min]=temp;
        }
       
    }
}

算法分析:

[外链图片转存失败(img-4T4pJ7vK-1567499175585)(assets/1567493657063.png)]

[外链图片转存失败(img-KgciHdXD-1567499175586)(assets/1567493699190.png)]

堆排序:

什么是堆排序:我们知道对于对于一个堆来说,他的根结点是整个堆中所有结点的值的最大值(大顶堆)或者

最小值(小顶堆),所以堆排序的思想就是每次将无序序列调节成一个堆,然后在堆中选择堆顶元素的值,把这个值加入有序序列,无序序列减少一个,再反复调节无序序列,直到所有的关键字都加入到有序序列。

算法思想:

1)建堆:堆初始序列的完全二叉树调整成一个大顶堆

调整方法:二叉树由下至上由左至又(数组的下标又大到小),检查每个结点是否满足大顶堆的要求,如果不满足进行调整。

[外链图片转存失败(img-WsFQtdOv-1567499175587)(assets/1567495920526.png)]

[外链图片转存失败(img-ybk25yCJ-1567499175588)(assets/1567495938589.png)]

[外链图片转存失败(img-PP8FNNlx-1567499175589)(assets/1567495992661.png)]

[外链图片转存失败(img-0muxf0su-1567499175590)(assets/1567495951853.png)]

[外链图片转存失败(img-ihsMkI3b-1567499175592)(assets/1567496020553.png)]

[外链图片转存失败(img-4nn4YXiu-1567499175593)(assets/1567496035953.png)]

[外链图片转存失败(img-fJifRbR9-1567499175594)(assets/1567496047414.png)]

2)将堆顶结点和最后一个结点19交换,也就是将最大值92移动到数组的最末尾,有序序列中加入了结点92,无序序列减少结点92到这了堆排序的第一趟完成。

[外链图片转存失败(img-ybNmitJ0-1567499175595)(assets/1567496296278.png)]

3)调堆:调整二叉树的结点是的满足大顶堆的要求。调整方法和建堆一样。

[外链图片转存失败(img-i0XI0hVY-1567499175596)(assets/1567496340959.png)]

4)重复上述过程,直到排完。

算法流程:设最后一个结点编号为N,N等于二叉树中结点数量,它肯定是叶子结点。所以第一个可能需要调整的非叶子结点的下标为[N/2],从他的右孩子开始检查,它的左孩子下标为[N/2]*2如果发生交换,下一轮检查交换过结点的左右孩子。

算法代码:

/*建堆*/void BuildMaxHeap(ElemType A[],int len){
	for(int i=len/2;i>0;i--)  //从第一个可能需要调整过的非叶子结点开始检查,直到根结点(注意根结点的下标不是0,是从1开始存储的)
		AdjustDown(A,i,len);
}
/*调整堆*/
void AdjustDown(ElemType A[],int k,int len){ //A是存储的数组,K需要检查的结点下标,Len是堆中结点的个数
	 A[0]=A[k];    //A[]暂存这个需要检查的结点值
     for(i=2*k;i<=len;i*=2){
         if(i<len&&A[i]<A[i+1])
             i++;
         if(A[0]>A[i])
             break;
         else{
			A[K]=A[i];
             k=i;
         }
     }
    A[K]=A[0];
}
/*堆排序算法*/
void HeapSort(ElemType A[],int len){
	BuildMaxHeap(A.len);
	for(i=len,i>1;i--){
		//输出堆顶元素(和堆底元素交换)
		ElemType temp =A[i];
		A[i]=A[1];
		A[1]=temp;
		printf(A[i]);
		AdjustDown(A,1,i-1);  //把剩余的i-1个元素整理成新的大顶堆
	}

}

算法分析:

[外链图片转存失败(img-U7Yuq1TB-1567499175597)(assets/1567498281607.png)]

[外链图片转存失败(img-TDbX4YTk-1567499175597)(assets/1567498327104.png)]

[外链图片转存失败(img-VkiDxhPN-1567499175598)(assets/1567498292830.png)]

[外链图片转存失败(img-3ccSt6D6-1567499175599)(assets/1567498304531.png)]

[外链图片转存失败(img-tGFQB7mJ-1567499175600)(assets/1567498361106.png)]

[外链图片转存失败(img-nPvfNGyx-1567499175601)(assets/1567498399098.png)]

[外链图片转存失败(img-Ao4p9K4v-1567499175601)(assets/1567498488364.png)]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值