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

来源:互联网 发布:手机制作个人简历软件 编辑:程序博客网 时间:2024/06/08 11:49

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、二叉树遍历——非递归

//先序遍历,非递归方法1void 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;}}}//先序遍历,非递归方法2void 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;};//后序遍历,非递归方法1void 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;}        }}}//后序遍历,非递归方法2void 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;}




0 0
原创粉丝点击