二叉搜索树与双向链表

Posted 三颗心

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二叉搜索树与双向链表相关的知识,希望对你有一定的参考价值。

题目:输入一棵二叉搜索树,现在要将该二叉搜索树转换成一个排序的双向链表。而且在转换的过程中,不能创建任何新的结点,只能调整树中的结点指针的指向来实现。

思路:采用中序遍历将二叉树从小到大遍历每一个结点,通过改变指针来实现双向链表。

  1 #include<stdio.h>
  2 #include "stdafx.h"
  3 #include<tchar.h>
  4 
  5 struct BinaryTreeNode
  6 {
  7     int              m_nValue;
  8     BinaryTreeNode*  m_pLeft;
  9     BinaryTreeNode*  m_pRight;
 10 };
 11 BinaryTreeNode* CreateBinaryTreeNode(int value)
 12 {
 13     BinaryTreeNode* pNode = new BinaryTreeNode();
 14     pNode->m_nValue = value;
 15     pNode->m_pLeft = NULL;
 16     pNode->m_pRight = NULL;
 17 }
 18 void ConnectTreeNodes(BinaryTreeNode* pParent, BinaryTreeNode* pLeft, BinaryTreeNode* pRight)
 19 {
 20     if(pParent != NULL)
 21     {
 22         pParent->m_pLeft = pLeft;
 23         pParent->m_pRight = pRight;
 24     }
 25 }
 26 void PrintTreeNode(BinaryTreeNode* pNode)
 27 {
 28     if(pNode != NULL)
 29     {
 30         printf("value of this node is: %d\\n", pNode->m_nValue);
 31         
 32         if(pNode->m_pLeft != NULL)
 33             printf("value of its left child is: %d.\\n", pNode->m_pLeft->m_nValue);
 34         else
 35             printf("left child is null.\\n");
 36         
 37         if(pNode->m_pRight != NULL)
 38             printf("value of its right child is: %d.\\n",pNode->m_pRight->m_nValue);
 39         else
 40             printf("right child is null.\\n");
 41     }
 42     else
 43     {
 44         printf("this node is null.\\n");
 45     }
 46     printf("\\n");
 47 }
 48 void PrintTree(BinaryTreeNode* pRoot)
 49 {
 50     PrintTreeNode(pRoot);
 51     
 52     if(pRoot != NULL)
 53     {
 54         if(pRoot->m_pLeft != NULL)
 55             PrintTree(pRoot->m_pLeft);
 56         
 57         if(pRoot->m_pRight != NULL) 
 58             PrintTree(pRoot->m_pRight);
 59     }
 60 }
 61 void DestroyTree(BinaryTreeNode* pRoot)
 62 {
 63     if(pRoot != NULL)
 64     {
 65         BinaryTreeNode* pLeft = pRoot->m_pLeft;
 66         BinaryTreeNode* pRight = pRoot->m_pRight;
 67         
 68         delete pRoot;
 69         pRoot = NULL;
 70         
 71         DestroyTree(pLeft);
 72         DestroyTree(pRight);
 73     }
 74 }
 75 
 76 void ConvertNode(BinaryTreeNode* pNode, BinaryTreeNode** pLastNodeInList);
 77 
 78 
 79 BinaryTreeNode* Convert(BinaryTreeNode* pRootOfTree)
 80 {
 81     BinaryTreeNode *pLastNodeInList = NULL;
 82     ConvertNode(pRootOfTree, &pLastNodeInList);
 83     
 84     //pLastNodeInList指向链表的的尾结点,遍历找到头结点返回。 
 85     BinaryTreeNode *pHeadOfList = pLastNodeInList;
 86     while(pHeadOfList != NULL && pHeadOfList->m_pLeft != NULL)
 87         pHeadOfList = pHeadOfList->m_pLeft;
 88     
 89     return pHeadOfList;
 90 }
 91 
 92 //中序遍历转换过程, 
 93 //参数:处理当前结点, 当前链表最后一个结点(初始值为空) 
 94 void ConvertNode(BinaryTreeNode* pNode, BinaryTreeNode** pLastNodeInList)
 95 {
 96     if(pNode == NULL)
 97         return;
 98     
 99     BinaryTreeNode *pCurrent = pNode;
100     
101     //递归处理左子树 
102     if(pCurrent->m_pLeft != NULL)
103         ConvertNode(pCurrent->m_pLeft, pLastNodeInList);
104     
105     //将当前链表的左指针指向已经转换好的链表的最后一个位置    
106     pCurrent->m_pLeft = *pLastNodeInList;
107     
108     //将已经转换好的链表的最后一个结点的右指针指向当前结点 
109     if(*pLastNodeInList != NULL)
110         (*pLastNodeInList)->m_pRight = pCurrent;
111     
112     //更新链表最后一个结点 
113     *pLastNodeInList = pCurrent;
114     
115     //递归处理当前结点的右子树 
116     if(pCurrent->m_pRight != NULL)
117         ConvertNode(pCurrent->m_pRight, pLastNodeInList);
118 }
119 
120 //打印双向链表 
121 void PrintDoubleLinkedList(BinaryTreeNode* pHeadOfList) 
122 {
123     BinaryTreeNode* pNode = pHeadOfList;
124     
125     printf("The nodes from left to right are:\\n");
126     while(pNode != NULL)
127     {
128         printf("%d\\t", pNode->m_nValue);
129         
130         if(pNode->m_pRight == NULL)
131             break;
132         pNode = pNode->m_pRight;
133     }
134     printf("\\n");
135 }
136 
137 void DestroyList(BinaryTreeNode* pHeadOfList)
138 {
139     BinaryTreeNode* pNode = pHeadOfList;
140     while(pNode != NULL)
141     {
142         BinaryTreeNode* pNext = pNode->m_pRight;
143         
144         delete pNode;
145         pNode = pNext;
146     }
147 }
148 
149 //            10
150 //         /      \\
151 //        6        14
152 //       /\\        /\\
153 //      4  8     12  16
154 
155 int main()
156 {
157     BinaryTreeNode* pNode10 = CreateBinaryTreeNode(10);
158     BinaryTreeNode* pNode6 = CreateBinaryTreeNode(6);
159     BinaryTreeNode* pNode14 = CreateBinaryTreeNode(14);
160     BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4);
161     BinaryTreeNode* pNode8 = CreateBinaryTreeNode(8);
162     BinaryTreeNode* pNode12 = CreateBinaryTreeNode(12);
163     BinaryTreeNode* pNode16 = CreateBinaryTreeNode(16);
164     
165     ConnectTreeNodes(pNode10, pNode6, pNode14);
166     ConnectTreeNodes(pNode6, pNode4, pNode8);
167     ConnectTreeNodes(pNode14, pNode12, pNode16);
168     
169     PrintTree(pNode10);
170     
171     BinaryTreeNode* pHeadOfList = Convert(pNode10);
172     
173     printf("The nodes from left to right are:\\n");
174     PrintDoubleLinkedList(pHeadOfList);
175     printf("\\n");
176     
177     DestroyList(pNode4);
178 }

以上是关于二叉搜索树与双向链表的主要内容,如果未能解决你的问题,请参考以下文章

剑指Offer-二叉搜索树与双向链表

剑指offer 27:二叉搜索树与双向链表

剑指offer二十七之二叉搜索树与双向链表

剑指offer 二叉搜索树与双向链表

剑指offer 二叉搜索树与双向链表

剑指 Offer 36. 二叉搜索树与双向链表