C语言 二叉树之线索二叉树
直接上代码!
(1)线索二叉树的存储结构
1 typedef enum{link,thread}pointertag;/*link==0表示指向左右孩子指针,thread==1表示指向前驱或后继的线索*/ 2 typedef struct BiTNode{//二叉线索存储结点结构 3 char data; 4 struct BiTNode *lchild,*rchild;//左右孩子指针 5 pointertag ltag;//左右标志 6 pointertag rtag; 7 }BiTNode,*BiTree; 8 BiTNode *pre; //全局变量,始终指向刚刚访问过的结点
(2)构造线索二叉树
1 BiTNode *CreateBiTree(BiTNode *T){ 2 /*分配存储空间*/ 3 T = (BiTNode *)malloc(sizeof(BiTNode)); 4 char ch; 5 printf("先序法创建二叉树,#表示空:"); 6 scanf("%c",&ch); 7 //如果输入为空,则二叉树是空树 8 if(ch=='#'){ 9 T = NULL; 10 }else{ 11 if(!T){ 12 printf("分配存储空间失败!"); 13 exit(OVERFLOW); 14 } 15 T->data = ch;//先输入根结点 16 T->ltag=link; 17 T->rtag=link; 18 T->lchild = CreateBiTree(T->lchild);//递归生成左子树 19 T->rchild = CreateBiTree(T->rchild);//递归生成右子树 20 } 21 return T; 22 }
(3)中序线索化二叉树
1 void InorderThread(BiTree T){ 2 if(T){ 3 InorderThread(T->lchild); 4 if(!T->lchild){ 5 T->ltag=thread; 6 T->lchild=pre;/*当前结点没有左孩子,则当前结点的左孩子指向前驱结点,即左孩子指向前驱 */ 7 } 8 if(!pre->rchild && pre!=NULL){ 9 pre->rtag=thread; 10 pre->rchild=T;/*前驱结点没有右孩子,则前驱结点的右孩子指向当前节点,即右孩子指向后继 */ 11 } 12 pre=T; 13 InorderThread(T->rchild); 14 } 15 }
提示:后继结点的处理麻烦些,因为此时T结点的后继还没有访问到,因此只能对它的前趋加点pre的右指针rchild进行判断。
(4)添加一个头结点
1 BiTNode *InorderHead(BiTNode *head,BiTNode *T){ 2 head=(BiTNode *)malloc(sizeof(BiTNode)); 3 head->ltag=link; 4 head->rtag=thread; 5 head->rchild=head; 6 if(!T){ 7 head->lchild=head; 8 }else{ 9 head->lchild=T; 10 11 pre=head; 12 InorderThread(T); 13 pre->rtag=thread; 14 pre->rchild=head; 15 head->rchild=pre; 16 } 17 return head; 18 }
提示:和双向链表结构一样,添加一个头结点,该结点的data域为空,lchild域的指针指向二叉树的根节点,ltag=0;rchild指向按某种遍历二叉树的最后一个结点,rtag=1.另外,令该遍历产生序列的第一个结点的lchild域指针和最后一个结点的rchild域指针均指向头结点
(5)中序遍历二叉树
1 //中序遍历线索二叉树 2 void InOrderTraverse(BiTNode *head){ 3 BiTNode *T = head->lchild;//T指向根节点 4 while(T != head){//空树或遍历结束时 5 while(T->ltag == link) 6 T = T->lchild; 7 printf("%c ",T->data); 8 while(T->rtag == thread && T->rchild != head){ 9 T = T->rchild; 10 printf("%c ",T->data); 11 } 12 T = T->rchild; 13 } 14 }
(6)在中序线索二叉树上查找后继后前驱
1 //在中序线索二叉树上查找后继 2 BiTNode *InOrderPostNode(BiTNode *T){ 3 if(T->rtag==thread)return(T->rchild); 4 else{ 5 BiTNode *q=T->rchild;//找右子树最先访问的结点 6 while(T->ltag==link)q=q->lchild; 7 return(q); 8 } 9 } 10 //在中序线索二叉树上查找前驱 11 BiTNode *InOrderPreNode(BiTNode *T){ 12 if(T->ltag==thread) return(T->lchild); 13 else{ 14 BiTNode *q=T->lchild;//找左子树最后访问的结点 15 while(q->rtag==link)q=q->rchild; 16 return(q); 17 } 18 }
整体代码及演示:
1 #include <stdio.h> 2 #include <stdlib.h> 3 #define OVERFLOW -1 4 typedef enum{link,thread}pointertag; 5 typedef struct BiTNode{ 6 char data; 7 struct BiTNode *lchild,*rchild; 8 pointertag ltag; 9 pointertag rtag; 10 }BiTNode,*BiTree; 11 BiTNode *pre; 12 BiTNode *CreateBiTree(BiTNode *T){ 13 /*分配存储空间*/ 14 T = (BiTNode *)malloc(sizeof(BiTNode)); 15 char ch; 16 printf("先序法创建二叉树,#表示空:"); 17 scanf("%c",&ch); 18 //如果输入为空,则二叉树是空树 19 if(ch=='#'){ 20 T = NULL; 21 }else{ 22 if(!T){ 23 printf("分配存储空间失败!"); 24 exit(OVERFLOW); 25 } 26 T->data = ch;//先输入根结点 27 T->ltag=link; 28 T->rtag=link; 29 T->lchild = CreateBiTree(T->lchild);//递归生成左子树 30 T->rchild = CreateBiTree(T->rchild);//递归生成右子树 31 } 32 return T; 33 } 34 //中序线索化 35 void InorderThread(BiTree T){ 36 if(T){ 37 InorderThread(T->lchild); 38 if(!T->lchild){ 39 T->ltag=thread; 40 T->lchild=pre;//当前结点没有左孩子,则当前结点的左孩子指向前驱结点,即左孩子指向前驱 41 } 42 if(!pre->rchild && pre!=NULL){ 43 pre->rtag=thread; 44 pre->rchild=T;//前驱结点没有右孩子,则前驱结点的右孩子指向当前节点,即右孩子指向后继 45 } 46 pre=T; 47 InorderThread(T->rchild); 48 } 49 } 50 BiTNode *InorderHead(BiTNode *head,BiTNode *T){ 51 head=(BiTNode *)malloc(sizeof(BiTNode)); 52 head->ltag=link; 53 head->rtag=thread; 54 head->rchild=head; 55 if(!T){ 56 head->lchild=head; 57 }else{ 58 head->lchild=T; 59 60 pre=head; 61 InorderThread(T); 62 pre->rtag=thread; 63 pre->rchild=head; 64 head->rchild=pre; 65 } 66 return head; 67 } 68 //中序遍历线索二叉树 69 void InOrderTraverse(BiTNode *head){ 70 BiTNode *T = head->lchild; 71 while(T != head){ 72 while(T->ltag == link) 73 T = T->lchild; 74 printf("%c ",T->data); 75 while(T->rtag == thread && T->rchild != head){ 76 T = T->rchild; 77 printf("%c ",T->data); 78 } 79 T = T->rchild; 80 } 81 } 82 //在中序线索二叉树上查找后继 83 BiTNode *InOrderPostNode(BiTNode *T){ 84 if(T->rtag==thread)return(T->rchild); 85 else{ 86 BiTNode *q=T->rchild;//找右子树最先访问的结点 87 while(T->ltag==link)q=q->lchild; 88 return(q); 89 } 90 } 91 //在中序线索二叉树上查找前驱 92 BiTNode *InOrderPreNode(BiTNode *T){ 93 if(T->ltag==thread) return(T->lchild); 94 else{ 95 BiTNode *q=T->lchild;//找左子树最后访问的结点 96 while(q->rtag==link)q=q->rchild; 97 return(q); 98 } 99 } 100 int main(){ 101 BiTNode *T; 102 T = CreateBiTree(T); 103 BiTNode *pHead; 104 pHead = InorderHead(pHead,T); 105 InOrderTraverse(pHead); 106 return 0; 107 }
测试输入:abd#g###ce##fh###
输出:d g b a e c h f
先序法输入的树为:

学习数据结构ing,欢迎交流!!

浙公网安备 33010602011771号