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