def __TSORT(self, v: int, S: Stack): """(连通域)基于DFS的拓扑排序算法""" assert (0 <= v) and (v < self.n) V = self.V[v] self.clock += 1 V.dTime = self.clock V.status = VStatus.DISCOVERD u = self.firstNbr(v) while -1 < u: U = self.V[u] E = self.E[v][u] if VStatus.UNDISCOVERD == U.status: U.parent = v E.type = EType.TREE print(U, end='\t') if not self.__TSORT(u, S): # 从顶点u出发深入搜索 return False # 若u及其后代不能拓扑排序(则全图亦必如此),故返回并报告 elif VStatus.DISCOVERD == U.status: # 一旦发现后向边(非DAG),则不必深入,故返回报告 E.type = EType.BACKWARD return False else: E.type = EType.FORWARD if V.dTime > U.dTime else EType.CROSS u = self.nextNbr(v, u) V.status = VStatus.VISITED S.push(self.vertex(v)) return True # v及后代可以拓扑排序
def visitAlongLeftBranch(self, s: Stack): """从当前节点出发,沿左分支不断深入,直至没有左分支的节点;沿途节点遇到后立即访问""" x = copy(self) while x: print(x.data, end="->") if x._rc: s.push(x._rc) x = x._lc
def travPre_I2(self): """二叉树先序遍历迭代版本""" s = Stack([]) x = copy(self) while True: x.visitAlongLeftBranch(s) if s.empty(): break x = s.pop()
def travIn_I1(self): """二叉树中序遍历迭代版本1""" x = copy(self) s = Stack([]) while True: if x: x.goAlongLeftBranch(s) if s.empty(): break x = s.pop() print(x.data, end="->") x = x.rc
def gotoHLVEL(self, s: Stack): x = s.top() while x: if BinNode.HasLChild(x): if BinNode.HasRChild(x): s.push(x.rc) s.push(x.lc) else: s.push(x.rc) s.pop()
def bcc(self, s: Any): """基于DFS的双连通分量分解算法""" assert (0 <= s) and (s < self.n) self.__reset() self.clock = 0 v = s S = Stack([], self.n) while True: if VStatus.UNDISCOVERD == self.status(v): self.__BCC(v, S) S.pop() v += 1 v %= self.n if s == v: break
def tSort(self, s: int): """基于DFS的拓扑排序算法: 每一个顶点都不会通过边,指向其在此序列中的前驱顶点,这样的一个线性序列,称作原有向图的一个拓扑排序 """ assert (0 <= s) and (s < self.n) self.__reset() self.clock = 0 v = s S = Stack([], self.n) # 用栈记录排序顶点 while True: if VStatus.UNDISCOVERD == self.status(v): if not self.__TSORT(v, S): while not S.empty(): # 任一连通域(亦即整图)非DAG S.pop() break # 则 不必继续计算,故直接返回 v += 1 v %= self.n if s == v: break
def __BCC(self, v: int, S: Stack): """(连通域)基于DFS的双连通分量分解算法""" assert (0 <= v) and (v < self.n) self.clock += 1 V = self.V[v] V.dTime = self.clock V.fTime = self.clock V.status = VStatus.DISCOVERD S.push(v) u = self.firstNbr(v) while -1 < u: U = self.V[u] E = self.E[v][u] if VStatus.UNDISCOVERD == U.status: U.parent = v E.type = EType.TREE print(U, end='\t') self.__BCC(u, S) if self.fTime(u) < self.dTime(v): V.fTime = min(V.fTime, U.fTime) else: while v != S.pop(): pass S.push(v) elif VStatus.DISCOVERD == U.status: E.type = EType.BACKWARD if u != V.parent: V.fTime = min(V.fTime, U.dTime) else: E.type = EType.FORWARD if V.dTime < U.dTime else EType.CROSS u = self.nextNbr(v, u) V.status = VStatus.VISITED
def travPost_I(self): """二叉树后序遍历迭代""" x = copy(self) s = Stack([]) if x: s.push(x) while not s.empty(): if s.top() != x.parent: self.gotoHLVEL(s) x = s.pop() print(x.data, end="->")
def travIn_I2(self): """二叉树中序遍历迭代版本2""" x = copy(self) s = Stack([]) while True: if x: s.push(x) x = x.lc elif not s.empty(): x = s.pop() print(x.data, end="->") x = x.rc else: break
def goAlongLeftBranch(self, s: Stack): """从当前节点出发,沿分支不断深入,直至没有左分支的节点""" x = copy(self) while x: s.push(x) x = x.lc