最近复习二叉树的相关知识,写点心得。呵呵
树的定义是递归的:一个根节点,一个左子树,一个右子树。
树的基本概念: 节点的度:节点拥有的子树数; 层次:根为第一层,依次类推;
树的度: 树内节点度的最大值; 深度:树中节点最大层次;
二叉树的性质: 在二叉树的第i层至多有2的(i-1)次方个节点;
深度为k的二叉树至多有2的(k)次方-1个节点;
n0 = n2+1;
二叉树的遍历分为:先序遍历、中序遍历、后序遍历,后面还有一个层次遍历。我先写了先序和中序的递归及非递归的算法,日后再丰富后序的非递归算法吧。。
/****************************************/
/* 二叉树 */
/* zengxing */
/****************************************/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <stack>
using namespace std;
typedef struct tNode{
char data;
tNode *lchild;
tNode *rchild;
tNode(){
lchild = NULL;
rchild = NULL;
}
}tNode,*pNode;
/************************************/
/* 建树 */
/* 参数:节点指针 */
/* 返回:状态 */
/************************************/
int CreateTree( pNode &p){ //注意使用引用
char ch;
scanf("%c",&ch); //getchar();
if(' ' == ch)
{
p = NULL;
return true;
}
else
{
if(!(p = (pNode)malloc(sizeof(tNode))))
return false;
p->data = ch; //先序建树
CreateTree(p->lchild); //建左子树
CreateTree(p->rchild); //建右子树
}
return true;
}
/*********************************************/
/* 先序遍历 */
/* 参数:根节点指针 */
/* 返回:状态 */
/*********************************************/
void PreTravel(const pNode p)
{
if(!p) return ;
printf("%c",p->data); //访问元素
PreTravel(p->lchild); //遍历左子树
PreTravel(p->rchild); //遍历右子树
}
/*********************************************/
/* 先序遍历2 */
/* 参数:根节点指针 */
/* 返回:状态 */
/*********************************************/
void PreTravel1(const pNode p)
{
stack<pNode> s;
s.push(p);
while(!s.empty())
{
pNode ptemp = NULL;
while(ptemp = s.top()) //一直将左子树入栈
{
printf("%c",ptemp->data); //访问节点
ptemp = ptemp->lchild;
s.push(ptemp);
}
s.pop(); //空栈出栈
//当一个节点的右子树入栈的话,本节点就没有价值,可以出栈了
if(!s.empty()) //右子树入栈
{
ptemp = s.top();
s.pop(); //节点出栈
s.push(ptemp->rchild);
}
}
}
/*********************************************/
/* 中序遍历 */
/* 参数:根节点指针 */
/* 返回:状态 */
/*********************************************/
void InTravel(const pNode p)
{
if(!p) return ;
InTravel(p->lchild); //遍历左子树
printf("%c",p->data); //访问元素
InTravel(p->rchild); //遍历右子树
}
/*********************************************/
/* 中序遍历2 */
/* 参数:根节点指针 */
/* 返回:状态 */
/*********************************************/
void InTravel1(const pNode p)
{
stack<pNode> s;
s.push(p);
while(!s.empty())
{
pNode ptemp = NULL;
while(ptemp = s.top()) //一直将左子树入栈
{
// printf("%c",ptemp->data); //访问节点
ptemp = ptemp->lchild;
s.push(ptemp);
}
s.pop(); //空栈出栈
//当一个节点的右子树入栈的话,本节点就没有价值,可以出栈了
if(!s.empty()) //右子树入栈
{
ptemp = s.top();
printf("%c",ptemp->data); //访问节点
s.pop(); //节点出栈
s.push(ptemp->rchild);
}
}
}
int main() //主函数
{
pNode biTree = NULL;
int status;
status = CreateTree( biTree );
PreTravel( biTree );
cout<<endl;
PreTravel1( biTree );
cout<<endl;
InTravel( biTree );
cout<<endl;
InTravel1( biTree );
system("pause");
return 0;
}
/*测试数据
ABE G CD F END
ABC DE G F END
*/
12-14