二叉树的建立以及遍历的多种实现(python版)

二叉树是很重要的数据结构,在面试还是日常开发中都是很重要的角色。

首先是建立树的过程,对比C或是C++的实现来讲,其涉及到了较为复杂的指针操作,但是在面向对象的语言中,就不需要考虑指针, 内存等。首先我们需要定义一个树节点, 我们采用基于链表设计的节点, 首先定义一个数据域, 其次就是左孩子和右孩子。如下定义:

# 树节点的定义
class Node:
    def __init__(self, data=-1, lchild=None, rchild=None):
        self.lchild = lchild  # 表示左子树
        self.rchild = rchild  # 表示右子树
        self.data = data  # 表示数据域

建立树的实现有两种,遍历建树与层次建树,这两种分别是基于堆栈和队列来实现的,先来看看最基本的递归建树。
递归建树的过程无非就是一路走到底,但是需要将节点的左右孩子节点对其余的节点相关联起来。因此,我们可以如此来实现:

def traversal_create(self, root):
data = input()
if data is "#":
return None
else:
root.data = data
root.lchild = self.traversal_create(root.lchild)
root.rchild = self.traversal_create(root.rchild)
return root

首先我们传入的参数是一个默认的节点,其data数据域为-1,然后我们接受输入的数据,赋值给节点数据域,然后就是递归了,将左右孩子节点关联起来。总体来讲,应该不难理解。

下面看看层次建树的实现,所谓层次建树其实就是基于队列的操作,利用队列先进先出的特点,每次我们访问一个节点的时候,将其存入队列中,待遍历玩当前节点的左右孩子节点,队列就弹出一个节点,之后的操作都是一样的。看看代码:

def add(self, elem):
node = Node(elem)
# 根节点
if self.root.data == -1:
self.root = node
self.myQueue.append(self.root)
else:
treeNode = self.myQueue[0] # 记录结点
if treeNode.lchild is None:
treeNode.lchild = node
self.myQueue.append(treeNode.lchild)
else:
treeNode.rchild = node
self.myQueue.append(treeNode.rchild)
self.myQueue.popleft() # 弹出已经处理好左右子树的父结点

我们输入一个数据,然后根据数据初始化一个节点,放入队列中,随后就是访问的操作了。

树的三序遍历就不用说了,基于递归的,很好理解,那么基于队列以及堆栈的的遍历呢?
对比下基于队列的建树,我们完全可以写出基于队列的遍历, 也是使用队列来存储节点,然后输出左右孩子的数据:

# 层次遍历 使用队列
def queue_tarversal(self, root):
if root is None:
return
q = deque()
q.append(root)
while q:
node = q.pop()
print(node.data)
if node.lchild is not None:
q.append(node.lchild)
else:
q.append(node.rchild)

基于堆栈的呢?联想下堆栈的特点,我们一路沿着左子树遍历下去,同时使用堆栈来存储元素,然后在弹出遍历右孩子节点:

# 使用堆栈来遍历
def stack_traversal(self, root):
if root is None:
return
mystack = []
node = root
while node or mystack:
while node:
print(node.data)
mystack.append(node)
node = node.lchild
node = mystack.pop()
node = node.rchild

数据结构是难点也是基础,不管怎么样都应该好好学习。

完整代码:

‘‘‘ 二叉树的建立及实现 (递归与非递归) ‘‘‘
from collections import deque

# 树节点的定义
class Node:
    def __init__(self, data=-1, lchild=None, rchild=None):
        self.lchild = lchild  # 表示左子树
        self.rchild = rchild  # 表示右子树
        self.data = data  # 表示数据域

class Create_Tree:
    def __init__(self):
        self.root = Node()  # 表示结点
        self.myQueue = deque()  # 使用队列不会有太多的内存开销

    # 按层次生成树
    def add(self, elem):
        node = Node(elem)
        # 根节点
        if self.root.data == -1:
            self.root = node
            self.myQueue.append(self.root)
        else:
            treeNode = self.myQueue[0]  # 记录结点
            if treeNode.lchild is None:
                treeNode.lchild = node
                self.myQueue.append(treeNode.lchild)
            else:
                treeNode.rchild = node
                self.myQueue.append(treeNode.rchild)
                self.myQueue.popleft()  # 弹出已经处理好左右子树的父结点

    # 递归建树
    def traversal_create(self, root):
        data = input()
        if data is "#":
            return None
        else:
            root.data = data
            root.lchild = self.traversal_create(root.lchild)
            root.rchild = self.traversal_create(root.rchild)
        return root

    # 前序遍历输出
    def digui(self, root):
        if root is None:
            return
        print(root.data)
        self.digui(root.lchild)
        self.digui(root.rchild)

    # 使用堆栈来遍历
    def stack_traversal(self, root):
        if root is None:
            return
        mystack = []
        node = root
        while node or mystack:
            while node:
                print(node.data)
                mystack.append(node)
                node = node.lchild
            node = mystack.pop()
            node = node.rchild

    # 层次遍历 使用队列
    def queue_tarversal(self, root):
        if root is None:
            return
        q = deque()
        q.append(root)
        while q:
            node = q.pop()
            print(node.data)
            if node.lchild is not None:
                q.append(node.lchild)
            else:
                q.append(node.rchild)

if __name__ == "__main__":
    elems = range(10)
    tree = Create_Tree()
    for i in elems:
        # 非递归建树,主要就是根据 队列FIFO的特点以及广度遍历的思路
        tree.add(i) 

    # 递归建树
    # tree.traversal_create(tree.root)

    # 递归遍历
    tree.digui(tree.root)
    # 栈遍历
    # tree.stack_traversal(tree.root)

时间: 2024-11-09 10:18:01

二叉树的建立以及遍历的多种实现(python版)的相关文章

C语言二叉树的建立与遍历

二叉树的建立和遍历都要用到递归,先暂时保存一下代码,其中主要是理解递归的思想,其它的就都好理解了.这里是三种遍历方式,其实理解一种,其它的几个就都理解了,就是打印出来的顺序不一样而已.建立和遍历的方式差不多.也分好几种方式建立,这里 就写一种,就是先序建立 1 #include <stdio.h> 2 #include <stdlib.h> 3 4 typedef struct TreeNode{ 5 char ch; 6 struct TreeNode *lchild, *rch

二叉树的建立与遍历(山东理工OJ)

数据结构实验之二叉树的建立与遍历 题目描述 已知一个按先序序列输入的字符序列,如abc,,de,g,,f,,,(其中逗号表示空节点).请建立二叉树并按中序和后序方式遍历二叉树,最后求出叶子节点个数和二叉树深度. 输入 输入一个长度小于50个字符的字符串. 输出 输出共有4行: 第1行输出中序遍历序列: 第2行输出后序遍历序列: 第3行输出叶子节点个数: 第4行输出二叉树深度. 示例输入 abc,,de,g,,f,,, 示例输出 cbegdfa cgefdba 3 5 #include <iost

关于二叉树,建立、遍历、求节点最大距离

今天做了一题求二叉树节点的最大距离,顺便写了下二叉树的建立,遍历的过程. 我觉得这题的主要思想是深度遍历+动态规划,我们在深度遍历的过程中,对于某一个子树,求出左右子树叶子节点到根节点的最大距离,进而求出经过根节点的最大距离. 最后求出所有子树经过根节点的最大距离.就是这个题目的最终结果.代码如下: //二叉树的建立,以及遍历 //16 14 8 2 -1 -1 4 -1 -1 7 1 -1 -1 -1 10 9 -1 -1 3 -1 -1 //16 14 8 2 -1 -1 4 -1 -1 7

小朋友学数据结构(3):二叉树的建立和遍历

小朋友学数据结构(3):二叉树的建立和遍历 一.基本概念 BinaryTree.png 二叉树:每个结点的子结点个数不大于2的树,叫做二叉树. 根结点:最顶部的那个结点叫做根结点,根结点是所有子结点的共同祖先.比如上图中的"7"结点就是根结点. 子结点:除了根结点外的结点,都叫子结点. 叶子结点:没有子结点的结点,叫做叶子结点.比如上图中的"1"结点."5"结点和"11"结点. 二叉树的遍历,有三种: (1)前序遍历:先遍历根

数据结构 二叉树的建立、遍历、销毁的递归算法(C语言)

这些是较为简单的二叉树的建立.遍历.销毁的递归算法.假设二叉树都用二叉链作为存储结构,并约定根节点的指针用T表示. 为了简化问题,我们用char类型的字符代替树中的数据,并且用前序遍历的算法,建立二叉树过程如下: 输入一个根节点. 若输入的是“ ”(即空格字符),则表明改结点为空,T设置为NULL: 若输入的不是“ ”(空格字符),则将字符存入到T->data中,并依次递归建立它的左子树T->lchild,和右子树T->rchild; 测试的源代码如下: 1 #include<st

二叉树的建立与遍历(二)(c++实现)

[目标] 建立如下所示的一棵二叉树,并且输出其对应的前序遍历.中序遍历.后序遍历. [代码实现] // Binarytree.h #ifndef Binarytree_H #define Binarytree_H template<class T> class Binarytree; template<class T> class TreeNode { friend class Binarytree<T>; private: T data; TreeNode<T&

C++ 二叉树的建立与遍历

重温了一下二叉树这个结构,以前上课的时候都是感觉懂了,具体实现还没有动手写过.主要写了二叉树的建立,递归遍历以及深度,根节点等方法. //树节点的头文件 #ifndef BinTreeNode_H_#define BinTreeNode_H_#define NULL 0class BinTreeNode{public: char data; BinTreeNode* leftChild; //左子树 BinTreeNode* rightChild;//右子树 public: BinTreeNod

二叉树的建立与遍历(c++实现)

[目标] 建立如下所示的一棵二叉树,并且输出其对应的前序遍历.中序遍历.后序遍历. [代码实现] 建立二叉树以及实现遍历的操作存放在Binarytree.h文件中 //Binarytree.h #ifndef Binarytree_H #define Binarytree_H template<class T> class Binarytree; template<class T> class TreeNode { friend class Binarytree<T>;

二叉树的建立和遍历

二叉树是十分重要的数据结构,主要用来存放数据,并且方便查找等操作,在很多地方有广泛的应用. 今天主要写的最基本的二叉树,后续会继续写线索二叉树,二叉排序树,平衡二叉树等. 二叉树的建立思路仍然是采用的递归的思想,给定一个指向根节点的指针,然后递归调用ceate()函数,自动生成一个二叉树.就像是在地上挖了个坑(根节点),然后他会拿着斧子(create函数)自己挖一颗很大的洞穴(二叉树)出来.当然挖坑前需要先定义每个洞长什么样(定义节点结构). 1 #include<iostream> 2 us