[Python] 斐波那契堆的实现

来源:互联网 发布:百度软件商店 编辑:程序博客网 时间:2024/05/29 07:59

[Python] 斐波那契堆的实现

斐波那契堆是一种基于堆的数据结构,其用途主要为:
- 实现“可合并堆”
-某些在斐波那契堆中常数摊还时间内完成的操作频繁使用的应用

具体函数(操作):

首先介绍堆中元素(节点)的实现:
元素初始化

def __init__(self, key):        self.key=key #关键字        self.degree=0 #元素在堆中的度        self.p=0 #指向双亲节点        self.child=0 #指向第一个孩子节点        self.left=0 #左向循环指针        self.right=0 #右向循环指针        self.mark=False #标记

x.GetChild(c): 使元素c成为元素x的孩子节点

def GetChild(self,cn):        cn.p=self        self.degree=self.degree+1        if self.child==0:            self.child=cn            cn.left=cn            cn.right=cn        else:            c=self.child            cn.right=c            cn.left=c.left            cn.left.right=cn

x.printNode():循环输出元素x和它的同一级节点及他们的子节点

def printNode(self):        if self.child!=0:            c=self.child            cl=c.left            while True:                print("%d has child: %d" % (self.key,c.key))                c.printNode()                if cl==c:                    break                c=c.right

x.SearchChild(key):循环搜索关键字为key的节点

def SearchChild(self, key):        w=self        v=self        resultnode=0        while True:            if w.key==key:                return w            if w.child!=0:                resultnode=w.child.SearchChild(key)            if resultnode!=0:                return resultnode            w=w.right            if w==v:                return 0

接着是斐波那契堆函数的实现:
大多数函数使在Fib类中实现,对此会有开头标注Fib:
斐波那契堆变量名为H
MAKEHEAP(): 创建和返回一个新的不含任何元素的堆

def MakeHeap():    return Fib(0,0)Fib:def __init__(self, n, minx):        self.n=n #堆大小        self.min=minx #最小节点的指针

H.Insert(x): 将一个已填入关键字的元素x插入堆H中

Fib:def Insert(self, x):#put on the left of min        if self.min==0:            self.min=x            x.left=x            x.right=x        else:            x.right=self.min            x.left=self.min.left            x.left.right=x            self.min.left=x            if x.key<self.min.key:                self.min=x        self.n=self.n+1

H.Minimum():返回一个指向堆H中具有最小关键字元素的指针

Fib:def Minimum(self):        return self.min

Union(H1,H2):创建并返回一个包含堆H1和堆H2中所有元素的新堆H。堆H1和堆H2由这一操作“销毁”

def Union(H1, H2):    H=MakeHeap()    if H1.min==0 or H1.min.key>H2.min.key:        H.min=H2.min    else:        H.min=H1.min    H.n=H1.n+H2.n    if H1.min!=0 and H2.min!=0:        xr=H1.min.right        H1.min.right=H2.min        H2.min.left.right=xr        xr.left=H2.min.left        H2.min.left=H1.min    return H

H.ExtractMin():从堆H中删除最小关键字的元素,并返回一个指向该元素的指针

Fib:def ExtractMin(self):        z=self.min        if z!=0:            if z.child!=0:                c=z.child                while c.p!=0:                    cpr=c.left                    c.p=0                    c.left=0                    c.right=0                    c.right=self.min                    c.left=self.min.left                    c.left.right=c                    self.min.left=c                    c=cpr            z.right.left=z.left            z.left.right=z.right            z.child=0            if z==z.right:                self.min=0            else:               self.min=z.right               self.Consolidate()            self.n=self.n-1        return z

需调用H.Consolidate()来减少堆中树的数目,保证同一个度的树只有一个

Fib:def Consolidate(self):        A=[]        for i in range(0,int(math.log(self.n,2)+1)):            A.append(0)        w=self.min        t=w.left        while True:            x=w            print('is %d' % w.key)            d=x.degree            while A[d]!=0:                y=A[d]                if x.key > y.key:                    v=x                    x=y                    y=v                self.Link(y,x)                A[d]=0                d=d+1            A[d]=x            if w==t:                break            w=x.right        self.min=0        for i in range(0,int(math.log(self.n,2)+1)):                if A[i]!=0:                    if self.min==0:                        self.min=A[i]                        A[i].left=A[i]                        A[i].right=A[i]                    else:                        A[i].right=self.min                        A[i].left=self.min.left                        A[i].left.right=A[i]                        self.min.left=A[i]                        if A[i].key<self.min.key:                            self.min=A[i] 

需调用H.Link(y,x)来重新时y变成x的子节点

Fib:def Link(self,y,x):        y.right.left=y.left        y.left.right=y.right        y.p=x        x.degree=x.degree+1        y.mark=False        if x.child==0:            x.child=y            y.left=y            y.right=y        else:            c=x.child            y.right=c            y.left=c.left            y.left.right=y            c.left=y

H.DecreaseKey(x,k):将堆H中元素x的关键字变为k,并相应的改变元素x在堆中的位置

Fib:def DecreaseKey(self,x,k):        if k>x.key:            print("error: new key is greater than current key")        x.key=k        y=x.p        if y!=0 and x.key<y.key:            self.Cut(x,y)            self.CasCut(y)        if x.key<self.min.key:            self.min=x

需调用H.Cut(x,y)切断x和其父节点y之间的链接,使x成为根节点

Fib:    def Cut(self,x,y):        if y.degree==1:            y.child=0            x.p=0        else:            if x==y.child:                w=x.right                w.left=x.left                x.left.right=x.right                y.child=w            else:                w=y.child                w.left=x.left                x.left.right=x.right        y.degree=y.degree-1        x.right=self.min        x.left=self.min.left        x.left.right=x        self.min.left=x        if x.key<self.min.key:            self.min=x        x.p=0        x.mark=False

调用H.CasCut(y)完成级联切断操作

Fib:def Cut(self,x,y):        if y.degree==1:            y.child=0            x.p=0        else:            if x==y.child:                w=x.right                w.left=x.left                x.left.right=x.right                y.child=w            else:                w=y.child                w.left=x.left                x.left.right=x.right        y.degree=y.degree-1        self.Insert(x)        x.p=0        x.mark=False

H.Delete(x):从堆中删除元素x

Fib:def Delete(self,x):        self.DecreaseKey(x,-1)        self.ExtractMin()

H.printHeap():显示堆结构

Fib:def printHeap(self):        root=self.min        c=root        print("min node and root nodei s: %d" % c.key)        c.printNode()        c=c.right        while c!=root:            print("root node is:%d" % c.key)            c.printNode()            c=c.right

H.FindNode(key):寻找关键字为key的节点,若存在返回指向该节点的指针

Fib:def FindNode(self,key): #find the node.key is key        w=self.min        resultnode=0        if w.key>key:            return 0        else:            cr=w            while True:                if cr.key==key:                    return cr                else:                    if cr.child!=0:                        resultnode=cr.child.SearchChild(key)                    if resultnode!=0:                        return resultnode                    cr=cr.right                    if cr==w:                        return 0
0 0
原创粉丝点击