概述
堆
堆是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆;或者每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆。
堆排序
堆排序是利用堆这种数据结构而设计的一种排序算法,堆排序是一种选择排序,它的最坏,最好,平均时间复杂度均为O(nlogn),它也是不稳定排序。
在数据结构中,我们将堆的逻辑结构映射到数组中存储,如下图:
于是在数组中,堆中节点的索引有如下定义:
大顶堆:arr[i] >= arr[2i+1] && arr[i] >= arr[2i+2]
小顶堆:arr[i] <= arr[2i+1] && arr[i] <= arr[2i+2]
堆常用来作堆排序,主要思想如下:
堆排序的基本思想是:将待排序序列构造成一个大顶堆,此时,整个序列的最大值就是堆顶的根节点。将其与末尾元素进行交换,此时末尾就为最大值。然后将剩余n-1个元素重新构造成一个堆,这样会得到n个元素的次小值。如此反复执行,便能得到一个有序序列了
堆排序的步骤:
一、构造初始堆。将给定无序序列构造成一个大顶堆(一般升序采用大顶堆,降序采用小顶堆)。
- 设给定的无序序列如下:
- 此时我们从最后一个非叶子结点开始(叶结点自然不用调整,第一个非叶子结点 arr.length/2-1=5/2-1=1,也就是下面的6结点),从左至右,从下至上进行调整。
- 找到第二个非叶节点4,由于[4,9,8]中9元素最大,4和9交换
- 如此进行下去,得到最后的大顶堆序列如下:
二、将堆顶元素与末尾元素进行交换,使末尾元素最大。然后继续调整堆,再将堆顶元素与末尾元素交换,得到第二大元素。如此反复进行交换、重建、交换。
a.将堆顶元素9和末尾元素4进行交换
b.重新调整结构,使其继续满足堆定义
c.再将堆顶元素8与末尾元素5进行交换,得到第二大元素8.
后续过程,继续进行调整,交换,如此反复进行,最终使得整个序列有序
再简单总结下堆排序的基本思路:
a.将无需序列构建成一个堆,根据升序降序需求选择大顶堆或小顶堆;
b.将堆顶元素与末尾元素交换,将最大元素"沉"到数组末端;
c.重新调整结构,使其满足堆定义,然后继续交换堆顶元素与当前末尾元素,反复执行调整+交换步骤,直到整个序列有序。
代码实现:
#include<stdio.h>
typedef int ElementType;
int arr1[11]={0,2,87,39,49,34,62,53,6,44,98};
#define LeftChild(i) (2 * (i) + 1)
void Swap(int* a,int* b)
{
int temp=*a;
*a=*b;
*b=temp;
}
void PercDown(int A[], int i, int N) //构成堆
{
int child;
ElementType Tmp;
for (Tmp = A[i]; 2*i+1 < N; i = child){
child = 2*i+1; //左孩子节点
if (child != N - 1 && A[child + 1] > A[child])
++child; //找到最大的儿子节点
if (Tmp < A[child]) //如果小于最大孩子的值,就将自己的值变为最大孩子的值
A[i] = A[child];
else
break; //否则,退出该非叶子节点的所有循环
}
A[i] = Tmp;
}
void HeapSort(int A[], int N) //排序,每次都把最大数排到堆顶,然后再与最后一个未定位的点交换
//这样就可以得到一个固定的顺序
{
int i;
for (i = N / 2; i >= 0; --i) //i=5,4,3,2,1,0
PercDown(A, i, N); //构造堆
for(i=N-1;i>0;--i)//i=9, ... ,1
{
Swap(&A[0],&A[i]); //将最大元素(根)与数组末尾元素交换,从而删除最大元素,重新构造堆
PercDown(A, 0, i);
}
}
void Print(int A[],int N)
{
int i;
for(i=0;i<N;i++)
{
printf(" %d ",A[i]);
}
}
int main()
{
int arr[10]={2,87,39,49,34,62,53,6,44,98};
Print(arr,10);
printf("n");
HeapSort(arr,10);
Print(arr,10);
printf("n");
return 0;
}
图文参考:https://www.cnblogs.com/chengxiao/p/6129630.html
代码参考:https://www.cnblogs.com/wuchanming/p/3821607.html
最后
以上就是美丽大叔为你收集整理的数据结构之堆排序算法详解+C语言实现的全部内容,希望文章能够帮你解决数据结构之堆排序算法详解+C语言实现所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复