wenbao与二叉树遍历

 

 

 

大牛博客

http://blog.csdn.net/sjf0115/article/details/8645991

 

 

以下全部转自大神博客。。。膜拜!!!!!!!!!!!

 

树形结构是一类重要的非线性数据结构,其中以树和二叉树最为常用。

二叉树是每个结点最多有两个子树的有序树。通常子树的根被称作“左子树”(left subtree)和“右子树”(right subtree)。二叉树常被用作二叉查找树和二叉堆或是二叉排序树。二叉树的每个结点至多只有二棵子树(不存在度大于2的结点),二叉树的子树有左右之分,次序不能颠倒。二叉树的第i层至多有2的 i -1次方个结点;深度为k的二叉树至多有2^(k) -1个结点;对任何一棵二叉树T,如果其终端结点数(即叶子结点数)为n0,度为2的结点数为n2,则n0 = n2 + 1。

二叉树的链式存储结构是一类重要的数据结构,其形式定义如下:

1 //二叉树结点
2 typedef struct BiTNode{
3     //数据
4     char data;
5     //左右孩子指针
6     struct BiTNode *lchild,*rchild;
7 }BiTNode,*BiTree;

 

二叉树的创建:

通过读入一个字符串,建立二叉树的算法如下:

 1 //按先序序列创建二叉树
 2 int CreateBiTree(BiTree &T){
 3     char data;
 4     //按先序次序输入二叉树中结点的值(一个字符),‘#’表示空树
 5     scanf("%c",&data);
 6     if(data == '#'){
 7         T = NULL;
 8     }
 9     else{
10         T = (BiTree)malloc(sizeof(BiTNode));
11         //生成根结点
12         T->data = data;
13         //构造左子树
14         CreateBiTree(T->lchild);
15         //构造右子树
16         CreateBiTree(T->rchild);
17     }
18     return 0;
19 }

 

二叉树的遍历:

 

遍历是对树的一种最基本的运算,所谓遍历二叉树,就是按一定的规则和顺序走遍二叉树的所有结点,使每一个结点都被访问一次,而且只被访问一次。由于二叉树是非线性结构,因此,树的遍历实质上是将二叉树的各个结点转换成为一个线性序列来表示。

递归算法:

 1 //输出
 2 void Visit(BiTree T){
 3     if(T->data != '#'){
 4         printf("%c ",T->data);
 5     }
 6 }
 7 //先序遍历
 8 void PreOrder(BiTree T){
 9     if(T != NULL){
10         //访问根节点
11         Visit(T);
12         //访问左子结点
13         PreOrder(T->lchild);
14         //访问右子结点
15         PreOrder(T->rchild);
16     }
17 }
18 //中序遍历
19 void InOrder(BiTree T){
20     if(T != NULL){
21         //访问左子结点
22         InOrder(T->lchild);
23         //访问根节点
24         Visit(T);
25         //访问右子结点
26         InOrder(T->rchild);
27     }
28 }
29 //后序遍历
30 void PostOrder(BiTree T){
31     if(T != NULL){
32         //访问左子结点
33         PostOrder(T->lchild);
34         //访问右子结点
35         PostOrder(T->rchild);
36         //访问根节点
37         Visit(T);
38     }
39 }

 

非递归算法:

<1>先序遍历:

【思路】:访问T->data后,将T入栈,遍历左子树;遍历完左子树返回时,栈顶元素应为T,出栈,再先序遍历T的右子树。

 1 /* 先序遍历(非递归)
 2    思路:访问T->data后,将T入栈,遍历左子树;遍历完左子树返回时,栈顶元素应为T,出栈,再先序遍历T的右子树。
 3 */
 4 void PreOrder2(BiTree T){
 5     stack<BiTree> stack;
 6     //p是遍历指针
 7     BiTree p = T;
 8     //栈不空或者p不空时循环
 9     while(p || !stack.empty()){
10         if(p != NULL){
11             //存入栈中
12             stack.push(p);
13             //访问根节点
14             printf("%c ",p->data);
15             //遍历左子树
16             p = p->lchild;
17         }
18         else{
19             //退栈
20             p = stack.top();
21             stack.pop();
22             //访问右子树
23             p = p->rchild;
24         }
25     }//while
26 }

 

<2>中序遍历

【思路】:T是要遍历树的根指针,中序遍历要求在遍历完左子树后,访问根,再遍历右子树。
         先将T入栈,遍历左子树;遍历完左子树返回时,栈顶元素应为T,出栈,访问T->data,再中序遍历T的右子树。

 1 void InOrder2(BiTree T){
 2     stack<BiTree> stack;
 3     //p是遍历指针
 4     BiTree p = T;
 5     //栈不空或者p不空时循环
 6     while(p || !stack.empty()){
 7         if(p != NULL){
 8             //存入栈中
 9             stack.push(p);
10             //遍历左子树
11             p = p->lchild;
12         }
13         else{
14             //退栈,访问根节点
15             p = stack.top();
16             printf("%c ",p->data);
17             stack.pop();
18             //访问右子树
19             p = p->rchild;
20         }
21     }//while
22 }

 

 

<3>后序遍历

 

【思路】:T是要遍历树的根指针,后序遍历要求在遍历完左右子树后,再访问根。需要判断根结点的左右子树是否均遍历过。

 1 //后序遍历(非递归)
 2 typedef struct BiTNodePost{
 3     BiTree biTree;
 4     char tag;
 5 }BiTNodePost,*BiTreePost;
 6 
 7 void PostOrder2(BiTree T){
 8     stack<BiTreePost> stack;
 9     //p是遍历指针
10     BiTree p = T;
11     BiTreePost BT;
12     //栈不空或者p不空时循环
13     while(p != NULL || !stack.empty()){
14         //遍历左子树
15         while(p != NULL){
16             BT = (BiTreePost)malloc(sizeof(BiTNodePost));
17             BT->biTree = p;
18             //访问过左子树
19             BT->tag = 'L';
20             stack.push(BT);
21             p = p->lchild;
22         }
23         //左右子树访问完毕访问根节点
24         while(!stack.empty() && (stack.top())->tag == 'R'){
25             BT = stack.top();
26             //退栈
27             stack.pop();
28             BT->biTree;
29             printf("%c ",BT->biTree->data);
30         }
31         //遍历右子树
32         if(!stack.empty()){
33             BT = stack.top();
34             //访问过右子树
35             BT->tag = 'R';
36             p = BT->biTree;
37             p = p->rchild;
38         }
39     }//while
40 }

 

<4>层次遍历

【思路】:按从顶向下,从左至右的顺序来逐层访问每个节点,层次遍历的过程中需要用队列。

 1 //层次遍历
 2 void LevelOrder(BiTree T){
 3     BiTree p = T;
 4     //队列
 5     queue<BiTree> queue;
 6     //根节点入队
 7     queue.push(p);
 8     //队列不空循环
 9     while(!queue.empty()){
10         //对头元素出队
11         p = queue.front();
12         //访问p指向的结点
13         printf("%c ",p->data);
14         //退出队列
15         queue.pop();
16         //左子树不空,将左子树入队
17         if(p->lchild != NULL){
18             queue.push(p->lchild);
19         }
20         //右子树不空,将右子树入队
21         if(p->rchild != NULL){
22             queue.push(p->rchild);
23         }
24     }
25 }

 

 

 

测试用例:

 

输入:

ABC##DE#G##F###

输出:

 

代码

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 
  4 //二叉树结点
  5 typedef struct BiTNode{
  6     //数据
  7     char data;
  8     //左右孩子指针
  9     struct BiTNode *lchild,*rchild;
 10 }BiTNode,*BiTree;
 11 
 12 //按先序序列创建二叉树
 13 int CreateBiTree(BiTree &T){
 14     char data;
 15     //按先序次序输入二叉树中结点的值(一个字符),‘#’表示空树
 16     scanf("%c",&data);
 17     if(data == '#'){
 18         T = NULL;
 19     }
 20     else{
 21         T = (BiTree)malloc(sizeof(BiTNode));
 22         //生成根结点
 23         T->data = data;
 24         //构造左子树
 25         CreateBiTree(T->lchild);
 26         //构造右子树
 27         CreateBiTree(T->rchild);
 28     }
 29     return 0;
 30 }
 31 //输出
 32 void Visit(BiTree T){
 33     if(T->data != '#'){
 34         printf("%c ",T->data);
 35     }
 36 }
 37 //先序遍历
 38 void PreOrder(BiTree T){
 39     if(T != NULL){
 40         //访问根节点
 41         Visit(T);
 42         //访问左子结点
 43         PreOrder(T->lchild);
 44         //访问右子结点
 45         PreOrder(T->rchild);
 46     }
 47 }
 48 //中序遍历  
 49 void InOrder(BiTree T){  
 50     if(T != NULL){  
 51         //访问左子结点  
 52         InOrder(T->lchild);  
 53         //访问根节点  
 54         Visit(T);  
 55         //访问右子结点  
 56         InOrder(T->rchild);  
 57     }  
 58 }  
 59 //后序遍历
 60 void PostOrder(BiTree T){
 61     if(T != NULL){
 62         //访问左子结点
 63         PostOrder(T->lchild);
 64         //访问右子结点
 65         PostOrder(T->rchild);
 66         //访问根节点
 67         Visit(T);
 68     }
 69 }
 70 /* 先序遍历(非递归)
 71    思路:访问T->data后,将T入栈,遍历左子树;遍历完左子树返回时,栈顶元素应为T,出栈,再先序遍历T的右子树。
 72  */
 73 void PreOrder2(BiTree T){
 74     stack<BiTree> stack;
 75     //p是遍历指针
 76     BiTree p = T;
 77     //栈不空或者p不空时循环
 78     while(p || !stack.empty()){
 79         if(p != NULL){
 80             //存入栈中
 81             stack.push(p);
 82             //访问根节点
 83             printf("%c ",p->data);
 84             //遍历左子树
 85             p = p->lchild;
 86         }
 87         else{
 88             //退栈
 89             p = stack.top();
 90             stack.pop();
 91             //访问右子树
 92             p = p->rchild;
 93         }
 94     }//while
 95 }
 96 /* 中序遍历(非递归)
 97    思路:T是要遍历树的根指针,中序遍历要求在遍历完左子树后,访问根,再遍历右子树。
 98    先将T入栈,遍历左子树;遍历完左子树返回时,栈顶元素应为T,出栈,访问T->data,再中序遍历T的右子树。
 99  */
100 void InOrder2(BiTree T){
101     stack<BiTree> stack;
102     //p是遍历指针
103     BiTree p = T;
104     //栈不空或者p不空时循环
105     while(p || !stack.empty()){
106         if(p != NULL){
107             //存入栈中
108             stack.push(p);
109             //遍历左子树
110             p = p->lchild;
111         }
112         else{
113             //退栈,访问根节点
114             p = stack.top();
115             printf("%c ",p->data);
116             stack.pop();
117             //访问右子树
118             p = p->rchild;
119         }
120     }//while
121 }
122 
123 //后序遍历(非递归)
124 typedef struct BiTNodePost{
125     BiTree biTree;
126     char tag;
127 }BiTNodePost,*BiTreePost;
128 
129 void PostOrder2(BiTree T){
130     stack<BiTreePost> stack;
131     //p是遍历指针
132     BiTree p = T;
133     BiTreePost BT;
134     //栈不空或者p不空时循环
135     while(p != NULL || !stack.empty()){
136         //遍历左子树
137         while(p != NULL){
138             BT = (BiTreePost)malloc(sizeof(BiTNodePost));
139             BT->biTree = p;
140             //访问过左子树
141             BT->tag = 'L';
142             stack.push(BT);
143             p = p->lchild;
144         }
145         //左右子树访问完毕访问根节点
146         while(!stack.empty() && (stack.top())->tag == 'R'){
147             BT = stack.top();
148             //退栈
149             stack.pop();
150             printf("%c ",BT->biTree->data);
151         }
152         //遍历右子树
153         if(!stack.empty()){
154             BT = stack.top();
155             //访问过右子树
156             BT->tag = 'R';
157             p = BT->biTree;
158             p = p->rchild;
159         }
160     }//while
161 }
162 //层次遍历
163 void LevelOrder(BiTree T){
164     BiTree p = T;
165     //队列
166     queue<BiTree> queue;
167     //根节点入队
168     queue.push(p);
169     //队列不空循环
170     while(!queue.empty()){
171         //对头元素出队
172         p = queue.front();
173         //访问p指向的结点
174         printf("%c ",p->data);
175         //退出队列
176         queue.pop();
177         //左子树不空,将左子树入队
178         if(p->lchild != NULL){
179             queue.push(p->lchild);
180         }
181         //右子树不空,将右子树入队
182         if(p->rchild != NULL){
183             queue.push(p->rchild);
184         }
185     }
186 }
187 int main()
188 {
189     BiTree T;
190     CreateBiTree(T);
191     printf("先序遍历:\n");
192     PreOrder(T);
193     printf("\n");
194     printf("先序遍历(非递归):\n");
195     PreOrder2(T);
196     printf("\n");
197     printf("中序遍历:\n");
198     InOrder(T);
199     printf("\n");
200     printf("中序遍历(非递归):\n");
201     InOrder2(T);
202     printf("\n");
203     printf("后序遍历:\n");
204     PostOrder(T);
205     printf("\n");
206     printf("后序遍历(非递归):\n");
207     PostOrder2(T);
208     printf("\n");
209     printf("层次遍历:\n");
210     LevelOrder(T);
211     printf("\n");
212     return 0;
213 }

 

 

弱鸡代码!!

//按照层次建树

 1 //Binary tree
 2 #include <iostream>
 3 #include <stdio.h>
 4 #include <malloc.h>
 5 using namespace std;
 6 const int maxn = 1024;
 7 struct Binary{
 8     int data;
 9     struct Binary *lchild, *rchild;
10 };
11 Binary *build(Binary *Btree){
12     printf("Input -1 exit\n");
13     Binary *tree, *queue[maxn];
14     int x, front = 0, rear = -1;
15     while(scanf("%d", &x) && x != -1){
16         tree = new Binary;
17         tree -> data = x;
18         tree -> lchild = tree -> rchild = NULL;
19         queue[++rear] = tree;
20         if(rear == 0) Btree = tree;
21         else{
22             if(tree != NULL && queue[front] != NULL){  
23                 if(rear%2 == 1){
24                     queue[front] -> lchild = tree;
25                 }  
26                 else{  
27                     queue[front] -> rchild = tree;  
28                 }  
29             }  
30             if(rear%2 == 0){  
31                 front++;
32             }  
33         }
34     }
35     return Btree;
36 }
37 void PreOrder(Binary *Btree){
38     if(Btree != NULL){
39         printf("%d ", Btree -> data);
40         PreOrder(Btree -> lchild);
41         PreOrder(Btree -> rchild);
42     }
43 }
44 void InOrder(Binary *Btree){
45     if(Btree != NULL){
46         InOrder(Btree -> lchild);
47         printf("%d ", Btree -> data);
48         InOrder(Btree -> rchild);
49     }
50 }
51 void PostOrder(Binary *Btree){
52     if(Btree != NULL){
53         PostOrder(Btree -> lchild);
54         PostOrder(Btree -> rchild);
55         printf("%d ", Btree -> data);
56     }
57 }
58 void LevelOrder(Binary *Btree){
59     Binary *queue[maxn], *tree;
60     int front = 0, rear = 1;
61     queue[0] = Btree;
62     while(front != rear){
63         tree = queue[front++];
64         printf("%d ", tree -> data);
65         if(tree -> lchild != NULL){
66             queue[rear++] = tree -> lchild;
67         }
68         if(tree -> rchild != NULL){
69             queue[rear++] = tree -> rchild;
70         }
71     }
72 }
73 int main(){
74     Binary *Btree = new Binary;
75     Btree = build(Btree);
76     printf("\nPreOrder : -> \n");
77     PreOrder(Btree);
78     printf("\n\nInOrder : -> \n");
79     InOrder(Btree);
80     printf("\n\nPostOrder : -> \n");
81     PostOrder(Btree);
82     printf("\n\nLevelOrder : -> \n");
83     LevelOrder(Btree);
84     printf("\n");
85     return 0;
86 }

 

 

只有不断学习才能进步! 

 

posted @ 2016-09-08 15:37  wenbao  阅读(214)  评论(0编辑  收藏  举报