
编程开发
切片copy
当我们需要在Go语言中复制一个切片时,我们可以使用内置的copy函数。copy函数可以将一个切片的元素复制到另一个切片中。下面是一个示例: 在上面的示例中,我们首先创建了一个源切片
将A选为源点,A出队列Q,加入到树T中,更新B,C的d值:
最小边为(A,B),将B移出Q,加入到树T中,更新CDE的d值
以此类推,得到结果:
代码
def Prim(G,s):
path={}
pre={}
alist=[]
for v in G:
alist.append(v)
path[v]=sys.maxsize
pre[v]=s
path[s]=0
queue=PriorityQueue(path)
queue.buildHeap(alist)
while queue.size>0:
vertex=queue.delMin()
for v in vertex.getNeighbors():
newpath=vertex.getWeight(v)
if v in queue.queue and newpath<path[v]:
path[v]=newpath
pre[v]=vertex
queue.perUp(v)
return pre
if __name__=='__main__':
g= Graph()
g.addEdge('a','b',2)
g.addEdge('b','a',2)
g.addEdge('a','c',3)
g.addEdge('c','a',3)
g.addEdge('b','c',1)
g.addEdge('c','b',1)
g.addEdge('b','d',1)
g.addEdge('d','b',1)
g.addEdge('d','e',1)
g.addEdge('e','d',1)
g.addEdge('b','e',4)
g.addEdge('e','b',4)
g.addEdge('c','f',5)
g.addEdge('f','c',5)
g.addEdge('e','f',1)
g.addEdge('f','e',1)
g.addEdge('f','g',1)
g.addEdge('g','f',1)
u=g.getVertex('a')
path=Prim(g,u)
for v in path:
print v.id,' after ',path[v].id
输出:
a after a
b after a
c after b
d after b
e after d
f after e
g after f
Prim算法是在无向图上运行的,记住把每一条边都加入到两个邻接表中。不用堆时运行时间为O(|V|2),使用二叉堆的运行时间是O(|E|log|V|)。
class Vertex(object):
def __init__(self,key):
self.id=key
self.adj={}
self.parent=None
self.rank=0
def addNeighbor(self,nbr,weight=0):
self.adj[nbr]=weight
def getNeighbors(self):
return self.adj.keys()
def getId(self):
return self.id
def getWeight(self,key):
return self.adj[key]
def Kruskal(G):
elist=[]
accpeted_e_list=[]
for v in G:
for vertex in v.getNeighbors():
e=Edge(v,vertex,v.getWeight(vertex))
elist.append(e)
queue=KruskalQueue(elist)
queue.buildHeap()
edge_num=0
while edge_num<G.size-1:
e=queue.delMin()
u=e.u
v=e.v
uset=Find(u)
vset=Find(v)
if uset!=vset:
accpeted_e_list.append(e)
edge_num+=1
Union(uset,vset)
return accpeted_e_list
class Edge(object):
def __init__(self,u,v,weight):
self.u=u
self.v=v
self.weight=weight
class KruskalQueue(object):
def __init__(self,elist):
self.elist=elist
self.size=len(self.elist)
def buildHeap(self):
for i in xrange(self.size/2-1,-1,-1):
self.perDown(i)
def delMin(self):
self.elist[0],self.elist[-1]=self.elist[-1],self.elist[0]
e=self.elist.pop()
self.size-=1
self.perDown(0)
return e
def perDown(self,i):
left=2*i+1
right=2*i+2
little=i
if left<=self.size-1 and self.elist[i].weight>self.elist[left].weight:
little=left
if right<=self.size-1 and self.elist[little].weight>self.elist[right].weight:
little=right
if little!=i:
self.elist[i],self.elist[little]=self.elist[little],self.elist[i]
self.perDown(little)
def perUp(self,i):
if i>0 and self.elist[i].weight<self.elist[(i-1)/2].weight:
self.elist[i],self.elist[(i-1)/2]=self.elist[(i-1)/2],self.elist[i]
self.perUp((i-1)/2)
def Find(v):
if v.parent is None:
return v
else:
v.parent=Find(v.parent)
return v.parent
def Union(u,v):
if u.rank<=v.rank:
u.parent=v
if u.rank==v.rank:
v.rank+=1
else:
v.parent=u
if __name__=='__main__':
g= Graph()
g.addEdge('a','b',2)
g.addEdge('a','c',3)
g.addEdge('b','c',1)
g.addEdge('b','d',1)
g.addEdge('d','e',1)
g.addEdge('b','e',4)
g.addEdge('f','c',5)
g.addEdge('f','e',1)
g.addEdge('g','f',1)
elist=Kruskal(g)
for e in elist:
print 'edge(%s,%s)'%(e.u.id,e.v.id)
输出:
>>> edge(b,c) edge(f,e) edge(b,d) edge(g,f) edge(d,e) edge(a,b)算法的最坏情况是O(|E|log|E|),受堆操作控制。图稠密的时候,E=O(V2),实际运行时间为O(ElogV)。
评论 0