数据结构与算法:图

【图】

1. 实现有向图、无向图、有权图、无权图的邻接矩阵和邻接表表示方法

class Undigraph(object):

def __init__(self, vertex_num): self.v_num = vertex_num self.adj_tbl = [] for i in range(self.v_num + 1): self.adj_tbl.append([]) def add_edge(self, s, t): if s > self.v_num or t > self.v_num: return False self.adj_tbl[s].append(t) self.adj_tbl[t].append(s) return True def __len__(self): return self.v_num def __getitem__(self, ind): if ind > self.v_num: raise IndexError("No Such Vertex!") return self.adj_tbl[ind] def __repr__(self): return str(self.adj_tbl) def __str__(self): return str(self.adj_tbl) class Digraph(object): def __init__(self, vertex_num): self.v_num = vertex_num self.adj_tbl = [] for i in range(self.v_num + 1): self.adj_tbl.append([]) def add_edge(self, frm, to): if frm > self.v_num or to > self.v_num: return False self.adj_tbl[frm].append(to) def __len__(self): return self.v_num def __getitem__(self, ind): if ind > self.v_num: raise IndexError("No such vertex!") return self.ajd_tbl[ind] def __repr__(self): return str(self.adj_tbl) def __str__(self): return str(self.adj_tbl)

 

2. 实现图的深度优先搜索、广度优先搜索

#dfs

from pythonds.graphs import Graph

class DFSGraph(Graph):

    def __init__(self):

        super().__init__()

        self.time = 0

 

    def dfs(self):

        for aVertex in self:

            aVertex.setColor('white')

            aVertex.setPred(-1)

        for aVertex in self:

            if aVertex.getColor() == 'white':

                self.dfsvisit(aVertex)

 

    def dfsvisit(self,startVertex):

        startVertex.setColor('gray')

        self.time += 1

        startVertex.setDiscovery(self.time)

        for nextVertex in startVertex.getConnections():

            if nextVertex.getColor() == 'white':

                nextVertex.setPred(startVertex)

                self.dfsvisit(nextVertex)

        startVertex.setColor('black')

        self.time += 1

        startVertex.setFinish(self.time)


#bfs

from pythonds.graphs import Graph, Vertex

from pythonds.basic import Queue

 

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')

 

3. 实现 Dijkstra 算法、A* 算法

def find_lowest_cost_node(costs):
    lowest_cost = float("inf")
    lowest_cost_node = None
    # Go through each node.
    for node in costs:
        cost = costs[node]
        # If it's the lowest cost so far and hasn't been processed yet...
        if cost < lowest_cost and node not in processed:
            # ... set it as the new lowest-cost node.
            lowest_cost = cost
            lowest_cost_node = node
    return lowest_cost_node

# Find the lowest-cost node that you haven't processed yet.
node = find_lowest_cost_node(costs)
# If you've processed all the nodes, this while loop is done.
while node is not None:
    cost = costs[node]
    # Go through all the neighbors of this node.
    neighbors = graph[node]
    for n in neighbors.keys():
        new_cost = cost + neighbors[n]
        # If it's cheaper to get to this neighbor by going through this node...
        if costs[n] > new_cost:
            # ... update the cost for this node.
            costs[n] = new_cost
            # This node becomes the new parent for this neighbor.
            parents[n] = node
    # Mark the node as processed.
    processed.append(node)
    # Find the next node to process, and loop.
    node = find_lowest_cost_node(costs)

 

4. 实现拓扑排序的 Kahn 算法、DFS 算法

class Solution:
    def Dfs(self, G):
        for u in G.V:
            u.color = 'white'
            u.pi = None
        global time
        time = 0
        for u in G.V:
            if u.color == 'white':
                self.DfsVisit(G, u)

    def DfsVisit(self, G, u):
        global time
        time = time + 1
        u.d = time
        u.color = 'gray'
        for v in u.adj:
            if v.color == 'white':
                self.DfsVisit(G, v)
                v.pi = u
        u.color = 'black'
        time = time + 1
        u.f = time

    def TopologicalSort(self, G):
        LinkedList = Vertex('#')
        self.Dfs(G)
        G.V.sort(key=lambda v:v.f)
        for v in G.V:
            v.next = LinkedList.next
            LinkedList.next = v
        return LinkedList

 

  练习:

  1. 岛屿的个数 https://leetcode-cn.com/problems/number-of-islands/description/

  思路:深度优先搜索递归

class Solution:
    def numIslands(self, grid: List[List[str]]) -> int:
        #遍历所有格点,每当发现陆地就用dfs递归沉没它周围的陆地,那么我们发现陆地的次数就是岛屿数
        #try-except异常处理
        try:
            m = len(grid)
            n = len(grid[0])
        except:
            return 0
        
        def dfs(i, j):
            if 0 <= i < m and 0 <= j < n and int(grid[i][j]):
                grid[i][j] = '0'
                for a, b in ((1, 0), (0, -1), (-1, 0), (0, 1)):
                    dfs(i + a, j + b)
                    
        r = 0
        for i in range(m):
            for j in range(n):
                r += int(grid[i][j])
                dfs(i, j) # 调用dfs沉没一整块陆地
        return r

 

  2. 有效的数独 https://leetcode-cn.com/problems/valid-sudoku/

  思路:集合set

class Solution:
    def isValidSudoku(self, board: List[List[str]]) -> bool:
        #分别判断行,列,3*3所组成的list里面是否有重复值
        for line in board:
            l = [value for value in line if value !='.']
            if len(set(l)) != len(l):
                return False
        for cursor in range(9):
            l=[board[i][cursor] for i in range(0,9) if board[i][cursor] !='.']
            if len(set(l)) != len(l):
                return False

        for i in [2,5,8]:
            for j in [2,5,8]:
                l = [board[i-m][j-n] for m in range(3) for n in range(3) if board[i-m][j-n] !="."]
                if len(set(l))!=len(l):
                    return False
        return True

 

转载于:https://www.cnblogs.com/deeplearning-man/p/10884765.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值