数据结构——第五讲、树(下)(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; } } }}
阅读全文
0 0
- 数据结构——第五讲、树(下)(1)
- 数据结构——第五讲、树(下)(2)
- 数据结构——第五讲、树(下)(3)
- 陈越《数据结构》第五讲 树(下)
- 数据结构——第八讲、图(下)(1)
- 数据结构——第三讲、树(上)(1)
- 数据结构——第四讲、树(中)(1)
- 读书笔记(第五讲)
- 0627第五讲继承(1)概述
- 数据结构——第三讲、树(上)(2)
- 数据结构——第三讲、树(上)(3)
- 数据结构——第四讲、树(中)(2)
- 数据结构——第六讲、图(上)(1)
- 数据结构——第七讲、图(中)(1)
- 数据结构——第一讲、基本概念(1)
- 数据结构——第二讲、线性结构(1)
- 数据结构——第六讲、图(上)(2)
- 数据结构——第一讲、基本概念(2)
- hdoj题目分类
- mysql的索引技术和字段修改命令
- OS中阻塞与挂起的区别&sleep()的实现原理
- Nginx安装教程
- TB 16 10 29 AM
- 数据结构——第五讲、树(下)(1)
- [JavaScript] Chrome启用ES6支持
- MATLAB长除法求z变换逆变换
- TreeSet排序原理
- JavaBean
- leetcode.array--33. Search in Rotated Sorted Array
- Windows下常用的100个CMD指令以及常见的操作
- 怎样判断ffmpeg接口是线程安全的?
- Can't update: no tracked branch