您的位置:首页 > 其它

二叉树创建、遍历(递归和非递归)、深度及求取二叉树中和为某一值的所有路径

2014-10-14 20:20 561 查看
1、建立一棵二叉树

思路:从键盘输入数据,将数据插入树,用#代表子树为空。按照深度优先的方法进行插入,示意图如下:



其中3、2、5、4、6是二叉树的结点,红色虚线表示建立二叉树的顺序。

代码:

//二叉树结点
struct BiTNode
{
char data;
struct BiTNode *lChild,*rChild;
};
//创建二叉树
BiTNode* CreateBinaryTree(BiTNode* &T)
{
char ch;
if ((ch=getchar())=='#')
{
T=NULL;
}
else
{
T=(struct BiTNode*)malloc(sizeof(struct BiTNode));
if (NULL==T)
{
std::cout<<"Error! Over flow!"<<std::endl;
return NULL;
}
T->data=ch;
CreateBinaryTree(T->lChild);
CreateBinaryTree(T->rChild);
}
return T;
}


2、二叉树遍历——递归

//先序遍历
void PreOrderTraverse(BiTNode* &T)
{
if (T)
{
std::cout<<T->data<<" ";
PreOrderTraverse(T->lChild);
PreOrderTraverse(T->rChild);
}
else
{
std::cout<<"";
}
}

//中序遍历
void InOrderTraverse(BiTNode* &T)
{
if (T)
{
InOrderTraverse(T->lChild);
std::cout<<T->data<<" ";
InOrderTraverse(T->rChild);
}
else
{
std::cout<<"";
}
}

//后序遍历
void PostOrderTraverse(BiTNode* &T)
{
if (T)
{
PostOrderTraverse(T->lChild);
PostOrderTraverse(T->rChild);
std::cout<<T->data<<" ";
}
else
{
std::cout<<"";
}
}


3、二叉树遍历——非递归

//先序遍历,非递归方法1
void PreOrderNonTvs(BiTNode* &T)
{
std::stack<BiTNode*> ss;
BiTNode* p=T;

while (p!=NULL || !ss.empty())
{
while (p!=NULL)
{
std::cout<<p->data<<" ";
ss.push(p);
p=p->lChild;
}
if (!ss.empty())
{
p=ss.top();
ss.pop();
p=p->rChild;
}

}
}

//先序遍历,非递归方法2
void PreOrderNonRecur(BiTNode* &T)
{
BiTNode* p=T;
std::stack<BiTNode*> ss;
ss.push(p);
while (!ss.empty())
{
BiTNode* q=ss.top();
std::cout<<q->data<<" ";
ss.pop();

if (q->rChild!=NULL)
{
ss.push(q->rChild);
}
if (q->lChild!=NULL)
{
ss.push(q->lChild);
}
}
}

//中序遍历,非递归
void InOrderNonRecur(BiTNode* &T)
{
BiTNode* p=T;
std::stack<BiTNode*> ss;

while (p!=NULL || !ss.empty())
{
while (p!=NULL)
{
ss.push(p);
p=p->lChild;
}
if (!ss.empty())
{
p=ss.top();
std::cout<<p->data<<" ";
ss.pop();
p=p->rChild;
}
}
}

//为后续遍历构造结构体
struct BiTPos
{
BiTNode* tree;
bool isFirst;
};
//后序遍历,非递归方法1
void PosOrderNonTvs(BiTNode* &T)
{
BiTNode* p=T;
std::stack<BiTPos*> ss;
BiTPos* q;

while(p!=NULL || !ss.empty())
{
while (p!=NULL)
{
q=new BiTPos;
q->tree=p;
q->isFirst=true;
ss.push(q);

p=p->lChild;
}
if (!ss.empty())
{
q=ss.top();
ss.pop();
if (q->isFirst==true)
{
q->isFirst=false;
ss.push(q);
p=q->tree->rChild;
}
else
{
std::cout<<q->tree->data<<" ";
p=NULL;
}
}
}
}

//后序遍历,非递归方法2
void PosOrderNonRecur(BiTNode* &T)
{
BiTNode* p=T;
std::stack<BiTNode*> ss;
ss.push(p);
BiTNode* cur;
BiTNode* pre=NULL;

while (!ss.empty())
{
cur=ss.top();

if (((cur->lChild==NULL)&&(cur->rChild==NULL)) || ((pre!=NULL)&&(pre==cur->lChild || pre==cur->rChild)))
{
std::cout<<cur->data<<" ";
ss.pop();
pre=cur;
}
else
{
if (cur->rChild!=NULL)
{
ss.push(cur->rChild);
}
if (cur->lChild!=NULL)
{
ss.push(cur->lChild);
}
}
}
}


4、层次遍历(非递归)

//层次遍历
void LevelOrderTraverse(BiTNode* &T)
{
std::queue<BiTNode*> sq;
BiTNode* p=T;
sq.push(p);

while(sq.size()!=0)
{
p=sq.front();
sq.pop();
std::cout<<p->data<<" ";
if (p->lChild!=NULL)
{
sq.push(p->lChild);
}
if (p->rChild!=NULL)
{
sq.push(p->rChild);
}
}
}


5、二叉树的深度

思路:若一棵二叉树为空,则其深度为0,否则其深度等于左子树和右子树的最大深度加1。上图中的深度为3。

//计算一棵二叉树的深度
int depth(BiTNode* &T)
{
if (!T)
{
return 0;
}
int d1=depth(T->lChild);
int d2=depth(T->rChild);
return ((d1>d2)?d1:d2)+1;
}


6、求二叉树中和为某一值的所有路径

思路:a>“和为某一值“——需要一个值来记录路径中遇到的值,该值可在递归中被修改,所以用static

b>”求取路径“——需要记录符合条件的路径,遍历的过程就是在通过各种路径,问题在于如何求取多条路径。采用栈来进行结点的压入和弹出,以完成路径的回溯。

c>栈用来记录路径信息——涉及到”路径栈“的初始化、压入、输出和弹出等操作,而栈的操作元素为二叉树结点。

d>递归——涉及到递归何时停止,一是路径信息和超出给定范围,二是当前结点为叶子结点

e>叶子结点——需要判断当前结点是否为叶子结点

代码:

//记录当前路径信息值
static int record=0;
//路径结点,存取的是从根结点开始的路径
struct BiTPath
{
BiTNode* tree;
struct BiTPath *next;
};
//初始化结点栈,或者说结点路径信息
void InitPath(BiTPath* &p)
{
p=(BiTPath*)malloc(sizeof(BiTPath));
p->next=NULL;
}

//结点入栈
void Push_backPath(BiTPath* &H,BiTNode* &T)
{
BiTPath* p=H->next;
BiTPath* q=H;

while (NULL!=p)
{
q=p;
p=p->next;
}
p=(BiTPath*)malloc(sizeof(BiTPath));
p->tree=T;
p->next=NULL;

q->next=p;
}

//打印结点,或打印路径信息
void PrintPath(BiTPath* &p)
{
BiTPath* L=p->next;
if (NULL==L)
{
std::cout<<"栈为空!"<<std::endl;
return;
}
while (NULL!=L)
{
std::cout<<L->tree->data<<" ";
L=L->next;
}
std::cout<<std::endl;
}

//结点出栈
void PopPath(BiTPath* &H)
{
BiTPath* p=H->next;
BiTPath* q=H;

if (NULL==p)
{
std::cout<<"栈为空!"<<std::endl;
return;
}
while (NULL!=p->next)
{
q=p;
p=p->next;
}
free(p);
q->next=NULL;

}

//判断结点是否为叶子结点
bool IsLeaf(BiTNode* &T)
{
return (T->lChild==NULL)&&(T->rChild==NULL);
}

//查找符合条件的路径
int Find_Path(BiTNode* &T,int sum,BiTPath* &p)
{
Push_backPath(p,T);
record+=(T->data)-'0';

if ((record==sum)&&(IsLeaf(T)))
{
std::cout<<"one of the path is: ";
PrintPath(p);
}
if (T->lChild!=NULL)
{
Find_Path(T->lChild,sum,p);
}
if (T->rChild!=NULL)
{
Find_Path(T->rChild,sum,p);
}
record-=(T->data)-'0';
PopPath(p);
return 0;
}<pre class="cpp" name="code">
//是否平衡二叉树
bool IsBalance(BiTNode* &T)
{
BiTNode* p=T;
if (p==NULL)
{
return true;
}
else
{
int lHeight=depth(p->lChild);
int rHeight=depth(p->rChild);
int diff=lHeight-rHeight;
if (diff>1 || diff<-1)
{
return false;
}
else
{
return IsBalance(p->lChild) && IsBalance(p->rChild);
}
}

}




7、主函数及测试结果

int main()
{
std::cout<<std::endl;
std::cout<<"Create Binary Tree('#' represent Null)"<<std::endl;
BiTNode* BiT;
CreateBinaryTree(BiT);

std::cout<<std::endl;
std::cout<<"(Recursive method)"<<std::endl;
std::cout<<"pre order traverse Binary Tree: ";
PreOrderTraverse(BiT);
std::cout<<std::endl;
std::cout<<"in order traverse Binary Tree: ";
InOrderTraverse(BiT);
std::cout<<std::endl;
std::cout<<"post order traverse Binary Tree: ";
PostOrderTraverse(BiT);
std::cout<<std::endl;

std::cout<<std::endl;
std::cout<<"(Non-Recursive method)"<<std::endl;
std::cout<<"pre order traverse Binary Tree Non-Rec Method 1: ";
PreOrderNonTvs(BiT);
std::cout<<std::endl;
std::cout<<"pre order traverse Binary Tree Non-Rec Method 2: ";
PreOrderNonRecur(BiT);
std::cout<<std::endl;
std::cout<<"in order traverse Binary Tree Non-Rec Method: ";
InOrderNonRecur(BiT);
std::cout<<std::endl;
std::cout<<"pos order traverse Binary Tree Non-Rec Method1: ";
PosOrderNonTvs(BiT);
std::cout<<std::endl;
std::cout<<"pos order traverse Binary Tree Non-Rec Method2: ";
PosOrderNonRecur(BiT);
std::cout<<std::endl;

std::cout<<std::endl;
std::cout<<"level order traverse Binary Tree Non-Rec Method: ";
LevelOrderTraverse(BiT);
std::cout<<std::endl;

std::cout<<std::endl;
std::cout<<"the height of Binary Tree: "<<depth(BiT)<<std::endl;

std::cout<<std::endl;
if (IsBalance(BiT))
{
std::cout<<"the Binary Tree is balance~ "<<std::endl;
}
else if (!IsBalance(BiT))
{
std::cout<<"the Binary Tree is not balance~ "<<std::endl;
}

//计算二叉树中和为某一值得所有路径
BiTPath* p=new BiTPath;
p->next=NULL;
InitPath(p);
std::cout<<"please enter the sum you want: "<<std::endl;
int sum;
std::cin>>sum;
Find_Path(BiT,sum,p);
return 0;
}






内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: