二叉树 => 链表

45 篇文章 0 订阅

源自:http://blog.csdn.net/lilypp/article/details/6525256

将搜索二叉树转换成链表,不能创建新的节点,只能改变指针的指向。

 

无论是转换成单向链表还是双向链表,节点的顺序都是:1-2-3-4-5-6-7,等于中序遍历的顺序。

【1.1 二叉树-->双向链表】

二叉树是一种很适合使用递归算法的数据结构,考虑根结点和其左右子树,如果左右子树都已经完成转换了,那么只需要将左子树的最大结点和根连接,将根和右子树的最小结点连接即完成整棵数的转换。

[cpp]  view plain copy
  1. //搜索二叉树->双链表  
  2. void BinaryTreeToDoublyList(BiTree &root)  
  3. {  
  4.     if (root == NULL)  
  5.         return;  
  6.   
  7.     if (root->lChild == NULL && root->rChild == NULL)  
  8.         return;  
  9.   
  10.     BiNode* left = root->lChild;  
  11.     BiNode* right = root->rChild;  
  12.     BinaryTreeToDoublyList(left);  
  13.     BinaryTreeToDoublyList(right);  
  14.   
  15.     //找到左子树的最大结点  
  16.     if(left)  
  17.     {  
  18.         while(left->rChild)  
  19.         {  
  20.             left = left->rChild;  
  21.         }  
  22.   
  23.         left->rChild = root;  
  24.         root->lChild = left;  
  25.     }  
  26.   
  27.     if (right)  
  28.     {  
  29.         //找到右子树的最大结点  
  30.         while(right->lChild)  
  31.         {  
  32.             right = right->lChild;  
  33.         }  
  34.   
  35.         right->lChild = root;  
  36.         root->rChild = right;  
  37.     }  
  38. }  
  39.   
  40. void BinaryTreeToDoublyListMain(BiTree &root)  
  41. {  
  42.     if (root == NULL)  
  43.         return;  
  44.   
  45.     BinaryTreeToDoublyList(root);  
  46.   
  47.     //root指向双向链表头  
  48.     if (root->lChild)  
  49.         root = root->lChild;  
  50. }  

【1.2 二叉树-->双向链表】

递归处理左右子树,再将左子树连上根,再连上右子树,得到链表。函数返回头节点方便链接操作。

[cpp]  view plain copy
  1. void BinaryTreeToDoublyList_2(BiNode* root, BiNode** head)  
  2. {  
  3.     if (root == NULL)  
  4.     {  
  5.         *head = NULL;  
  6.         return;  
  7.     }  
  8.   
  9.     BiNode* leftHead = NULL;  
  10.     BiNode* rightHead = NULL;  
  11.   
  12.     //转换左右子树  
  13.     BinaryTreeToDoublyList_2(root->lChild, &leftHead);  
  14.     BinaryTreeToDoublyList_2(root->rChild, &rightHead);  
  15.   
  16.     if (leftHead == NULL)  
  17.         *head = root;  
  18.     else  
  19.         *head = leftHead;  
  20.   
  21.     //将左右子链表链接起来  
  22.     if (leftHead != NULL)  
  23.     {  
  24.         //找到左子链表的末尾结点  
  25.         BiNode* leftTail = leftHead;  
  26.         while(leftTail->rChild)  
  27.             leftTail = leftTail->rChild;  
  28.   
  29.         //左子链表连上根  
  30.         leftTail->rChild = root;  
  31.         if (root != NULL)  
  32.             root->lChild = leftTail;  
  33.     }  
  34.   
  35.     if (root != NULL)  
  36.     {  
  37.         //根连上右子链表  
  38.         root->rChild = rightHead;  
  39.         if (rightHead != NULL)  
  40.             rightHead->lChild = root;  
  41.     }  
  42. }  

【2. 二叉树-->单向链表】

与1.2类似,递归处理左右子树,但是要记住子链表的首尾结点,方便连接操作。对于单链表来说,从head开始,沿着rChild,可以遍历所有结点,而结点的lChild值和之前二叉树时的值一样。

[cpp]  view plain copy
  1. //搜索二叉树->单链表  
  2. void BinaryTreeToSinglyList(BiNode* root, BiNode** head, BiNode** tail)  
  3. {  
  4.     if (root == NULL)  
  5.     {  
  6.         *head = NULL;  
  7.         *tail = NULL;  
  8.         return;  
  9.     }  
  10.   
  11.     BiNode* leftHead = NULL;  
  12.     BiNode* leftTail = NULL;  
  13.     BiNode* rightHead = NULL;  
  14.     BiNode* rightTail = NULL;  
  15.   
  16.     BinaryTreeToSinglyList(root->lChild, &leftHead, &leftTail);  
  17.     BinaryTreeToSinglyList(root->rChild, &rightHead, &rightTail);  
  18.   
  19.     if (leftHead == NULL)  
  20.         *head = root;  
  21.     else  
  22.         *head = leftHead;  
  23.   
  24.     if (rightTail == NULL)  
  25.         *tail = root;  
  26.     else  
  27.         *tail = rightTail;  
  28.   
  29.     //将左右子链表链接起来  
  30.     if (leftTail != NULL)  
  31.         leftTail->rChild = root;  
  32.     if (root != NULL)  
  33.         root->rChild = rightHead;  
  34. }  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值