用一组数建立小堆(堆的创建)

(二叉)堆的概念:

如果有一组数,数的集合K={K0,K1,.....Kn-1},把它的所有元素按照完全二叉树的顺序存储方式存储在一个一维数组中,并且有Ki<=2*Ki+1,Ki<=2*Ki+2,(或者Ki>=2*Ki+1,Ki>=2*Ki+2),称为小(大)堆。

用一组数建立小堆(堆的创建)_第1张图片

如上图所示:

小(大)堆中,任一关键码均小于(大于)等于它的左右孩子的关键码,位于堆顶顶点的关键码最小(最大),从根节点到每个节点的路径上数组组成的序列都是递减(递增)的。

 

堆存储在下标为0开始的数组中,因此在堆中给定下标为i的节点时:

1)如果i=0,节点是根节点,没有双亲节点,否则,双亲节点为(i-1)/2

2)如果2*i+1<=n-1,则节点i的左孩子为节点2*i+1,否则节点i无左孩子

3)如果2*i+2<=n-1,则节点i的右孩子为节点2*i+2,否则节点i无右孩子

 

堆的创建:

(1)将一组数先放进堆定义的结构体中;

用一组数建立小堆(堆的创建)_第2张图片      用一组数建立小堆(堆的创建)_第3张图片  

(2)向下调整堆

从最后一个非叶子节点开始调整,一直到根节点为止,将每一个节点及其子树调整到满足小堆的性质即可。

具体调整方法:

while(1)

{1)若此节点为K;

2)则此节点的左孩子为2*K+1,判断左孩子是否存在,不存在,结束;存在,向下走。

3)判断此节点的右孩子2*K+2是否存在,不存在,判断左孩子与节点K的大小;存在,向下走。

4)比较左右孩子与节点K的大小,若节点K最小,结束;若左孩子最小,左孩子与节点交换,若右孩子最小,右孩子与节点交换。

}

代码如下:

头文件:二叉堆.h

#pragma once
#include
#include

#define Max 100

typedef int DataType;
//typedef int size_t;

//二叉堆
typedef struct StackN
{
    DataType array[Max];
    //size_t size;
    int size;
}StackN;

void init(StackN * php)
{
    php->size = 0;
    php = NULL;
}

//让数据入堆
void CreatS(DataType a[], StackN*php, int n)
{
    if (n == 0)
    {
        return;
        printf("内容为空!\n");
    }
    int i = 0;
    for (i = 0; i < n; i++)
    {
        php->array[i] = a[i];
        php->size++;
    }
}

void swap(int*a, int *b)
{
    int t = 0;
    t = *a;
    *a = *b;
    *b = t;
}


void AdJust(StackN*php,  int root)
{
    while (1) {
        int left = 2 * root + 1;
        int right = 2 * root + 2;
        // 判断是否是叶子结点,如果左孩子下标越界了,没有左孩子了
        // 所以也就没有右孩子了
        if (left >= php->size) {    // == 的情况也是越界
            // 越界
            return;
        }

        int min = left;    // 假设大的那个是左孩子
        // 找到左右孩子中大的一个
        // 一定要先判断右孩子有,才能比较左右孩子的大小
        // if (array[right] > array[left] && right < size),错误的
        if (right < php->size && php->array[right] < php->array[left]) {
            min = right;
        }

        // 判断和 [root] 的关系
        // root >= max    错误的, root 和 max 表示的下标
        if (php->array[root] <= php->array[min]) {
            return;
        }

        // 交换
        int t = php->array[root];
        php->array[root] = php->array[min];
        php->array[min] = t;

        root = min;
    }
}


void A_S(DataType a[], StackN*php)
{
    int i = 0;
    for (i = (php->size-1)/2; i >= 0; i--)
        AdJust(php, i);
    printf("\n");
}


void test()
{
    StackN php;
    init(&php);
    DataType aa[] = { 53, 17, 78, 9, 45, 65, 87, 23, 31 };  //堆   调整为小堆
    int n = sizeof(aa) / sizeof(DataType);
    CreatS(aa, &php, n);

    A_S(aa, &php);

}

源文件:test.c

#include"二叉堆.h"
#include

int main()
{
    test();
    system("pause");
    return 0;
}

 

你可能感兴趣的:(C语言)