设为首页 加入收藏

TOP

二叉树(Binary Tree)相关算法的实现(二)
2015-07-20 18:03:12 来源: 作者: 【 】 浏览:9
Tags:Binary Tree 相关 算法 实现
足一定条件的结点,删除指定结点,在指定位置添加结点(子树)...都是在遍历的基础上做一些额外的操作
?
四.计算树的深度
?
计算树深有多种方式,例如:
?
1.分别计算根下左右子树的高度,二者中的较大的为树深
?
2.最大递归深度为树深
?
...
?
我们采用第一种方式,更清晰一些
?
int btDepth(struct bt* root)
{
? ? int rd,ld;
? ? if(root==NULL)return 0;//空树深度为0
? ? else
? ? {
? ? ? ? ld=1+btDepth(root->left);//递归进层,深度加1
? ? ? ? rd=1+btDepth(root->right);//递归进层,深度加1
? ? ? ? return ld > rd ? ld : rd;//返回最大值
? ? }
}
五.树形输出
?
所谓树形输出,即对自然表示的二叉树逆时针旋转90度,其实仍然是在遍历的过程中记录递归层数,以此确定输出结果
?
?
//depth表示递归深度,初始值为0
void btOutput(struct bt* root,int depth)
{
? ? int k;
? ? if(root==NULL)return;
? ? else
? ? {
? ? ? ? btOutput(root->right,depth+1);//遍历右子树
? ? ? ? for(k=0;k
? ? ? ? ? ? printf(" ");//递归层数为几,就输出几个空格(缩进几位)
? ? ? ? putchar(root->data);printf("\n");
? ? ? ? btOutput(root->left,depth+1);//遍历左子树
? ? }
}
//“右-中-左”的遍历顺序被称为“逆中序”遍历,采用这种顺序是为了符合输出规则(逆时针90度)
六.按层缩进输出
?
按层缩进输出就像代码编辑器中的自动缩进,从根结点开始逐层缩进,只需要对上面的代码稍作改动就可以实现
?
?
//k仍然表示递归深度,初始值为0
void indOutput(struct bt* root,int k)
{
? ? int i;
? ? if(root!=NULL)
? ? {
? ? ? ? for(i=1;i<=k;i++)
? ? ? ? ? ? putchar(' ');
? ? ? ? putchar(root->data);putchar('\n');
? ? ? ? indOutput(root->left,k+1);
? ? ? ? indOutput(root->right,k+1);
? ? }
? ? else return;
}
//按层缩进输出与树形输出的唯一区别就是遍历方式不同,前者是先序遍历,后者是逆中序遍历
七.按层顺序输出
?
按层顺序输出与前面提及的两种输出方式看似相似,实则有着很大不同,至少,我们无法简单地套用任何一种遍历过程来完成这个目标
?
所以,只能维护一个队列来控制遍历顺序
?
?
void layerPrint(struct bt* root)
{
? ? struct bt* queue[100];//声明结点队列
? ? struct bt* p;//当前结点
? ? int amount=0,head,tail,j,k;//队列相关属性(元素总数,对头、队尾索引)
? ? queue[0]=root;
? ? head=0;
? ? tail=1;
? ? amount++;
? ? while(1)
? ? {
? ? ? ? j=0;
? ? ? ? for(k=0;k
? ? ? ? {
? ? ? ? ? ? p=queue[head++];//取对头元素
? ? ? ? ? ? if(p->left!=NULL)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? queue[tail++]=p->left;//如果有则记录左孩子
? ? ? ? ? ? ? ? j++;
? ? ? ? ? ? }
? ? ? ? ? ? if(p->right!=NULL)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? queue[tail++]=p->right;//如果有则记录右孩子
? ? ? ? ? ? ? ? j++;
? ? ? ? ? ? }
? ? ? ? ? ? putchar(p->data);//输出当前结点值
? ? ? ? }
? ? ? ? amount=j;//更新计数器
? ? ? ? if(amount==0)break;
? ? }
}
八.计算从根到指定结点的路径
?
要记录路径,当然不宜用递归的方式,这里采用后序遍历的非递归实现
?
为什么选择后序遍历?
?
因为在这种遍历方式中,某一时刻栈中现有的结点恰恰就是从根结点到当前结点的路径(从栈底到栈顶)。严格地说,此时应该用队列来保存路径,因为栈不支持从栈底到栈顶的出栈操作(这样的小细节就把它忽略好了...)
?
?
//参数c为指定结点值
void printPath(struct bt* root,char c)
{
? ? struct st* stack[100];//声明结点栈
? ? int top=-1;//栈顶索引
? ? int i;
? ? struct bt* p=root;//当前结点
? ? struct bt* q=NULL;//上一次处理的结点
? ? while(p!=NULL||top!=-1)
? ? {
? ? ? ? for(;p!=NULL;p=p->left)stack[++top]=p;//遍历左子树
? ? ? ? if(top!=-1)
? ? ? ? {
? ? ? ? ? ? p=stack[top];//获取栈顶元素
? ? ? ? ? ? if(p->right==NULL||p->right==q)//如果当前结点没有右孩子或者右孩子刚被访问过
? ? ? ? ? ? {
? ? ? ? ? ? ? ? if(p->data==c)//如果找到则输出路径
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? for(i=0;i<=top;i++)
? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? p=stack[i];
? ? ? ? ? ? ? ? ? ? ? ? putchar(p->data);
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? printf("\n");
? ? ? ? ? ? ? ? ? ? //此处不跳出循环,因为可能存在不唯一的结点值,遍历整个树,找出所有路径
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? q=p;
? ? ? ? ? ? ? ? p=stack[top];
? ? ? ? ? ? ? ? top--;
? ? ? ? ? ? ? ? p=NULL;
? ? ? ? ? ? }
? ? ? ? ? ? else p=p->right;//遍历右子树
? ? ? ? }
? ? }
}
九.完整 源码与截图示例
?
源码:#include
?
struct bt
{
? ? char data;
? ? struct bt *left;
? ? struct bt *right;
};
?
首页 上一页 1 2 3 4 下一页 尾页 2/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇c++单列模式与线程安全 下一篇HDU3572_Task Schedule(网络流最..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: