二叉树:树的创建和遍历

前面介绍的链表,栈,队列都是一种顺序容器,访问元素的时候都是通过位置来访问的。如果想要通过值的方式来获取数据,只能通过遍历的方式。这在时间上消耗比较大。而二叉树可以做到不用遍历就可以通过值的方式来获取数据。二叉树是按值来保存元素,也按值来访问元素。

二叉树的相关术语:

树的结点:包含一个数据元素及若干指向子树的分支;

孩子结点:结点的子树的根称为该结点的孩子;

双亲结点:B 结点是A 结点的孩子,则A结点是B 结点的双亲;

兄弟结点:同一双亲的孩子结点; 堂兄结点:同一层上结点;

祖先结点: 从根到该结点的所经分支上的所有结点子孙结点:以某结点为根的子树中任一结点都称为该结点的子孙

结点层:根结点的层定义为1;根的孩子为第二层结点,依此类推;

树的深度:树中最大的结点层

结点的度:结点子树的个数

树的度: 树中最大的结点度。

叶子结点:也叫终端结点,是度为 0 的结点;

分枝结点:度不为0的结点;

有序树:子树有序的树,如:家族树;

无序树:不考虑子树的顺序;[3]

二叉树的定义:

二叉树是每个节点最多有两个子树的树结构。通常子树被称作“左子树”(left subtree)和“右子树”(right subtree)。二叉树常被用于实现二叉查找树和二叉堆。

二叉树的每个结点至多只有二棵子树(不存在度大于2的结点),二叉树的子树有左右之分,次序不能颠倒。二叉树的第i层至多有2^(i-1)个结点;深度为k的二叉树至多有2^k-1个结点;对任何一棵二叉树T,如果其终端结点数为n_0,度为2的结点数为n_2,则n_0=n_2+1。

若设二叉树的高度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第h层有叶子节点,并且叶子结点都是从左到右依次排布,这就是完全二叉树。

一棵深度为k,且有2^k-1个节点的二叉树,称为满二叉树。

这种树的特点是每一层上的节点数都是最大节点数。

而在一棵二叉树中,除最后一层外,若其余层都是满的,并且最后一层或者是满的,或者是在右边缺少连续若干节点,则此二叉树为完全二叉树。

具有n个节点的完全二叉树的深度为log2n+1。深度为k的完全二叉树,至少有2^(k-1)个节点,至多有2^k-1个节点。

二叉树的性质:

性质1:二叉树第i层上的结点数目最多为 2{i-1} (i≥1)。
性质2:深度为k的二叉树至多有2{k}-1个结点(k≥1)。
性质3:包含n个结点的二叉树的高度至少为log2 (n+1)
性质4:在任意一棵二叉树中,若终端结点的个数为n0,度为2的结点数为n2,则n0=n2+1 

完全二叉树的性质:假设有n个节点

如果i=1,则结点i是二叉树的根

如果i>1,则其双亲结点是i/2

如果2i<=n,则结点的左孩子为2i

如果2i>n,则结点i无左孩子

如果2i+1<=n, 则结点i的右孩子为2i+1

如果2i+1>n,则结点i无右孩子。

遍历二叉树:

有三种遍历方式:1 先根序遍历 2 中根序遍历 3 后根序遍历

1 先根序遍历:先访问根结点,而后以同样方式顺序遍历左子树和右子树

2 中根序遍历:先以同样方式遍历左子树,然后访问根结点,最后再以同样的方式遍历右子树

3 后根序遍历:先以同样方式遍历左右子树,最后访问根结点

比如下面这张图:

先根序遍历的顺序 1->2->4->5->7->3->6

中根序遍历的顺序 4->2->7->5->1->3->6

后根序遍历的顺序 4->7->5->2->6->3->1

下面来看下如何创建二叉树和层次遍历一个二叉树

class Tree():

def __init__(self):

self.root=None

self.result=[]

self.q=[]

def add(self,elem):

node=Node(elem)

if self.root is None:

self.root=node

else:

q=[self.root]

while True:

pop_node=q.pop(0)

if pop_node.lchild is None:

pop_node.lchild=node

return

if pop_node.rchild is None:

pop_node.rchild = node

return

else:

q.append(pop_node.lchild)

q.append(pop_node.rchild)

#基于队列的层次遍历

def level_print(self):

if self.root == None:

return ‘empyt tree‘

self.q.append(self.root)

while True:

if len(self.q) > 0:

current = self.q.pop(0)

self.result.append(current.elem)

if current.lchild != None:

self.q.append(current.lchild)

if current.rchild != None:

self.q.append(current.rchild)

else:

break

print self.result

if __name__=="__main__":

elems=range(10)

tree=Tree()

for elem in elems:

tree.add(elem)

tree.level_print()

打印结果:

/usr/bin/python2.7 /home/zhf/py_prj/data_struct/chapter6.py

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

先根遍历,中根遍历,后根遍历的实现

def pre_order(tree):

if tree == None:

return ‘empyt tree‘

print tree.elem

pre_order(tree.lchild)

pre_order(tree.rchild)

def middle_order(tree):

if tree == None:

return ‘empty tree‘

middle_order(tree.lchild)

print tree.elem

middle_order(tree.rchild)

def post_order(tree):

if tree == None:

return ‘empty tree‘

post_order(tree.lchild)

post_order(tree.rchild)

print tree.elem

运行结果:

/usr/bin/python2.7 /home/zhf/py_prj/data_struct/chapter6.py

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

pre_order

0

1

3

7

8

4

9

2

5

6

middle_order

7

3

8

1

9

4

0

5

2

6

post_order

7

8

3

9

4

1

5

6

2

0

原文地址:https://www.cnblogs.com/zhanghongfeng/p/8531097.html

时间: 2024-10-24 03:35:33

二叉树:树的创建和遍历的相关文章

数据结构学习笔记(五) 树的创建和遍历

创建(先序创建和根据先序和中序进行创建)和遍历(先序遍历.中序遍历.后序遍历.非递归堆栈遍历.层次遍历): package tree; public class XianCreateTree { private static Node header; //非递归遍历的堆栈头指针 private static Node first; //层次遍历的尾和头指针(队尾插入,对头出去) private static Node rear; private static Node front; privat

树的创建与遍历

#include<iostream>#include<list>#include<fstream>#include<queue>using namespace std; template<class T>class Tree //树的建立{ T *NA; list<int> *HL; int root; int sizeN,sizeC; int maxN;public: Tree(int n=100):root(-1),sizeN(0

树的创建和遍历

#include <stdio.h>#include <stdlib.h> struct node{    char data; struct node* left;    struct node* right;}; void preorder(struct node* root)        //前序遍历{    if(root == NULL)        return ;    else {        printf("%c\t", root->

创建先序二叉树-创建层次遍历树

创建先序二叉树 #include<iostream> using namespace std; class BinTreeNode { public:     char ch;     BinTreeNode(int value){ch=value;}     BinTreeNode *left,*right; }; BinTreeNode* create_tree() {     char item;     BinTreeNode *t,*t_l,*t_r;     cin>>

创建二叉树 树的深度搜索 广度搜索

树的深度搜索 与树的前序遍历同理 根节点->左孩子->右孩子  树的广度搜索 与树的层次遍历同理 一层一层遍历内容 深度搜索 采用stack的适配器 先进后出原则  而广度搜索采用的queue适配器 先进先出原则 二者正好满足 搜索需求 简要代码如下: #include <iostream> #include <stack> #include <queue> #include <malloc.h> using namespace std; typ

C++ 创建和遍历二叉树

一个简单的创建和遍历二叉树的C++程序,二叉树的其他操作程序待更新. #include <iostream> using namespace std; struct BiTNode{ char data; struct BiTNode *lchild, *rchild;//左右孩子 }; BiTNode*T; void CreateBiTree(BiTNode* &T); void Inorder(BiTNode* &T); void PreOrderTraverse(BiTN

【数据结构之二叉树】二叉树的创建、遍历等操作

二叉树的基本操作: 1.创建二叉树 2.销毁二叉树 3.遍历二叉树:1)前序遍历 2)中序遍历 3)后序遍历 4)层次遍历 4.搜索二叉树 5.删除子叶 6.插入子叶 7.获取左/右子叶的值 8.获取树深度 9.获取叶子结点数 1.创建二叉树 这里创建的是链式存储结构的二叉树,包含数据域,左右两结点的指针域:在读取创建树时,以#代替空格,输入格式的规范为:以前序遍历的顺序输入,如果该结点的左子叶为空,则输入#,以此类推: e.g: -  +         \ a    *    e    f 

[数据结构]二叉树创建与遍历

实验报告:二叉树创建与遍历 一.问题描述 二叉树是一种实用范围很广的非线性结构,一棵非空二叉树有也只有一个根结点,每个结点最多有两个子树,我们称为左子树与右子树,当一个结点的左.右子树都是空的时,沃恩称此结点为叶子结点. 二叉树有一些很好的性质,这里不再赘述.考虑如何存储一棵树,本实验选择使用链式存储结构——二叉链表:如果事先知道需要存储的二叉树是满二叉树或者完全二叉树,则可以考虑使用顺序存储,否则将浪费大量的存储空间. 对于一棵既成的二叉树,有三种遍历方式——先序.中序与后序.可以证明,一棵形

二叉树 二叉树的性质 存储结构 遍历二叉树 C实现二叉树的创建和遍历 线索二叉树

定义 二叉树(binary tree)是n(n>=0)个结点的有限集合,该集合为空集合称为空二叉树,或者有一个根结点和两棵互不相交的,分别称为树根结点的左孩子树和右孩子树组成. 二叉树的特点 每个结点最多有两棵子树,所以二叉树总没有度大于2的结点 左子树和右子树是有顺序的,次数不能任意颠倒 即使树中某结点只有一棵子树,也要区分是左子树还是右子树 特殊的二叉树 1. 斜树 所有的结点都只有左子树的二叉树称为左斜树; 所有的结点都只有右子树的二叉树称为右斜树; 这两者统称为斜树 2. 满二叉树 在一