数据结构——第五讲、树(下)(1)

来源:互联网 发布:西电人工智能学院 编辑:程序博客网 时间:2024/05/22 15:46

5.1 堆

当需要存储一个不同优先级的优先队列时(删除都删除最大/最小值,插入任意元素),我们就要用到堆,当然,用数组,链表,或树都可以完成,但是算法复杂度不够理想。

堆是一种特殊的树,它的任意节点都比它的左右儿子大/小,所以它的根节点是最大的/或者是最小的,删除的时候只需要删除最上面的根节点即可,插入时,为了使空间利用率最大,按照完全二叉树插入,这就是最大/小堆

还记得刚开始说二叉树的时候,我们试过用数组存储二叉树,然而因为利用率不高,只适合存完全二叉树这种排的比较满的树,对于现在堆这种结构,我们就可以用数组来存,从上到下一层一层排序,第i个节点左儿子是2*i,右儿子是2*i+1,父节点是i/2。

堆的抽象数据类型描述:
类型名称:最大堆(MaxHeap)
数据对象集:完全二叉树
操作集:

MaxHeap Create(int MaxSize);Boolean IsFull(MaxHeap H);Boolean IsEmpty(MaxHeap H);MaxHeap Insert(ElementType x, MaxHeap H);ElementType Delete(MaxHeap H);

最大堆的结构

typedef struct HeapStruct *MaxStruct;struct HeapStruct{    //指向数组    ElementType *Elements;    //现有元素个数    int Size;    //最大容量    int Capacity;};

创建一个最大堆

MaxHeap Create(int MaxSize){    MaxHeap H = malloc(sizeof(struct HeapStruct));    //数组空出一个位置存放最大值作为哨兵    H->Elements = malloc(sizeof((MaxSize+1)*ElementType));    H->Size = 0;    H->Capacity = MaxSize;    //宏定义一个数据里面的最大可能值,插入时可以减少一个判断条件。    H->Elements[0] = MaxData;    return H;}

插入

MaxHeap Insert(ElementType x, MaxHeap H){    int i;    if(IsFull(H)){        printf("已满!");        return NULL;    }    //改变最大堆信息的同时,告诉i应该插入的位置    i = ++H->Size;    for(;H->Elements[i/2] < x;i /= 2){        H->Elements[i] = H->Elements[i/2];    }    H->Elements[i] = x;    return H;}

删除

ElementType Delete(MaxHeap H){    if( IsEmpty(H) ){        printf("堆空!");        return NULL;    }    ElementType MaxItem = H->Elements[1];    ElementType item;    int parent = 1;    int child;    item = H->Elements[H->Size--];    for(;2*parent <= H->Size;parent = child){        child = 2 * parent;        if( child != H->Size){            if( H->Elements[child] < H->Elements[child+1])                child++;        }        if(item >= H->Elements[child])break;        else            H->Elements[parent] = H->Elements[child];    }    H->Elements[parent] = item;    return MaxItem;}

给定一个序列,创建一个堆,可以通过不断的插入,但是有效率更高的方法,先把序列存入完全二叉树中,然后从最后一个有儿子的节点开始调整,形成一个节点,他的左右儿子都是堆的递归

//这段代码未经验证,有什么问题希望能反馈给我……MaxHeap Create(ElementType T[Size]){    MaxHeap H;    for(int i = 0; i < Size; i++)        H->Elements[++H->Size] = T[i];    int parent = H->Size/2;    int child;    ElementType t;    for(;parent>0;parent--){        for(;2*parent <= H->Size;parent = child){            child = 2 * parent;            if( child != H->Size){                if( H->Elements[child] < H->Elements[child+1])                    child++;            }            if(H->Elements[parent] >= H->Elements[child])break;            else{                t = H->Elements[parent];                H->Elements[parent] = H->Elements[child];                H->Elements[child] = t;            }        }    }}