`
hm4123660
  • 浏览: 278177 次
  • 性别: Icon_minigender_1
  • 来自: 广州
博客专栏
Dea4ce76-f328-3ab2-b24a-fb268e1eeb75
数据结构
浏览量:69027
社区版块
存档分类
最新评论

二叉树详解

阅读更多

        树是一种比较重要的数据结构,尤其是二叉树。二叉树是一种特殊的树,在二叉树中每个节点最多有两个子节点,一般称为左子节点和右子节点(或左孩子和右孩子),并且二叉树的子树有左右之分,其次序不能任意颠倒。本篇博客将详细为大家解析二叉树。

 

首先介绍两个概念:

满二叉树:在一棵二叉树中,如果所有分支结点都有左孩子和右孩子结点,并且叶子结点都集中在二叉树的最下层,这样的树叫做满二叉树

 

如:



 

完全二叉树:若二叉树中最多只有最下面两层的结点的度数可以小于2,并且最下面一层的叶子结点都是依次排列在该层最左边的位置上,则称为完全二叉树

 

如:



 区别:满二叉树是完全二叉树的特例,因为满二叉树已经满了,而完全并不代表满。所以形态你也应该想象出来了吧,满指的是出了叶子节点外每个节点都有两个孩子,而完全的含义则是最后一层没有满,并没有满。

 

      

二叉树的链式存储结构是一类重要的数据结构,定义结果为:

//定义树的结构
struct node
{
	node * lchild;
	node * rchild;
	string data;
	//初始化
	node()
	{
		lchild=rchild=NULL;
	}
};

 

二叉树的建立

 

首先我们用户输入生成一棵二叉树,要生的的二叉树如下图所示:

#代表空结点。

 下面我们根据上面图中所示的二叉树,利用先序依次输入ABDG###E#H##C#F##(即先序遍历)

生成二叉树的代码如下:

//二叉树生成--先序遍历输入要生成的二叉树数据,#代表空结点
void CreateTree(node * & root)
{
	 char data;
	 cin>>data;
	 if(data!='#')
	 {
		 root=new node;
		 root->data=data;
		 
		 CreateTree(root->lchild);
		
		 CreateTree(root->rchild);
		
	 }
}

 

二叉树节点查找

采用递归的方法在二叉树root里查找只为aim的结点,若找到此节点则返回其指针,否则返回NULL

查找代码如下:

//检查二叉树是否包含数据aim,有则返回其指针
node * Findnode(node * & root,string aim)
{
	node * p;
	if(root==NULL)//空树
		return NULL;
	else if(root->data==aim)
		return root;
	else
	{	
		p=Findnode(root->lchild,aim);
		if(p!=NULL)
			return p;
		else
			return Findnode(root->rchild,aim);	
	}
}

 这里解释一下递归中的return的意思:

return 对当前函数来说是结束了,对调用它的父函数来说你这个函数执行完成了,父函数就会接着执行下一语句。
没想到父函数马上又遇到一个return,父函数结束了,对爷爷函数来说父函数执行完成了,爷爷函数就接着执行下一个语句

 

二叉树遍历

1.先序遍历

先序遍历过程是:

1)访问根结点

2)先序遍历左子树

3)先序遍历右子树

先序遍历代码为:

 

void  PreOrder(node * root)//先序遍历
{
	if(root!=NULL)
	{
		cout<<root->data;
		PreOrder(root->lchild);
		PreOrder(root->rchild);
	}
}

 

2.中序遍历

中序遍历过程是:1)序遍历左子树

2)访问根结点

3)序遍历右子树

 

中序遍历的代码:

 

void  InOrder(node * root)//中序遍历
{
	if(root!=NULL)
	{
		
		InOrder(root->lchild);
		cout<<root->data;
		InOrder(root->rchild);
	}
}

 

3.后续遍历后序遍历过程是:

1)后序遍历左子树

2)后序遍历右子树3)访问根结点

 

后序遍历代码为:

 

void  PostOrder(node * root)//后序遍历
{
	if(root!=NULL)
	{
		
		PostOrder(root->lchild);
		PostOrder(root->rchild);
		cout<<root->data;
	}
}

 

二叉树高度计算

递归解法:
(1)如果二叉树为空,二叉树的深度为0
(2)如果二叉树不为空,二叉树的深度 = max(左子树深度, 右子树深度) + 1

代码如下:

int NodeHeight(node * root)//计算二叉树高度
{
	int lchild,rchlid;
	if(root==NULL)
		return 0;
	else
	{
		lchild=NodeHeight(root->lchild);
		rchlid=NodeHeight(root->rchild);
		return (lchild>rchlid)?(lchild+1):(rchlid+1);
	}
}

 

 

输出二叉树叶子节点

递归解法:
参考代码如下:

void Showleaf(node * root)
{
	if(root!=NULL)
	{
		if(root->lchild==NULL&&root->rchild==NULL)
			cout<<root->data;
		Showleaf(root->lchild);//输出左子树叶子节点
		Showleaf(root->rchild);//输出右子树叶子节点
	}
}

 

运行结果为:



 

附上源代码地址:https://github.com/longpo/algorithm/tree/master/Btree

 

递归分析

上面源代码中,大量运用了递归算法,

下面我们来分析其中一个递归的过程。

二叉树结构为:



 利用先序遍历,即代码为:

void  PreOrder(node * root)//先序遍历
{
	if(root!=NULL)
	{
		cout<<root->data;
		PreOrder(root->lchild);
		PreOrder(root->rchild);
	}
}

 

画出其运行状态图:



 

  • 大小: 5.8 KB
  • 大小: 3.6 KB
  • 大小: 6.4 KB
  • 大小: 22.9 KB
  • 大小: 23.9 KB
  • 大小: 53.5 KB
  • 大小: 40.3 KB
4
0
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics