二叉树算法
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二叉树算法相关的知识,希望对你有一定的参考价值。
参考技术A 二叉树的算法主要分为三种:先序遍历,中序遍历和后序遍历。二叉树(Binary Tree)是n(n>=0)个节点的有限集合,该集合或者空集(称为空二叉树),或者由一个根节点和两棵互不相交的,分别称为根节点的左子树和右子树的二叉树组成。扩展资料
二叉树的每个结点至多只有二棵子树(不存在度大于2的结点),二叉树的\'子树有左右之分,次序不能颠倒。二叉树的第i层至多有2^(i 1)个结点;深度为k的二叉树至多有2^k 1个结点;对任何一棵二叉树T,如果其终端结点数为n0,度为2的结点数为n2,则n0 = n2 + 1。二叉树算法常被用于实现二叉查找树和二叉堆。
概念
编辑 语音
二叉树是每个节点最多有两个子树的有序树。通常子树被称作“左子树”(left subtree)和“右子树”(right subtree)。二叉树常被用于实现二叉查找树和二叉堆。
基本形态:
二叉树也是递归定义的,其结点有左右子树之分,逻辑上二叉树算法有五种基本形态:
(1)空二叉树——(a)
(2)只有一个根结点的二叉树——(b);
(3)右子树为空的二叉树——(c);
(4)左子树为空的二叉树——(d);
(5)完全二叉树——(e)
注意:尽管二叉树与树有许多相似之处,但二叉树不是树的特殊情形。
二叉树遍历非递归算法——后序遍历
在前面先后介绍了二叉树先序遍历的非递归算法和中序遍历的非递归算法,这里则来介绍二叉树后序遍历非递归算法,二叉树后序非递归遍历真的非常之
重要,因为它具有独特的特性(文章结尾会阐述),所以,在很多与二叉树相关的复杂算法中,经常要用到二叉树后序遍历的非递归算法。并且在互联网面试笔
试也经常考察该算法,所以,我们应该对二叉树后序遍历非递归算法乱熟于心。
和二叉树先序遍历、中序遍历非递归算法一样,后序遍历非递归算法同样是使用栈来实现:从根结点开始,将所有最左结点全部压栈,每当一个结点出栈时,
都先扫描该结点的右子树,只有当一个结点的左孩子和右孩子结点均被访问过了,才能访问结点自身。
二叉树后序遍历非递归算法实现如下:
#include <stdlib.h> #include <stdio.h> #define MAXSIZE 100 // 定义结点类型 typedef struct node { int data; struct node* lchild; struct node* rchild; } BTnode; void Postorder(BTnode* t) { BTnode* Seqstack[MAXSIZE]; int top = -1; int falg = 1; BTnode* p; if(t != NULL) { do { while(t != NULL) // 循环,将所有最左结点压栈 { top ++; Seqstack[top] = t; t = t->lchild; } flag = 1; // 辅助变量flag为1表示当前结点的左孩子为空或者已被访问 p = NULL; // 指针变量p指向当前结点的前驱结点 while(top > -1&& falg == 1) { t = Seqstack[top]; // 注意:这里只是获取栈顶元素,而并没有出栈 if(t->rchild == p) // 如果当前结点右孩子为空,或者已经被访问过,则访问当前结点 { top --; // 当前结点出栈 printf("%d ", p->data); p = t; // 指针变量指向当前结点 } else // 如果当前结点右孩子不为空,则先去处理右孩子 { t = t->rchild; // 处理右孩子 flag = 0; // *t的左孩子未被访问,flag置为0 } } }while(top > -1) } }
上面代码实现了二叉树后序遍历非递归算法(重点看懂注释),接下来就说一说前面提到的该算法的一个特性了:就是当访问某个结点时,栈中所保存的元素
正好是这个结点的所有祖先。那么知道了这个特性,我们就很容易解决下面如下问题:
(1).当给定一个叶子结点,要求输出该叶子结点的所有祖先
(2).输出根结点到所有叶子结点的路径
(3).如果二叉树结点的值是数值,那么求每条路径上值之和,也可以利用二叉树后序遍历的非递归算法这个特性
以上是关于二叉树算法的主要内容,如果未能解决你的问题,请参考以下文章
c++如何用非递归的算法去创建二叉树,有没有分层建立二叉树的方法