数据结构与算法(python版)之图
一、图的基本概念及相关术语
1.什么是图
2.相关术语
二、图抽象数据类型
1.图的定义
2.图的实现方法
三、图抽象数据类型的python实现
1.实例
源程序:
class Vertex:
def __init__(self,key):
self.id=key
self.connectedTo={}
def addNeighbor(self,nbr,weight=0):
self.connectedTo[nbr]=weight
def __str__(self):
return str(self.id)+'connectedTo'+str([x.id for x in self.connectedTo])
def getConnections(self):
return self.connectedTo.keys()
def getId(self):
return self.id
def getWeight(self,nbr):
return self.connectedTo[nbr]
class Graph:
def __init__(self):
self.vertList={}
self.numVertices=0
def addVertex(self,key):
self.numVertices=self.numVertices+1
newVertex=Vertex(key)
self.vertList[key]=newVertex
return newVertex
def getVertex(self,n):
if n in self.vertList:
return self.vertList[n]
else:
return None
def __contains__(self,n):
return n in self.vertList
def addEdge(self,f,t,cost=0):
if f not in self.vertList:
nv=self.addVertex(f)
if t not in self.vertList:
nv =self.addVertex(t)
self.vertList[f].addNeighbor(self.vertList[t],cost)
def getVertexs(self):
return self.vertList.keys()
def __iter__(self):
return iter(self.vertList.values())
四、图的应用:词梯问题
1.词梯问题
源程序:
def buildGraph(worldFile):
d={}
g=Graph()
wfile=open(worldFile,'r')
#创建单词桶
for line in wfile:
world=line[:-1]
for i in range(len(world)):
bucket=world[:i]+'_'+world[i+1:]
if bucket in d:
d[bucket].append(world)
else:
d[bucket]=[world]
#创建图
for bucket in d:
for world1 in d[bucket]:
for world2 in d[bucket]:
if world1!=world2:
g.addEdge(world1,world2)
return g
五、广度优先搜索
源程序:
import sys
import os
from pythonds.basic.queue import Queue
class Vertex:
def __init__(self,key):
self.id=key
self.connectedTo={}
self.color = 'white'
self.dist = sys.maxsize
self.pred = None
def addNeighbor(self,nbr,weight=0):
self.connectedTo[nbr]=weight
def __str__(self):
return str(self.id)+'connectedTo'+str([x.id for x in self.connectedTo])
def getConnections(self):
return self.connectedTo.keys()
def getId(self):
return self.id
def getWeight(self,nbr):
return self.connectedTo[nbr]
def setColor(self, color):
self.color = color
def setDistance(self, d):
self.dist = d
def setPred(self, p):
self.pred = p
def getPred(self):
return self.pred
def getDistance(self):
return self.dist
def getColor(self):
return self.color
class Graph:
def __init__(self):
self.vertList={}
self.numVertices=0
def addVertex(self,key):
self.numVertices=self.numVertices+1
newVertex=Vertex(key)
self.vertList[key]=newVertex
return newVertex
def getVertex(self,n):
if n in self.vertList:
return self.vertList[n]
else:
return None
def __contains__(self,n):
return n in self.vertList
def addEdge(self,f,t,cost=0):
if f not in self.vertList:
nv=self.addVertex(f)
if t not in self.vertList:
nv =self.addVertex(t)
self.vertList[f].addNeighbor(self.vertList[t],cost)
def getVertexs(self):
return self.vertList.keys()
def __iter__(self):
return iter(self.vertList.values())
def buildGraph(worldFile):
d={}
g=Graph()
wfile=open(worldFile,'r')
#创建单词桶
for line in wfile:
world=line[:-1]
for i in range(len(world)):
bucket=world[:i]+'_'+world[i+1:]
if bucket in d:
d[bucket].append(world)
else:
d[bucket]=[world]
#创建图
for bucket in d:
for world1 in d[bucket]:
for world2 in d[bucket]:
if world1!=world2:
g.addEdge(world1,world2)
return g
def bfs(g,start):
start.setDistance(0)
start.setPred(None)
vertQueue=Queue()
vertQueue.enqueue(start)
while vertQueue.size()>0:
currentVert=vertQueue.dequeue()
for nbr in currentVert.getConnections():
if nbr.getColor()=='white':
nbr.setColor('gray')
nbr.setDistance(currentVert.getDistance()+1)
nbr.setPred(currentVert)
vertQueue.enqueue(nbr)
currentVert.setColor('black')
def traverse(y):
while y.getPred():
print(y.getId())
y=y.getPred()
print(y.getId())
wordGraph=buildGraph("fourletterwords.txt")
bfs(wordGraph,wordGraph.getVertex('FOOL'))
traverse(wordGraph.getVertex('SAGE'))
六、图的应用:骑士周游问题
1.问题描述
2.构建骑士周游图
3.骑士周游算法实现
4.源程序
def genLegalMoves(x,y,bdSize):
newMoves=[]
moveOffsets=[(-1,-2),(-1,2),(-2,-1),(-2,1),(1,-2),(1,2),(2,-1),(2,1)]
for i in moveOffsets:
newX=x+i[0]
newY=y+i[1]
if legalCoord(newX,bdSize) and legalCoord(newY,bdSize):
newMoves.append((newX,newY))
return newMoves
def legalCoord(x,bdSize):
if x>=0 and x<bdSize:
return True
else:
return False
def knightGraph(bdSize):
ktGraph=Graph()
for row in range(bdSize):
for col in range(bdSize):
nodeId=posToNodeId(row,col,bdSize)
newPosition=genLegalMoves(row,col,bdSize)
for e in newPosition:
nid=posToNodeId(e[0],e[1],bdSize)
ktGraph.addEdge(nodeId,nid)
return ktGraph
def posToNodeId(row,col,bdSize):
return row*bdSize+col
def knightTour(n,path,u,limit):
u.setColor('gray')
path.append(u)
if n<limit:
nbrList=list(u.getConnections())
i=0
done=False
while i<len(nbrList) and not done:
if nbrList[i].getColor()=='white':
done=knightTour(n+1,path,nbrList[i],limit)
i=i+1
if not done:
path.pop()
u.setColor('white')
else:
done=True
return done
七、骑士周游问题的改进