数据结构和算法-------树和一些涉及到的算法
树的定义
这就是一个简单基本的树
根节点:没有前驱,有后继
叶子: 就是终端节点,没有后继
双亲: 上层的节点,直接前驱
孩子:下层端,直接后继
这几个是比较重要的概念,其他的概念就不是很重要了
树的表示
图形表示法
这个是用文字表示各个元素之间的关系,这个跟我们写代码没什么联系。
左孩子,右兄弟表示法
data是存储的数据,left和right是指针,分别表示左孩子和右兄弟,我们将一般的树转化成这种二叉树表示方法,这种方法就可以进行编程表示,
如图:就是将一般的树转化成了二叉树的表示形式,规则:左孩子,右兄弟。
数的存储
数的存储一般有两种方式,1.顺序存储 2.链式存储
将数按照一定顺序存储到内存中
这种方式存储缺点:对于一种无法还原的树结构是无法还原的。
2.链式存储
这种存储结构中data就是存放节点的数据,next是该节点的指针域,如果分支太多,则地址占用也会太多,next的个数就会增多,没有一种稳定的表示方法,
所以我们通常将树转化成二叉树来进行代码的编写和存储,所以就有下图的二叉树结构体表示形式,第二个就是二叉树其中的一个表示节点。
树的遍历方式
二叉树的遍历分为以下三种:
基本遍历方法:如下图,先序遍历:根左右:先根,是1,后左,是2,然后到了2之后,以2作为跟,继续以一个新的节点开始,所以要继续 左, 是4,然后还是以4为跟节点,然后再左 ,左没有了,然后右 是5,然后返回到上一层节点的右,是3,然后以3为跟节点, 再左是6,然后以6为跟节点,再左,没有,然后右,是8,然后再返回上一层,的右,是7,所以遍历是每到一层,都会作为一个新的单元进行处理。剩下的都是一个意思了。
先序遍历:遍历顺序规则为【根左右】
中序遍历:遍历顺序规则为【左根右】
后序遍历:遍历顺序规则为【左右根】
上代码:
# 一个基本的树节点结构
class TreeNode(object):
def __init__(self, x):
self.val = x# 数值
self.left = None# 左孩子
self.right = None # 右孩子
# 树的遍历方式
# 先序遍历
def preOderResivise(root):
if root == None:
return None
print(root.val)
preOderResivise(root.left)
preOderResivise(root.right)
# 中序遍历
def midOderResivise(root):
if root == None:
return None
midOderResivise(root.left)
print(root.val)
midOderResivise(root.right)
# 后续遍历
def latOderResivise(root):
if root == None:
return None
latOderResivise(root.left)
latOderResivise(root.right)
print(root.val)
if __name__ == '__main__':
T1 = TreeNode(1)
T2 = TreeNode(2)
T3 = TreeNode(3)
T4 = TreeNode(4)
T5 = TreeNode(5)
T6 = TreeNode(6)
T7 = TreeNode(7)
T8 = TreeNode(8)
T1.left = T2
T1.right = T3
T2.left = T4
T2.right = T5
T3.left = T6
T3.right = T7
T6.right = T8
preOderResivise(T1)
midOderResivise(T1)
latOderResivise(T1)
数的遍历
题目描述
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
分析:
思路就是将给出的遍历结果,按遍历的特点将该结果分成树单元,用递归的方法重建二叉树
# -*- coding:utf-8 -*-
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
# 返回构造的TreeNode根节点
def reConstructBinaryTree(self, pre, tin):
#首先要判断给的序列是否是无效序列,也是递归的终止条件
if not pre or not tin:
return None
if len(pre)!= len(tin):
return None
# 首先要找到数的根节点root
root = pre[0]
treeNode = TreeNode(root)
pos = tin.index(root)# 找到根节点的索引位置
# 将给出的遍历结果分成左子树和右子树,
preLeft = pre[1:pos+1]
preRight = pre[pos+1:]
tinLeft = tin[:pos]
tinRight = tin[pos+1:]
# 这里递归,不断的区分左子树和右子树
leftNode = self.reConstructBinaryTree(preLeft,tinLeft)
rightNode = self.reConstructBinaryTree(preRight,tinRight)
treeNode.left = leftNode
treeNode.right = rightNode
return treeNode
# write code here