如何通过层序遍历序列和中序遍历序列来确定一棵二叉树?
- 根据层序遍历序列第一个结点确定根结点;
- 根据根结点在中序遍历序列中分割出左右子树的中序序列;
- 根据分割出的左右子树的中序序列从层序序列中提取出对应的左右子树的层序序列;
- 对左子树和右子树分别递归使用相同的方式继续分解;
要点:根据分割出的左右子树的中序序列从层序序列中提取出对应的左右子树的层序序列,分别构建出新的左右子树的层序序列和中序序列;
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 5 struct node 6 { 7 char data; 8 struct node *lt, *rt; 9 }; 10 11 // 前序遍历 12 void preorder(struct node *root) 13 { 14 if(root) 15 { 16 printf("%c", root->data); 17 preorder(root->lt); 18 preorder(root->rt); 19 } 20 } 21 22 // 中序遍历 23 void midorder(struct node *root) 24 { 25 if(root) 26 { 27 midorder(root->lt); 28 printf("%c", root->data); 29 midorder(root->rt); 30 } 31 } 32 33 // 后序遍历 34 void postorder(struct node *root) 35 { 36 if(root) 37 { 38 postorder(root->lt); 39 postorder(root->rt); 40 printf("%c", root->data); 41 } 42 } 43 44 // 层序遍历 45 void levelorder( struct node *root ) 46 { 47 struct node *queue[100]; 48 struct node *pt; 49 int head; 50 int tail; 51 52 head = 0; 53 tail = 0; 54 55 queue[tail++] = root; 56 while( tail != head ) 57 { 58 pt = queue[head++]; 59 printf("%c", pt->data); 60 if( pt->lt != NULL ) 61 { 62 queue[tail++] = pt->lt; 63 } 64 65 if( pt->rt != NULL ) 66 { 67 queue[tail++] = pt->rt; 68 } 69 } 70 } 71 72 // 由先序序列和中序序列建立二叉树 73 struct node *create_by_pre_and_mid(int n, char *pre, char *mid) 74 { 75 struct node *root; 76 int i; 77 78 if(n==0) 79 return NULL; 80 81 root=(struct node *)malloc(sizeof(struct node)); 82 root->data=pre[0]; 83 84 for(i=0;i<n;i++) // 寻找左右子树的元素 85 if(pre[0]==mid[i]) 86 break; 87 88 root->lt = create_by_pre_and_mid(i, pre+1, mid); // 建立左子树 89 root->rt = create_by_pre_and_mid(n-i-1, pre+i+1, mid+i+1); // 建立右子树 90 91 return root; 92 } 93 94 // 由后序序列和中序序列建立二叉树 95 struct node *create_by_post_and_mid(int n, char *post, char *mid) 96 { 97 struct node *root; 98 int i; 99 100 if(n==0) 101 return NULL; 102 103 root=(struct node *)malloc(sizeof(struct node)); 104 root->data=post[n-1]; 105 106 for(i=0;i<n;i++) // 寻找左右子树的元素 107 if(post[n-1]==mid[i]) 108 break; 109 110 root->lt = create_by_post_and_mid(i, post, mid); // 建立左子树 111 root->rt = create_by_post_and_mid(n-i-1, post+i, mid+i+1); // 建立右子树 112 113 return root; 114 } 115 116 // 由层序序列和中序序列建立二叉树 117 struct node *create_by_level_and_mid(int n, char *level, char *mid) 118 { 119 struct node *root; 120 char left[20]; 121 char right[20]; 122 int i, j, k; 123 int l, r; 124 int lcnt, rcnt; 125 126 lcnt = 0; 127 rcnt = 0; 128 129 if( n == 0 ) 130 return NULL; 131 132 root = (struct node *)malloc(sizeof(struct node)); 133 root->data = level[0]; 134 135 // 找到根节点 136 for( i = 0; i < n; i++ ) 137 if( level[0] == mid[i] ) 138 break; 139 140 // 划分左右子树 141 for( k = 0; k < n; k++ ) 142 { 143 for( l = 0; l < i; l++ ) 144 { 145 if( mid[l] == level[k] ) 146 { 147 148 left[lcnt++] = level[k]; 149 } 150 } 151 for( r = 0; r < n-i-1; r++ ) 152 { 153 if( mid[r+i+1] == level[k] ) 154 { 155 right[rcnt++] = level[k]; 156 } 157 } 158 } 159 160 root->lt = create_by_level_and_mid( lcnt, left, mid ); 161 root->rt = create_by_level_and_mid( rcnt, right, mid+i+1 ); 162 163 return root; 164 } 165 166 /** 167 * 168 * A 169 * / 170 * B C 171 * / / 172 * D E G H 173 * / 174 * F I 175 **/ 176 int main( void ) 177 { 178 struct node *root=NULL; 179 int len; 180 char *post = "DFEBGIHCA"; 181 char *pre = "ABDEFCGHI"; 182 char *mid = "DBFEAGCHI"; 183 char *level = "ABCDEGHFI"; 184 185 len = strlen(mid); 186 187 //root = create_by_pre_and_mid(len, pre, mid); 188 //root = create_by_post_and_mid(len, post, mid); 189 root = create_by_level_and_mid( len, level, mid ); 190 191 printf(" preorder: "); 192 preorder(root); 193 194 printf(" midorder: "); 195 midorder(root); 196 197 printf(" postorder: "); 198 postorder(root); 199 200 printf(" levelorder: "); 201 levelorder( root ); 202 203 printf(" "); 204 205 system("pause"); 206 return 0; 207 }