1.先创建一个二叉树结构,如下图:
2.前序排列: 前序排列的顺序即:根→左→右,那么我们先把头根节点压入栈,然后再把头根节点的左节点压入栈,此时这个左节点就成为了第二个根节点,一直按照此左子树路径压栈 (可见这是一个循环过程,注!每次压入栈时也应该把这个节点打印出来,因为根节点是第一个被访问的),直到左子树路径上的所有节点都被压入栈,此时退出循环弹出栈顶元素,再判断其是否有右子节点,如果有右子节点就继续按照右子节点的左子树路径继续压栈,如果没有右子节点,则继续弹出下一个栈顶元素,然后按照上面的方法继续压栈 (这也是一个循环过程),最后循环结束,所有的节点被前序遍历打印出来了
代码如下:
def preorder(self):
p = self.__root #一个指针指向头根节点
stack = [] #创建一个栈用来进行节点的压栈和出栈操作
while stack or p:
while p != None: #内层循环,当循环结束,所有的左子树路径上的节点就都被压入栈了
print(p.elem,end=' ') #打印根节点
stack.append(p)
p = p.left
p = stack.pop() #出了循环弹出栈顶节点
if p.right is not None: #判断该节点是否有右子节点
p = p.right
else: #没有右子节点的情况
p = None
也可以对外层循环的代码块简化一个,如下:
def preorder(self):
p = self.__root
stack = []
while stack or p:
while p != None:
print(p.elem,end=' ')
stack.append(p)
p = p.left
p = stack.pop()
p = p.right #直接指向栈顶结点的右子节点,没有就为空,有就继续进入内层循环
3.中序循环: 中序排列的顺序即:左→根→右,那么我们先把头根节点压入栈,然后再把头根节点的左节点压入栈,此时这个左节点就成为了第二个根节点,一直按照此左子树路径压栈 (可见这是一个循环过程,注!每次压入栈时就不用打印该节点元素了,因为现在根节点不是第一个被访问的了),直到左子树路径上的所有节点都被压入栈,此时退出循环弹出栈顶元素并打印出来,再判断其是否有右子节点,如果有右子节点就继续按照右子节点的左子树路径继续压栈,如果没有右子节点,则继续弹出下一个栈顶元素,然后按照上面的方法继续压栈 (这也是一个循环过程),最后循环结束,所有的节点被中序遍历打印出来了。
代码如下:
def inorder(self):
p = self.__root
stack = []
while stack or p:
while p:
stack.append(p)
p = p.left
p = stack.pop()
''' 应该在外层循环的代码块内进行打印,这样左节点才是第一个被访问的'''
print(p.elem,end=' ')
if p.right is not None:
p = p.right
else:
p = None
也可以对外层循环的代码块简化一下,如下:
def inorder(self):
p = self.__root
stack = []
while stack or p:
while p:
stack.append(p)
p = p.left
p = stack.pop()
print(p.elem,end=' ')
p = p.right
测试代码如下:
c = a.preorder()
print(c)
e = a.inorder()
print(e)
结果如下:
0 3 7 6 9 1 4 2 5 8 None
6 7 9 3 4 1 0 5 2 8 None