【数据结构】——构建二叉树,遍历二叉树
二叉树的数据结构:
1 typedef struct BiTree{ 2 char item; 3 struct BiTree *lchild,*rchild; 4 }BiTree;
构建一个二叉树:
为了能让每个结点确认是否有左右孩子,我们要对二叉树进行扩展,变成上图的样子。也就是,将二叉树的每个结点的空指针引出的一个虚节点,其值为一特定值,比如“1”。我们称这种处理后的二叉树为原二叉树的扩展二叉树。
有了扩展二叉树就可以进行二叉树的构建了,笔者选择的是先序构建二叉树:
1 void CreateBiTree(BiTree **T) 2 { 3 char ch; 4 char tmp; 5 scanf("%c",&ch); 6 tmp = getchar(); 7 if(ch == '1') 8 *T = NULL; 9 else{ 10 *T = (BiTree *)malloc(sizeof(BiTree)); 11 if(!*T) 12 exit(1); 13 (*T)->item = ch; 14 CreateBiTree(&((*T)->lchild)); 15 CreateBiTree(&((*T)->rchild)); 16 } 17 }
如果是先序构建二叉树那么我们的输入顺序就应该是:“abdh11i11e11cf11g11”;输入这些数据之后就会构建上图的二叉树了;
若要中序构建二叉树可以把(*T)->item = ch;移动到CreateBiTree(&(*T)->lchild);的后面,不过输入的顺序就变成 对上图扩展二叉树的中序遍历结果了;
前序遍历二叉树:
前序遍历的规则如下:
若二叉树为空,则退出。否则
⑴访问处理根结点;
⑵前序遍历左子树;
⑶前序遍历右子树;
特点:由左而右逐条访问由根出发的树支 (回溯法的基础)
也就是一个递归的过程:
1 void alr_show(BiTree *t) 2 { 3 if(t == NULL) 4 return; 5 printf("%c\t",t->item); 6 alr_show(t->lchild); 7 alr_show(t->rchild); 8 }
中序遍历的规则:
若二叉树为空,则退出;否则
⑴中序遍历左子树;
⑵访问处理根结点;
⑶中序遍历右子树;
1 void lar_show(BiTree *t) 2 { 3 if(t == NULL) 4 return; 5 lar_show(t->lchild); 6 printf("%c\t",t->item); 7 lar_show(t->rchild); 8 }
后序遍历的规则如下:
若二叉树为空,则退出;否则
⑴后序遍历左子树;
⑵后序遍历右子树;
⑶访问处理根结点;
1 void lra_show(BiTree *t) 2 { 3 if(t == NULL) 4 return; 5 lra_show(t->lchild); 6 lra_show(t->rchild); 7 printf("%c\t",t->item); 8 }
完整的代码如下:
1 #include <stdio.h> 2 #include <stdlib.h> 3 4 //二叉树数据结构定义 5 typedef struct BiTree{ 6 char item; 7 struct BiTree *lchild,*rchild; 8 }BiTree; 9 10 void CreateBiTree(BiTree **T) 11 { 12 char ch; 13 char tmp; 14 scanf("%c",&ch); 15 tmp = getchar(); 16 if(ch == '1') 17 *T = NULL; 18 else{ 19 *T = (BiTree *)malloc(sizeof(BiTree)); 20 if(!*T) 21 exit(1); 22 (*T)->item = ch; 23 CreateBiTree(&((*T)->lchild)); 24 CreateBiTree(&((*T)->rchild)); 25 } 26 } 27 28 void alr_show(BiTree *t) 29 { 30 if(t == NULL) 31 return; 32 printf("%c\t",t->item); 33 alr_show(t->lchild); 34 alr_show(t->rchild); 35 } 36 37 void lar_show(BiTree *t) 38 { 39 if(t == NULL) 40 return; 41 lar_show(t->lchild); 42 printf("%c\t",t->item); 43 lar_show(t->rchild); 44 } 45 46 void lra_show(BiTree *t) 47 { 48 if(t == NULL) 49 return; 50 lra_show(t->lchild); 51 lra_show(t->rchild); 52 printf("%c\t",t->item); 53 } 54 int main(void) 55 { 56 BiTree *t; 57 CreateBiTree(&t); 58 printf("先序遍历二叉树\n"); 59 alr_show(t); 60 printf("\n"); 61 printf("中序遍历二叉树\n"); 62 lar_show(t); 63 printf("\n"); 64 printf("后序遍历二叉树\n"); 65 lra_show(t); 66 printf("\n"); 67 68 }
如果按照上述的方法构建二叉树,每次都要输入一个字符,如果二叉树的结点很多,那我们岂不是要输入很多的结点,稍有不注意就会把结点输错;我们可以先把需要输入的结点的顺序存储到一个数组中。然后把数组传入到构建二叉树的函数中,在构建二叉树函数中取数据,赋值给结点;我们会设计一个取数据的函数:
1 char getvalue(char *val) 2 { 3 static int i = 0; 4 return *(val + i++); 5 }
需要注意的是我们的int i,是静态的,也就是说运行程序开始就会存在文件中,修改的值会存在文件中,什么时候用都可以;
那么现在的构建二叉树的函数就变成了:
1 void CreateBiTree(BiTree **T,char *val) 2 { 3 char ch; 4 char tmp; 5 ch = getvalue(val); 6 //scanf("%c",&ch); 7 //tmp = getchar(); 8 if(ch == '1') 9 *T = NULL; 10 else{ 11 *T = (BiTree *)malloc(sizeof(BiTree)); 12 if(!*T) 13 exit(1); 14 (*T)->item = ch; 15 CreateBiTree(&((*T)->lchild),val); 16 CreateBiTree(&((*T)->rchild),val); 17 } 18 }
完整代码如下:
1 #include <stdio.h> 2 #include <stdlib.h> 3 4 //二叉树数据结构定义 5 typedef struct BiTree{ 6 char item; 7 struct BiTree *lchild,*rchild; 8 }BiTree; 9 10 char getvalue(char *val) 11 { 12 static int i = 0; 13 return *(val + i++); 14 15 } 16 17 void CreateBiTree(BiTree **T,char *val) 18 { 19 char ch; 20 char tmp; 21 ch = getvalue(val); 22 //scanf("%c",&ch); 23 //tmp = getchar(); 24 if(ch == '1') 25 *T = NULL; 26 else{ 27 *T = (BiTree *)malloc(sizeof(BiTree)); 28 if(!*T) 29 exit(1); 30 (*T)->item = ch; 31 CreateBiTree(&((*T)->lchild),val); 32 CreateBiTree(&((*T)->rchild),val); 33 } 34 } 35 36 void alr_show(BiTree *t) 37 { 38 if(t == NULL) 39 return; 40 printf("%c\t",t->item); 41 alr_show(t->lchild); 42 alr_show(t->rchild); 43 } 44 45 void lar_show(BiTree *t) 46 { 47 if(t == NULL) 48 return; 49 lar_show(t->lchild); 50 printf("%c\t",t->item); 51 lar_show(t->rchild); 52 } 53 54 void lra_show(BiTree *t) 55 { 56 if(t == NULL) 57 return; 58 lra_show(t->lchild); 59 lra_show(t->rchild); 60 printf("%c\t",t->item); 61 } 62 int main(void) 63 { 64 char ch[100] = "abdh11i11e11cf11g11"; 65 BiTree *t; 66 CreateBiTree(&t,ch); 67 printf("先序遍历二叉树\n"); 68 alr_show(t); 69 printf("\n"); 70 printf("中序遍历二叉树\n"); 71 lar_show(t); 72 printf("\n"); 73 printf("后序遍历二叉树\n"); 74 lra_show(t); 75 printf("\n"); 76 77 }