erl_tree heap 堆实现
来源:互联网 发布:云计算系统软件 编辑:程序博客网 时间:2024/06/05 20:45
erlang heap 堆实现
要说最大堆和最小堆,就得先知道最大树和最小树。
每个结点的值都大于(小于)或等于其子节点(如果有的话)值的树,就叫最大(最小)树。
最大堆(最小堆)是最大(最小)完全树。
由于堆是完全二叉树,所以可以用公式化描述,用一维数组来有效的描述堆结构。
利用二叉树的性质:
如果对一棵有n个结点的完全二叉树的结点按层序编号(从第1层到第[log2n]向下取整+1层,每层从左到右),则对任一结点i(1≤i≤n),有:
(1)如果i=1,则结点i无双亲,是二叉树的根;如果i>1,则其双亲是结点[i/2]向下取整。
(2)如果2i>n,则结点i为叶子结点,无左孩子;否则,其左孩子是结点2i。
(3)如果2i+1>n,则结点i无右孩子;否则,其右孩子是结点2i+1。
这样就就可以将堆中结点移到它的父节点或者其中一个子节点处。
堆中进行的操作主要是:插入,删除,以及初始化。
以下代码用tuple实现了最大最小堆,要转换只需修改一下?HEAP_TYPE 成max.
代码
%% Copyright-module(tuple_heap).-author("sugar").%% API-compile(export_all).%% 最小堆 min 最大堆 max-define(HEAP_TYPE, min ).-define(CMP(V1,V2),case ?HEAP_TYPE of min-> ?MINCMP(V1,V2); _ -> ?MAXCMP(V1,V2) end).%%最小堆-define(MINCMP(V1,V2), V1 < V2 ).%%最大堆-define(MAXCMP(V1,V2), V1 < V2 ).get_size(Heap)-> erlang:tuple_size(Heap).%% 获取父节点parent(Index)-> trunc(Index / 2).%% 获取左孩子left(Index)-> 2*Index.%%获取右孩子right(Index)-> 2*Index+1.get_top(Heap)-> case get_size(Heap) of 0-> error("heap empty !"); _ -> erlang:element(1,Heap) end.%%插入insert(V,Heap)-> NewHeap = erlang:append_element(Heap,V), NewSize = get_size(NewHeap), if NewSize == 1 -> NewHeap; true-> Parent = erlang:element(parent(NewSize),NewHeap), case ?CMP(V , Parent) of true-> move_up(NewHeap,NewSize); _-> NewHeap end end.%%取出%%return {minData,newHeap}pop(Heap)-> Size = get_size(Heap), Min = erlang:element(1,Heap), Last = erlang:element(Size,Heap), Heap1 = erlang:delete_element(Size,Heap), Heap2 = erlang:setelement(1,Heap1,Last), Heap3 = move_down(Heap2,1), {Min,Heap3}.move_up(Heap,1)-> Heap;move_up(Heap,Index)-> Cur = erlang:element(Index,Heap), Pindex = parent(Index), Parent = erlang:element(Pindex,Heap), case ?CMP(Cur , Parent) of true-> Heap1 = erlang:setelement(Pindex,Heap,Cur), Heap2 = erlang:setelement(Index,Heap1,Parent), move_up(Heap2,Pindex); _-> Heap end.move_down(Heap,Index)-> Size = get_size(Heap), Cur = erlang:element(Index,Heap), TIndex = case ?HEAP_TYPE of max-> right(Index); _-> left(Index) end, ToV = if TIndex =< Size-> erlang:element(TIndex,Heap); true-> undefined end, ToVIsint = erlang:is_integer(ToV), case ToVIsint andalso ?CMP(ToV , Cur) of true-> Heap1 = erlang:setelement(TIndex,Heap,Cur), Heap2 = erlang:setelement(Index,Heap1,ToV), move_down(Heap2,TIndex); _-> Heap end.
0 0
- erl_tree heap 堆实现
- 堆的实现 Heap
- 堆(heap)实现
- 堆(heap)的实现
- 堆(Heap)的实现
- STL的 heap 堆实现
- C实现heap堆排序
- 浅析 Win2K 中堆(Heap)的实现
- 浅析 Win2K 中堆(Heap)的实现
- 堆排序(Heap Sort)算法的实现
- 堆(heap)基于数组的实现
- 堆排序(Heap Sort)算法的实现
- C++实现最小堆(binary heap)
- 堆 Heap <实现类+测试用例>
- 数据结构之堆(Heap)的实现
- heap 堆
- heap 堆
- 堆(heap)
- ozzie配置和example
- Android简单用属性动画实现两个控件重叠
- Yum配置文件详解
- 关于序列旋转(辗转相除求取最大公约数)
- Ruby 安装
- erl_tree heap 堆实现
- POJ 3080 Blue Jeans (暴力)
- 如何更便捷的监控前端服务质量
- java 静态(static)方法的继承和重写
- SlidingMenu
- ABP之动态WebAPI(二)
- ubuntu14.04 安裝chrome flash 插件
- j2ee在tomcat服务器下跟一个不同的名字
- 双十一电信宽带会有优惠