二叉树创建、遍历(递归和非递归)、深度及求取二叉树中和为某一值的所有路径
2014-10-14 20:20
561 查看
1、建立一棵二叉树
思路:从键盘输入数据,将数据插入树,用#代表子树为空。按照深度优先的方法进行插入,示意图如下:
其中3、2、5、4、6是二叉树的结点,红色虚线表示建立二叉树的顺序。
代码:
2、二叉树遍历——递归
3、二叉树遍历——非递归
4、层次遍历(非递归)
5、二叉树的深度
思路:若一棵二叉树为空,则其深度为0,否则其深度等于左子树和右子树的最大深度加1。上图中的深度为3。
6、求二叉树中和为某一值的所有路径
思路:a>“和为某一值“——需要一个值来记录路径中遇到的值,该值可在递归中被修改,所以用static
b>”求取路径“——需要记录符合条件的路径,遍历的过程就是在通过各种路径,问题在于如何求取多条路径。采用栈来进行结点的压入和弹出,以完成路径的回溯。
c>栈用来记录路径信息——涉及到”路径栈“的初始化、压入、输出和弹出等操作,而栈的操作元素为二叉树结点。
d>递归——涉及到递归何时停止,一是路径信息和超出给定范围,二是当前结点为叶子结点
e>叶子结点——需要判断当前结点是否为叶子结点
代码:
7、主函数及测试结果
思路:从键盘输入数据,将数据插入树,用#代表子树为空。按照深度优先的方法进行插入,示意图如下:
其中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; }
相关文章推荐
- 二叉树的基本操作(创建、递归和非递归遍历、求深度、求叶子数)
- 程序员面试100题(算法)之二叉树中找出和为某一值的所有路径(含二叉树前序创建、遍历)
- 二叉树创建及遍历算法(递归及非递归)(转)
- 递归遍历某一路径下的所有文件
- 二叉树创建及遍历算法(递归及非递归)
- 二叉树创建及遍历算法(递归及非递归)
- 二叉树创建及遍历算法(递归及非递归)
- 二叉树创建及遍历算法(递归及非递归)
- 二叉树创建及遍历算法(递归及非递归)
- 用非递归实现二叉树的前序、中序、后序、层次遍历,用递归实现查找、统计个数、比较、求深度
- 二叉树创建及遍历算法(递归及非递归)
- [转]递归遍历某一路径下的所有文件(for windows or linux)
- 二叉树创建及遍历算法(递归及非递归)
- 二叉树创建及遍历算法(递归及非递归)
- 二叉树创建及遍历算法(递归及非递归)
- 二叉树创建及遍历算法(递归及非递归)
- 二叉树创建及遍历算法(递归及非递归)
- 二叉树创建及遍历算法(递归及非递归)
- 二叉树创建及遍历算法(递归及非递归)
- 二元树中和为某一值的所有路径(递归与非递归的方法)