二叉树转换成双向链表


             上次写了一个二叉树的创建的程序,代码思想基本都是数据结构书本上的,后面看到另外一个人的博客 用java实现了一个二叉排序树的转换为双向链表的程序,代码之多吓我一跳,后面想想用递归的方法从二叉树的基础上按照某种方式建立双向链表,代码量应该不是很多。

 

[cpp]  view plain copy
  1. #define EQ(x,m) ( x == m ? 1 : 0)  
  2. #define LT(x,m) ( x < m ? 1 : 0)  
  3.   
  4. typedef int Element;  
  5.   
  6. typedef struct tag_Tree  
  7. {  
  8.     Element data;  
  9.     struct tag_Tree * lchild;  
  10.     struct tag_Tree * rchild;  
  11. }*BiTree,BiTNode;  
  12.   
  13. typedef struct tag_DuLNode  
  14. {  
  15.     Element data;  
  16.     struct tag_DuLNode * next;  
  17.     struct tag_DuLNode * prior;  
  18. }*DulList,DulNode;  
  19.   
  20. /*按插入的方式建立二叉排序树*/  
  21. int  InsertBST(BiTree * T , Element e)  
  22. {  
  23.     BiTree s,p;  
  24.     if( !SearchBST(*T,e,0,&p) )  
  25.     {  
  26.         s = (BiTree) malloc( sizeof(BiTNode) );  
  27.           
  28.         s -> data = e;  
  29.         s -> lchild = s -> rchild = 0;  
  30.           
  31.         if( ! p )   *T = s;  
  32.         else if ( LT(e,p->data))  
  33.         {  
  34.             p -> lchild = s;  
  35.         }  
  36.         else  
  37.         {  
  38.             p -> rchild = s;  
  39.         }  
  40.         return 1;  
  41.     }  
  42.     else   
  43.         return 0;  
  44. }  
  45.   
  46. /*从排序树中删除 元素为e的节点,递归搜索,然后搜索删除*/  
  47. int DeleteBST(BiTree * T,Element e)  
  48. {  
  49.     if(!(*T))  
  50.     {  
  51.         return 0;  
  52.     }  
  53.     else  
  54.     {  
  55.         if( EQ(e,(*T)->data) )     
  56.         {  
  57.             return DeleteSearch(T);  
  58.         }  
  59.         else if( LT(e,(*T)->data) )  
  60.         {  
  61.             return DeleteBST(&((*T)->lchild),e);  
  62.         }  
  63.         else  
  64.             return DeleteBST(&((*T)->rchild),e);  
  65.     }  
  66. }  
  67. /* 
  68. 从排序树中删除的节点T 
  69. 如果节点的左子树为空,就用右子树待地该节点 
  70. 如果节点的右子树为空,就用左子树待地该节点 
  71.  
  72. 如果,T节点的左右孩子都不为空,则取T左孩子的最右孩子代替该节点, 
  73. (如果T的左子树没有右孩子,则直接用T的左孩子的左孩子代替为T的左孩子) 
  74. */  
  75. int DeleteSearch(BiTree* T)  
  76. {  
  77.     BiTree q,s;  
  78.     if(!(*T))  
  79.         return 0;  
  80.     if( ! (*T)->lchild )  
  81.     {  
  82.         q = *T;  
  83.         (*T) = (*T)->rchild;  
  84.         free(q);  
  85.     }  
  86.     else if( ! (*T)->rchild)  
  87.     {  
  88.         q = *T;  
  89.         (*T) = (*T)->lchild;  
  90.         free(q);  
  91.         q=0;  
  92.     }  
  93.     else  
  94.     {  
  95.         q = (*T);  
  96.         s = (*T) -> lchild;  
  97.         while( s ->rchild )  
  98.         {  
  99.             q = s;  
  100.             s = s->rchild;  
  101.         }  
  102.         (*T)->data = s ->data;  
  103.         if ( q != (*T)) q->rchild = s ->lchild;  
  104.         else  
  105.         {  
  106.             q ->lchild = s ->lchild;  
  107.         }  
  108.         free(s);  
  109.     }  
  110. }  
  111.   
  112.   
  113. int SearchBST(BiTree T,Element key,BiTree f,BiTree * p)  
  114. {  
  115.     if(!T)  
  116.     {  
  117.         *p = f;   
  118.         return 0;  
  119.     }  
  120.     else if( EQ(key,T->data) )  
  121.     {  
  122.         *p = T;  
  123.         return 1;  
  124.     }  
  125.     else if( LT(key,T->data) )  
  126.     {  
  127.         return SearchBST(T->lchild,key,T,p);  
  128.     }  
  129.     else  
  130.     {  
  131.         return SearchBST(T->rchild,key,T,p);  
  132.     }  
  133.   
  134. }  
  135. /*构造新的双向链表的节点*/  
  136. DulNode * NewChainNode(Element data)  
  137. {  
  138.     DulNode * pChain=0;  
  139.     pChain = ( DulNode * )malloc( sizeof(DulNode) );  
  140.       
  141.     if( ! pChain )  return 0;  
  142.   
  143.     pChain->data=data;  
  144.     pChain->next=0;  
  145.     pChain->prior=0;  
  146.     return pChain;  
  147. }  
  148. /*得到链表上的某个点,pos 为-1得到最后一个*/  
  149. DulNode * GetAddr(DulList  plist,int pos)  
  150. {  
  151.     DulNode * pt = 0;  
  152.     int n = 0 ;  
  153.     if( !(plist ) || pos < -1  )  
  154.         return 0;  
  155.     pt = plist;  
  156.   
  157.     if( pos == -1)  
  158.     {  
  159.         while(pt->next)  
  160.         {  
  161.             pt = pt->next;  
  162.         }  
  163.       
  164.         return pt;  
  165.     }  
  166.     while(n < pos)  
  167.     {  
  168.         pt = pt->next;  
  169.         n++;  
  170.     }  
  171.     return pt;  
  172.   
  173. }  
  174. /* 
  175.     递归创建: 
  176.     按递增的方式创建双向链表 
  177.     ,创建完成之后会在链表的最后有个数值为0的无效节点,小小的缺憾,有待改进; 
  178. */  
  179. int CreateList_Dul_Ins(BiTree T,DulList * DList)  
  180. {  
  181.     DulNode * newp = 0;  
  182.     DulNode * oldp = 0;  
  183.     Element data= 0;  
  184.     if(!T)  
  185.         return 0 ;  
  186.     if(!( DList))  
  187.         return 0;  
  188.   
  189.     newp =GetAddr(*DList,-1);  
  190.   
  191.     CreateList_Dul_Ins(T->lchild,&(newp)) ;  
  192.   
  193.     /*printf("%d ",T->data);*/  
  194.     newp =GetAddr(*DList,-1);  
  195.     newp->data = T->data;  
  196.   
  197.     newp ->next =  NewChainNode(data);     
  198.     newp ->next->prior = newp;  
  199.     newp = newp->next;  
  200.   
  201.   
  202.     CreateList_Dul_Ins(T->rchild,&(newp) ) ;  
  203.     return 1;  
  204. }  
  205.   
  206. /* 
  207.     递归创建: 
  208.     按递增的方式创建双向链表 
  209.     ,创建完成之后会在链表的最后有个数值为0的无效节点,小小的缺憾,有待改进; 
  210. */  
  211. int CreateList_Dul_Des(BiTree T,DulList * DList)  
  212. {  
  213.     DulNode * newp = 0;  
  214.     DulNode * oldp = 0;  
  215.     Element data= 0;  
  216.     if(!T)  
  217.         return 0 ;  
  218.     if(!( DList))  
  219.         return 0;  
  220.   
  221.     newp  =  * DList ;  
  222.     CreateList_Dul_Des(T->lchild,&(newp)) ;  
  223.   
  224.     * DList =  newp;  
  225.     /*printf("%d ",T->data);*/  
  226.     newp->data = T->data;  
  227.     oldp  =  NewChainNode(data);  
  228.     oldp->next = newp;  
  229.     newp->prior = oldp;  
  230.     (* DList)  = oldp;  
  231.     newp  =  * DList ;  
  232.   
  233.     if( CreateList_Dul_Des(T->rchild,&(newp) ) )  
  234.     {  
  235.          * DList =  newp;  
  236.     }  
  237.     return 1;  
  238.   
  239. }  
  240.   
  241. void showTree(BiTree T)  
  242. {  
  243.     if(!T) return ;  
  244.       
  245.     printf("%d ", T->data);  
  246.       
  247.     showTree(T->lchild);  
  248.   
  249.     showTree(T->rchild);  
  250. }  
  251.   
  252. /*两种方式输出双向链表*/  
  253. void showList(DulList DList)  
  254. {  
  255.     DulList pt;  
  256.     pt =DList;  
  257.       
  258.     printf("\n");  
  259.   
  260.     printf("正向输出: ");     
  261.     while(pt)  
  262.     {  
  263.         printf("%d ",pt->data);  
  264.   
  265.         pt = pt->next;  
  266.     }  
  267.     printf("\n");  
  268.     printf("反向输出: ");  
  269.     /*后续输出*/  
  270.     pt = GetAddr(DList,-1);  
  271.     while(pt)  
  272.     {  
  273.         printf("%d ",pt->data);  
  274.   
  275.         pt = pt->prior;  
  276.     }  
  277.     printf("\n");  
  278. }  
  279.   
  280. main()  
  281. {  
  282.     int a[20]={45,24,53,12,37,90,-2};//"hello world!";  
  283.     int n  = 0;  
  284.     BiTree T = 0;  
  285.     BiTree f = 0;  
  286.     BiTree p = 0;  
  287.     DulList  ADList =NewChainNode(0); /* 双向链表的头结点*/   
  288.     DulList  BDList =NewChainNode(0);  
[cpp]  view plain copy
  1.     /*建立二叉排序树*/   
  2.     while( a[n] > 0)  
  3.     {  
  4.         InsertBST(&T , a[n]);  
  5.         n++;  
  6.     }  
  7.     showTree(T);  
  8.     printf("\n");  
  9.     if(! SearchBST(T,53,0,&p) )  
  10.         printf("error\n");  
  11.       
  12. /*  DeleteBST(&T,24); 
  13. */  
  14.     printf("输出二叉排序树,先根序\n");  
  15.       
  16.     showTree(T);  
  17.       
  18.     printf("\n");  
  19.       
  20.     CreateList_Dul_Des(T,&(ADList));  
  21.     showList(ADList);  
  22.   
  23.     printf("\n");  
  24.   
  25.     CreateList_Dul_Ins(T,&(BDList));  
  26.     showList(BDList);  
  27.   
  28. }  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值