堆排序

2021-01-20 23:14

阅读:505

标签:UNC   ica   小根堆   near   word   交换   key   size   heapsort   

堆排序

  1. 大根堆,小根堆:所有非叶子节点大于或者小于其孩子节点。

  2. 用大根堆进行从小到大的排序

  3. 建立大根堆:从下往上,从右往左遍历非叶子节点,判断其是否符合大根堆性质,若不符合,则交换节点位置,直至建出大根堆。

  4. 大根堆根节点一定是被排序的这段数值的最大值,交换堆尾堆首数值,堆尾指针前移(有没有冒泡的感觉?最大值逐渐飘到堆尾)

  5. 当前堆只有根节点不符合大根堆性质,所以从根节点开始,向下找到合适的位置即可

 1#include
2#include
3using namespace std;
4
5/**刚还奇怪,为什么从小到大排序用的是大根堆?
6仔细看,建好堆以后,根节点是最大值,可是!!!
7交换了堆尾和堆首的值,那么最大值就跑到了后面.
8交换后,这个堆尾就算最大值了 ,不用管,再排序前面 n-1 个节点
9同理,每次最大值都跑到了后面
10*/

11
12
13/**以 k 为根的完全二叉树,分别以2*K 和 2*k+1 为根的左右子树为大根堆*/
14/**使 k 为根的树满足堆的性质*/
15void sift(int a[],int k,int m)
16
{
17    int x=a[k];
18    int i=k;
19    int j=k*2;
20    bool finish=false;
21    while(j22    {
23        if(j+11])
24            j=j+1;/**此时 j 指向最大子树根节点*/
25
26        if(x>=a[j])
27            finish=true;
28        else/**若是比子树根小,交换后还得考虑下层大小关系*/
29        {
30            a[i]=a[j];
31            i=j;
32            j=2*i;
33        }
34    }
35    a[i]=x;
36}
37void crateHeap(int a[],int n)
38
{
39    /**从最后一个非叶子节点往上筛选建堆*/
40    for(int i=n/2;i>=1;i--)
41        sift(a,i,n);
42}
43void heapSort(int a[],int n)
44
{
45    /**建大根堆后 ,保证了下面的数字不会大于上面的数字*/
46    crateHeap(a,n);
47    /**对 a 数组进行 从小到大 堆排序*/
48    for(int i=n;i>=2;i--)
49    {
50        /**每次得到的最大值跑到了后面*/
51        swap(a[i],a[1]);
52
53
54        /**交换以后只有堆顶元素是不合法的,所以下面只是为了
55        给堆顶元素找到一个合适的位置*/

56        /**对a[1~i-1]调整成堆*/
57        sift(a,1,i-1);
58    }
59}
60int main()
61
{
62    int a[12]={0,88,32,34,12,34,66,52,33,25,20};
63    heapSort(a,10);
64    for(int i=1;i10;i++)
65        printf("%d ",a[i]);
66    return 0;
67}

堆排序

标签:UNC   ica   小根堆   near   word   交换   key   size   heapsort   

原文地址:https://www.cnblogs.com/HappyKnockOnCode/p/12899782.html


评论


亲,登录后才可以留言!