c++二叉树

 二叉树的定义:二叉树(binary tree)是指树中节点的度不大于2的有序树,它是一种最简单且最重要的树。二叉树的递归定义为:二叉树是一棵空树,或者是一棵由一个根节点和两棵互不相交的,分别称作根的左子树和右子树组成的非空树;左子树和右子树又同样都是二叉树

【节选自百度】

节点

左子树

右子树

0

子树 1

子树 7

1

子树 2

子树 6

2

链表也可以看作是一棵特殊的二叉树,因为链表每个结点只有一个子节点,满足二叉树的定义。二叉树与普通树的差别在于,普通树可以有 2 个以上的子节点,而二叉树的子节点不能超过 2 个。

链表

二叉树

后继节点

1个

不超过 2个

任意个

定义关系

链表属于二叉树

二叉树属于树

二叉树相关术语:

  1. 节点:包含一个数据元素及若干指向子树分支的信息 。
  2. 节点的度:一个节点拥有子树的数目称为节点的度 。
  3. 叶子节点:也称为终端节点,没有子树的节点或者度为零的节点。
  4. 分支节点:也称为非终端节点,度不为零的节点称为非终端节点 。
  5. 树的度:树中所有节点的度的最大值。
  6. 节点的层次:从根节点开始,假设根节点为第1层,根节点的子节点为第2层,依此类推,如果某一个节点位于第L层,则其子节点位于第L+1层 。
  7. 树的深度:也称为树的高度,树中所有节点的层次最大值称为树的深度 。
  8. 有序树:如果树中各棵子树的次序是有先后次序,则称该树为有序树。
  9. 无序树:如果树中各棵子树的次序没有先后次序,则称该树为无序树。
  10. 森林:由m(m≥0)棵互不相交的树构成一片森林。如果把一棵非空的树的根节点删除,则该树就变成了一片森林,森林中的树由原来根节点的各棵子树构成。

二叉树的节点数量

一棵高度为n的二叉树,最多包括2n−1个节点。树高为n,共有n 层,第一层有1 个根节点,根据二叉树的定义,后面每层节点的数量最多为上一层的2 倍,因此最多有:1+2+4+....+2n−1=2n−1个节点。

那么一棵高度为 nn 的二叉树,最少有 nn 个节点,是一个链表。

二叉树的存储

可以继续沿用存储树的方法,来存储二叉树。

struct node{
    int value;
    vector<int> childs; //用来记录所有子节点的编号
}nodes[10000];
int root;
//root为根节点

也可以利用二叉树的特性,用左右子树的方式,来存储二叉树。

用结构体来表示二叉树的节点, 每个节点存储了当前节点的值, 以及左子树和右子树的编号。

struct node{
    int value;
    int left;
    int right;
}nodes[10000];
int root;					//root为根节点

二叉树的遍历

遍历二叉树的方法可以沿用遍历树的方法——递归。

DFS(当前节点u){

    DFS(u.left);

    DFS(u.right);

}

在此基础上,二叉树的遍历又分为以下三种:

先序遍历

遍历顺序规则为:根左右,遍历方法:

(1)访问根节点

(2)采用先序递归遍历左子树

(3)采用先序递归遍历右子树

中序遍历

遍历顺序规则为:左根右,遍历方法:

(1)采用中序遍历左子树

(2)访问根节点

(3)采用中序遍历右子树

二叉树遍历的总结

三种方法遍历过程中经过节点的路线一样,只是访问各个节点的顺序不同。

二叉树的先序、中序、后序遍历我们已经学会了, 那么给定其中任意两种遍历, 我们能否推出唯一的第三种遍历么?

答案:给定先序+中序可以推出后序。后序+中序可以推出先序。但是先序+后序是无法推出中序的。

这里我们只是以:知道先序遍历和中序遍历,推断后序遍历作为例子,其他组合方式原理是一样的。

二叉树有以下几种特性:

特性 A ,对于先序遍历,第一个肯定是根节点

特性 B ,对于后序遍历,最后一个肯定是根节点

特性 C ,利用先序或后序遍历,确定根节点,在中序遍历中,根节点的两边就可以分出左子树和右子树;

特性 D ,对左子树和右子树分别做前面 3 点的分析和拆分,相当于做递归,我们就可以重建出完整的二叉树。

所以我们可以靠保存先序+中序,或者后序+中序 2 个顺序,来保存整个二叉树的结构。

特殊的二叉树

二叉搜索树

        二叉搜索树( Binary Search Tree )它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有节点的值均小于它的根节点的值; 若它的右子树不空,则右子树上所有节点的值均大于它的根节点的值; 它的左、右子树也分别为二叉搜索树。

        能够快速查找数据也是二叉搜索树被用于各类数据结构的原因,但这种快速是有限制的,即不会出现退化,假如二叉搜索树退化为链表,则无法做到快速查找数据的要求,所以又出现了平衡二叉树

平衡二叉树

平衡二叉树( Balanced Binary Tree )具有以下性质:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。

平衡二叉树有效的限制了树高,使得二叉树不会退化为一个链表。

平衡二叉树如果同时也是一棵二叉搜索树,那么查找某个节点的效率是O(log(n))的。

很多数据结构,不能完美的做到平衡,但也能有效的控制树高,例如:红黑树。也被经常用于数据的快速查找。

满二叉数有2k-1个结点

样例代码

struct node{
	char value;
		int left,right;
	}data[101];
	int root=0,cnt;
	char ch;
	int buildTree(int bt){
		cin>>ch;
		if(ch=='.'){
			bt==0;
			return bt;
		}else{
			bt=++cnt;
			data[bt].value=ch;
			data[bt].left=data[bt].right=0;
			data[bt].left=buildTree(bt);
			data[bt].right=buildTree(bt);
		}
		return bt;
	} 
	void postorder(int bt){
		if(bt){
			postorder(data[bt].left);
			postorder(data[bt].right);	
			cout<<data[bt].value;
		}
	}
	int main(){
		root=0;
		cnt=0;
		root=buildTree(0);
		postorder(root);
return 0;
}

  • 35
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值