浅谈堆

xiaoxiao2021-02-28  125

#简介

堆结构是一种数组对象,它可以被视为一颗完全二叉树(除了叶子节点别的节点都是满的)。树中结构与数组中存放该节点值得那个元素是对应相同的,见图:

#堆的性质


设数组A的长度为len,二叉树的节点个数为size,size<=len,则A[i]存储二叉树中编号为i的节点值(1<=i<=size),而A[size]以后的元素并不属于相应的堆,树的根为A[1],并且利用完全二叉树的性质,我们很容易求第i个节点的父节点(prarent(i))、左孩子结点(left(i))、右孩子节点(right(i))的下标了,分别是:i/2、2i、2i+1。 更重要的是,堆具有一个性质,对除根以外的每个节点i,A[parent(i)]>=A[i]。即除根节点外,所有节点的值都不能超过它的父节点,这样就推出,堆中的最大元素存在堆顶,且每个节点的子树中的节点值都咸鱼等于该节点的值,这种堆又称为“大根堆”;反之称为“小根堆”。


#堆的操作 up 和 down up是把一个点移上去的过程。如图: 理解一下: pascal

procedure up(k:longint); begin while(k>1)and(a[k]<a[k div 2])do begin a[0]:=a[k]; a[k]:=a[k div 2]; a[k div 2]:=a[0]; k:=k div 2; end; end;

c++

void up(int k) { int now,next; a[++a_size]=k; now=a_size; while (now>1) { next=now>>1; if (a[now]>=a[next]) break; a[0]=a[k]; a[k]=a[k/2]; a[k/2]=a[0]; now=next; } }

**c++**标准模板库STL

void up(int k) { a[++a_size]=k; //push_a(a+1,a+a_size+1); //大根堆 push_a(a+1,a+a_size+1,greater<int>());//小根堆 }

down是把一个点向下移。如下图; 理解一下 pascal

procedure down(x:longint); var y,k:longint; begin while (x*2<=tot)and(a[x]>a[x*2])or(x*2+1<=tot)and(a[x]>a[x*2+1]) do begin y:=x*2; if(y+1<=tot)and(a[y]>a[y+1])then inc(y); k:=a[x]; a[x]:=a[y]; a[y]:=k; x:=y; end; end;

c++

void down(int k) { int now,next; now=k; while (now*2<=a_size) { next=now*2; if (next<a_size&&a[next+1]<a[next]) next++; if (a[now]<=a[next]) break; a[0]=a[now]; a[now]=a[next]; a[next]=a[0]; now=nex; } }

**c++**标准模板库STL

void down() { //pop_a(a+1,a+a_size+1);//大根堆 pop_a(a+1,a+a_size+1,greater<int>());//小根堆 }

在堆的应用中,只要好好的运用这两个程序,就会飞啦~~

转载请注明原文地址: https://www.6miu.com/read-41332.html

最新回复(0)