二叉树的遍历(层遍历和深度遍历)

定义:
1、满二叉树:一棵深度为k且有2的k次方减1个结点的二叉树称为满二叉树
2、完全二叉树:如果有深度为k的,有n个结点的二叉树,当且仅当其每一个结点都与深度为k的满二叉树中编号从1至n的结点一一对应时,称之为完全二叉树。
性质:
1、二叉树的第i层上至多有2的i-1次方个结点(i>=1)。
2、深度为k的二叉树至多有2的k次方减1个结点(k>=1)。
3、对任何一棵二叉树T,如果其终端结点数为n0,度为2的结点数为n2,则n0=n2+1。
4、具有n个结点的完全二叉树的深度为以2为底n的对数取下限加1。
5、如果对一棵有n个结点的完全二叉树的结点按层序编号,则对任一结点i(1=<i=<n)有:
(1)如果i=1,则结点i是二叉树的根,无双亲;如果i>1,则双亲PARENT(i)是结点[i/2]
(2)如果2i>n,则结点i无左孩子(结点i为叶子结点);否则其左孩子LCHILD(i)是结点2i
(3)如果2i+1>n,则结点i无右孩子;否则其右孩子RCHILD(i)是结点2i+1.
存储结构:顺序存储结构(数组方式),链式存储结构(二叉链表)
<wbr></wbr>
二叉树链表存储方式:
struct BiNode
{
<wbr><wbr> Type<wbr> data;</wbr></wbr></wbr>
<wbr><wbr> struct BiNode *lchild,*rchild;//左右孩子指针<br> }BiNode,*BiTree</wbr></wbr>
<wbr></wbr>
设计一个算法层序遍历二叉树(同一层从左到右访问)。
思想:用一个队列保存被访问的当前节点的左右孩子以实现层序遍历。
void<wbr>HierarchyBiTree(BiTree Root)</wbr>
{
<wbr><wbr><wbr><wbr> LinkQueue *Q;<wbr>// 保存当前节点的左右孩子的队列<br><wbr><wbr><wbr><wbr><br><wbr><wbr><wbr><wbr> InitQueue(Q);<wbr>// 初始化队列<br><br><wbr><wbr><wbr><wbr> if (Root == NULL) return ; //树为空则返回<br><wbr><wbr><wbr><wbr> BiNode *p = Root;<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>// 临时保存树根Root到指针p中<br><wbr><wbr><wbr><wbr> Visit(p-&gt;data);<wbr><wbr><wbr><wbr><wbr>// 访问根节点<br><wbr><wbr><wbr><wbr> if (p-&gt;lchild)</wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
<wbr><wbr><wbr><wbr><wbr><wbr><wbr> EnQueue(Q, p-&gt;lchild);<wbr><wbr>// 若存在左孩子,左孩子进队列<br><wbr><wbr><wbr><wbr> if (p-&gt;rchild)</wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>EnQueue(Q, p-&gt;rchild); // 若存在右孩子,右孩子进队列<br><br><wbr><wbr><wbr><wbr> while (!QueueEmpty(Q)) // 若队列不空,则层序遍历</wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
<wbr><wbr><wbr><wbr><wbr><wbr>{<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr> DeQueue(Q, p);<wbr>// 出队列<br><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr> Visit(p-&gt;data);// 访问当前节点<br><br><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr> if (p-&gt;lchild)</wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr> EnQueue(Q, p-&gt;lchild);<wbr>// 若存在左孩子,左孩子进队列<br><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr> if (p-&gt;rchild)</wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr> EnQueue(Q, p-&gt;rchild); // 若存在右孩子,右孩子进队列<br><wbr><wbr><wbr><wbr> }<br><br><wbr><wbr><wbr><wbr> DestroyQueue(Q);<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>// 释放队列空间<br><wbr><wbr><wbr><wbr> return ;<br> }<br><br> 算法分析:假设T有n个节点。因为本算法中基本操作是Visit(p-&gt;data),则时间复杂度为O(n);由于用一个队列保存当前孩子的节点,所以队列占用的额外空间为该二叉树的叶子节点数,最好情况是一棵只有左分支或只有右分支的单边树,此时占用空间最少,仅为1。最坏情况是该树是满二叉树,此时占用的空间最多为(n+1)/2。</wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>

深度遍历是软件开发中经常遇到的遍历方法。常用的遍历方法主要有下面三种:(1)前序遍历;(2)中序遍历;(3)后序遍历。按照递归的方法,这三种遍历的方法其实都不困难,前序遍历就是根-左-右,中序遍历就是左-根-右,后续遍历就是左-右-根。代码实现起来也不复杂。

1)前序遍历

void preorder_traverse(TREE_NODE* pTreeNode)
{
	if(pTreeNode){
		printf("%d", pTreeNode->data);
		preorder_traverse(pTreeNode->left);
		preorder_traverse(pTreeNode->right);
	}
}

2)中序遍历
void inorder_traverse(TREE_NODE* pTreeNode)
{
	if(pTreeNode){
		inorder_traverse(pTreeNode->left);
		printf("%d", pTreeNode->data);
		inorder_traverse(pTreeNode->right);
	}
}

3)后序遍历
  1. voidafterorder_traverse(TREE_NODE*pTreeNode)
  2. {
  3. if(pTreeNode){
  4. afterorder_traverse(pTreeNode->left);
  5. afterorder_traverse(pTreeNode->right);
  6. printf("%d",pTreeNode->data);
  7. }
  8. }

----------------------------------------------------------------------------------------------------------------------

//计算结点的总个数
int nodeTotal(binTree *rootNode)
{
if(rootNode==NULL)return 0;
else
{
return 1+nodeTotal(rootNode->lNode)+nodeTotal(rootNode->rNode);
}
}
//计算二叉树的深度
int treeDepth(binTree *rootNode)
{
if(rootNode==NULL)return -1;
else
{
int lH=treeDepth(rootNode->lNode);
int rH=treeDepth(rootNode->rNode);
if(lH>rH)return lH+1;
return rH+1;
}
}
//计算叶子结点的个数
int leafTotal(binTree *rootNode)
{
if(rootNode==NULL)return 0;
else
{
if(rootNode->lNode==NULL && rootNode->rNode==NULL)return 1;
else
{
int lH=leafTotal(rootNode->lNode);
int rH=leafTotal(rootNode->rNode);
return rH+lH;
}
}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值