对树的一些操作.比如遍历.比如.根据先序和中序创建二叉树

  1 #include "stdafx.h"
  2 #include<string>
  3 #include<iostream>
  4 #include<stack>
  5
  6 using namespace std;
  7
  8 struct BinaryTreeNode
  9 {
 10     int m_nValue;
 11     BinaryTreeNode* m_pLeft;
 12     BinaryTreeNode* m_pRight;
 13 };
 14
 15 void beforeTraverse(BinaryTreeNode *root)
 16 {
 17     if(root!=NULL)
 18     {
 19         cout<<root->m_nValue<<"  ";
 20         beforeTraverse(root->m_pLeft);
 21         beforeTraverse(root->m_pRight);
 22     }
 23 }
 24
 25 void PreOrder(BinaryTreeNode* pRoot)
 26 {//迭代先序遍历
 27     if (pRoot==NULL)
 28         return;
 29     std::stack<BinaryTreeNode*> S;
 30     BinaryTreeNode *p=pRoot;   //二叉树分左右,所以光有栈不行,合理的运用遍历指针是关键之一
 31     while(p!=NULL)
 32     {
 33         cout<<p->m_nValue<<"  ";
 34         if (p->m_pRight!=NULL)
 35             S.push(p->m_pRight);
 36         if (p->m_pLeft!=NULL)
 37             p=p->m_pLeft;
 38         else
 39         {
 40             if (S.empty())
 41                 break;
 42             p=S.top();
 43             S.pop();
 44         }
 45     }
 46 }
 47
 48
 49
 50
 51 void midTraverse(BinaryTreeNode *root)
 52 {
 53     if(root!=NULL)
 54     {
 55         midTraverse(root->m_pLeft);
 56         cout<<root->m_nValue<<"  ";
 57         midTraverse(root->m_pRight);
 58     }
 59 }
 60
 61
 62 void InOrder(BinaryTreeNode* pRoot)
 63 {//迭代中序遍历
 64     if (pRoot==NULL)
 65         return;
 66     std::stack<BinaryTreeNode*> S;
 67     BinaryTreeNode *p=pRoot;
 68     do
 69     {
 70         while(p!=NULL)
 71         {
 72             S.push(p);
 73             p=p->m_pLeft;
 74         }
 75         //若进行到这里左子树为空
 76         if (!S.empty())//Stack不空时退栈,然后访问该元素
 77         {
 78             p=S.top();
 79             cout<<p->m_nValue<<"  ";
 80             S.pop();
 81             p=p->m_pRight;
 82         }
 83     } while (p!=NULL||!S.empty());
 84     //这里的p==NULL表示右子树为空,然后堆栈如果也空的话,才是处理完毕
 85 }
 86
 87 void backTraverse(BinaryTreeNode *root)
 88 {
 89     if(root!=NULL)
 90     {
 91         backTraverse(root->m_pLeft);
 92         backTraverse(root->m_pRight);
 93         cout<<root->m_nValue<<"  ";
 94     }
 95 }
 96
 97 void PostOrder(BinaryTreeNode* pRoot)
 98 {
 99     if (pRoot==NULL)
100         return;
101     std::pair<BinaryTreeNode*,char> w;
102     std::stack<std::pair<BinaryTreeNode*,char> > S;
103     BinaryTreeNode *p=pRoot;
104     do
105     {
106         while(p!=NULL)           //左子树经过节点加L进栈
107         {
108             w.first=p;
109             w.second=‘L‘;
110             S.push(w);
111             p=p->m_pLeft;
112         }
113         bool continuel=true;     //继续循环标志,用于L改为R的时候就开始向右遍历
114         while (continuel && !S.empty()) //用一个break语句也能实现循环标志continuel的功能
115         {
116             w=S.top();
117             S.pop();
118             p=w.first;
119             if (w.second==‘L‘)  //标记为L表示左子树遍历完
120             {
121                 w.second=‘R‘;
122                 S.push(w);
123                 continuel=false;
124                 p=p->m_pRight;
125             }
126             else
127                 cout<<(p->m_nValue)<<"   ";      //如果标记为R,表示右子树遍历完
128         }
129     }while (!S.empty());
130 }
131
132 BinaryTreeNode* createTree(int *leftArr,int leftarrl,int leftarrr,int *midArr,int midarrl,int midarrr)
133 {
134     if(leftarrl<=leftarrr){
135         BinaryTreeNode* root =new BinaryTreeNode;
136         root->m_nValue= leftArr[leftarrl];//取先序遍历的第一个元素作为根节点
137         //取出这个结点以后..要在midArr里面找到这个节点
138         int temIndex = -1;
139
140         for(int i = midarrl;i<=midarrr;++i)
141         {
142             if(midArr[i]==leftArr[leftarrl])
143             {
144                 temIndex =i;
145                 break;
146             }
147         }
148         if(temIndex==-1)
149         {
150             cout<<"数据有误"<<endl;
151             throw std::exception("valid data");
152
153         }
154         int lengthl = temIndex-midarrl;
155         root->m_pLeft = createTree(leftArr,leftarrl+1,leftarrl+lengthl,midArr,midarrl,temIndex-1);
156         root->m_pRight =createTree(leftArr,leftarrl+lengthl+1,leftarrr,midArr,temIndex+1,midarrr);
157         return root;
158 }
159     else
160     {
161         return NULL;
162     }
163 }
164 BinaryTreeNode* cTree(int *leftArr,int *midArr,int len)
165 {
166     return createTree(leftArr,0,len-1,midArr,0,len-1);
167 }
168
169
170
171
172 int _tmain(int argc, _TCHAR* argv[])
173 {
174
175     BinaryTreeNode *roots = new BinaryTreeNode;
176     roots->m_nValue=1;
177     BinaryTreeNode *lchild = new BinaryTreeNode;
178     lchild->m_nValue = 2;
179     lchild->m_pLeft=lchild->m_pRight=NULL;
180     BinaryTreeNode *rchild = new BinaryTreeNode;
181     rchild->m_nValue = 3;
182     rchild->m_pLeft=rchild->m_pRight=NULL;
183     roots->m_pLeft = lchild;
184     roots->m_pRight = rchild;
185
186     beforeTraverse(roots);
187     cout<<endl;
188     midTraverse(roots);
189     cout<<endl;
190     backTraverse(roots);
191     cout<<endl;
192
193     //下面根据先序和中序构建一棵树
194     const int len = 8;
195     int left[]={1,2,4,7,3,5,6,8};
196     int mid[]={4,7,2,1,5,3,8,6};
197     BinaryTreeNode *root;
198     root = cTree(left,mid,len);
199
200     cout<<"先序遍历:";
201     beforeTraverse(root);
202     cout<<endl;
203     cout<<"迭代版先序遍历:";
204     PreOrder(root);
205     cout<<endl;
206     cout<<"中序遍历:";
207     midTraverse(root);
208     cout<<endl;
209     cout<<"迭代中序遍历:";
210     InOrder(root);
211     cout<<endl;
212     cout<<"后序遍历:";
213     backTraverse(root);
214     cout<<endl;
215     cout<<"迭代后序遍历:";
216     PostOrder(root);
217     cout<<endl;
218     return 0;
219 }
时间: 2024-10-28 21:22:58

对树的一些操作.比如遍历.比如.根据先序和中序创建二叉树的相关文章

Java实现二叉搜索树的添加,前序、后序、中序及层序遍历,求树的节点数,求树的最大值、最小值,查找等操作

什么也不说了,直接上代码. 首先是节点类,大家都懂得 /** * 二叉树的节点类 * * @author HeYufan * * @param <T> */ class Node<T extends Comparable<? super T>> { /** * 节点储存的值 */ private T data; /** * 左子节点 */ private Node<T> leftNode; /** * 右子节点 */ private Node<T>

二叉树高度,以及栈实现二叉树的先序,中序,后序遍历的非递归操作

求解二叉树的高度 树是递归定义的,所以用递归算法去求一棵二叉树的高度很方便. #include <iostream> #include <cstdio> using namespace std; struct Node { char data; Node *lchild; Node *rchild; }; void High(Node *T, int &h) { if (T == NULL) h = 0; else { int left_h; High(T->lchi

通过树的先序和中序遍历序列来构造二叉树

题目:给出一棵二叉树的先序和中序遍历的序列,构造出该二叉树. 思路一:采用分治法. 1)取先序遍历序列的第一个值,用该值构造根结点,,然后在中序遍历序列中查找与该元素相等的值,这样就可以把序列分为三部分:左子树(如果有).根结点和右子树(如果有). 2)将两个序列都分成三部分,这样就分别形成了根结点的左子树和右子树的先序遍历和后序遍历的序列. 3)重复1)和2)步骤,直至所有结点都处理完就可以完整构成一颗二叉树了. 根据分治法构造二叉树的代码实现: TreeNode *buildTree(vec

树——二叉树的先序、中序和后序遍历

1,二叉树是否只有一种遍历方式(层次遍历)? 2,典型的二叉树的遍历方式: 1,先序遍历(Pre-Order Traversal): 2,中序遍历(In-Order Traversal): 3,后序遍历(Post-Order Traversal): 3,先序遍历(“先序”指最先访问根结点中的数据元素): 1,二叉树为空: 1,无操作,直接返回: 2,二叉树不为空: 1,访问根结点中的数据元素: 2,先序遍历左子树: 3,先序遍历右子树: 4,先序遍历功能定义及其代码实现: 1,代码示例: 1 p

二叉树先序、中序、后序遍历的递归算法和非递归算法

先序遍历:若二叉树为空,则空操作:否则访问根节点:先序遍历左子树:先序遍历右子树. 中序遍历:若二叉树为空,则空操作:否则中序遍历左子树:访问根节点:中序遍历右子树. 后序遍历:若二叉树为空,则空操作:否则后序遍历左子树:后序遍历右子树:访问根节点. 二叉链表:链表中的结点包含三个域:数据域和左右指针域. 三叉链表:在二叉链表的基础上增加指向双亲结点的指针域. 以下代码均使用二叉链表. //二叉树的二叉链表存储表示 typedef char TElemType; typedef struct B

C语言非递归实现二叉树的先序、中序、后序、层序遍历

C语言非递归实现二叉树的先序.中序.后序.层序遍历代码如下: 1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <stack> 4 #include <queue> 5 using namespace std; 6 7 //*****二叉树的二叉链表存储表示*****// 8 typedef struct BiNode 9 { 10 char data; 11 struct BiNode *lchil

二叉树的先序、中序、后序遍历

二叉树的遍历方法有多种,首先我想先改变这几个遍历的名字(前根序遍历,中根序遍历,后根序遍历):前中后本来就是相对于根结点来说的,少一个字会产生很多不必要的误解. 先简单描述一下这三种遍历方法的区别: 先序遍历:先遍历根结点,然后遍历左子树,最后遍历右子树.上图中的先序遍历结果是ABDHECFG 中序遍历:先遍历左子树,然后遍历根结点,最后遍历右子树.上图中的中序遍历结果是HDBEAFCG 后序遍历:先遍历左子树,然后遍历右子树,最后遍历根节点.上图中的后序遍历结果是HDEBFGCA 先序遍历:

PTA 根据后序和中序遍历输出先序遍历(25 分)

7-1 根据后序和中序遍历输出先序遍历(25 分) 本题要求根据给定的一棵二叉树的后序遍历和中序遍历结果,输出该树的先序遍历结果. 输入格式: 第一行给出正整数N(≤30),是树中结点的个数.随后两行,每行给出N个整数,分别对应后序遍历和中序遍历结果,数字间以空格分隔.题目保证输入正确对应一棵二叉树. 输出格式: 在一行中输出Preorder:以及该树的先序遍历结果.数字间有1个空格,行末不得有多余空格. 输入样例: 7 2 3 1 5 7 6 4 1 2 3 4 5 6 7 输出样例: Pre

二叉树遍历(先序、中序、后序)

二叉树的遍历(递归与非递归) 遍历:traversal 递归:recursion 栈----------回溯----------递归 栈和回溯有关 本文讨论二叉树的常见遍历方式的代码(Java)实现,包括 前序(preorder).中序(inorder).后序(postorder).层序(level order), 进一步考虑递归和非递归的实现方式. 递归的实现方法相对简单,但由于递归的执行方式每次都会产生一个新的方法调用栈,如果递归层级较深,会造成较大的内存开销, 相比之下,非递归的方式则可以