## 1. 把二元查找樹轉變成排序的雙向鏈表 ##
### 題目: 輸入一棵二元查找樹,將該二元查找樹轉換成一個排序的雙向鏈表。 ###
要求不能建立任何新的結點,只調整指針的指向。
10
/ \
6 14
/ \ / \
4 8 12 16
轉換成雙向鏈表 4=6=8=10=12=14=16。
首先咱們定義的二元查找樹節點的數據結構以下: node
1 struct BSTreeNode 2 { 3 int m_nValue; // value of node 4 BSTreeNode *m_pLeft; // left child of node 5 BSTreeNode *m_pRight; // right child of node 6 };
下面是使用C++泛型寫的一種算法:ios
1 #include "stdafx.h" 2 #include <string> 3 #include <iostream> 4 using namespace std; 5 6 template<typename T> 7 struct BSTTreeNode 8 { 9 BSTTreeNode(T v, BSTTreeNode* lNode = NULL, BSTTreeNode* rNode=NULL) 10 :m_Value(v), m_pLeft(lNode), m_pRight(rNode){} 11 T m_Value; 12 BSTTreeNode* m_pLeft; 13 BSTTreeNode* m_pRight; 14 }; 15 16 17 template<typename T> 18 void TravelBSTree(BSTTreeNode<T> *root) 19 { 20 if (NULL == root) 21 { 22 return; 23 } 24 25 TravelBSTree(root->m_pLeft); 26 27 printf("%d ", root->m_Value); 28 29 TravelBSTree(root->m_pRight); 30 31 } 32 33 template<typename T> 34 void TravelBSTreeAsList(BSTTreeNode<T> *head, bool bReverseTravel = false) 35 { 36 BSTTreeNode<T>* pNode = head; 37 while (pNode) 38 { 39 printf("%d ", pNode->m_Value); 40 if (!bReverseTravel) 41 { 42 pNode = pNode->m_pRight; 43 } 44 else 45 { 46 pNode = pNode->m_pLeft; 47 } 48 } 49 } 50 51 //思路: 52 //查找樹,中序遍歷獲得的節點排序即爲排序的鏈表,而要求排序的雙向鏈表, 53 //1. 假設lt爲左子樹的中序遍歷的尾結點,rh爲右子樹中序遍歷的頭結點 54 //2. 化繁爲簡,若是隻有root, lt, rh三個節點,此時只須然這幾個節點鏈接起來便可。 55 //3. 分別遍歷左右子樹,重複上述過程。 56 template<typename T> 57 void BSTreeHelper(BSTTreeNode<T>* &head, BSTTreeNode<T>* &tail, BSTTreeNode<T>* root) 58 { 59 //step 1. 60 BSTTreeNode<T>* lt = NULL;//左子樹尾結點 61 BSTTreeNode<T>* rh = NULL;//右子樹頭結點 62 63 if (NULL == root) 64 { 65 head = nullptr; 66 tail = nullptr; 67 return; 68 } 69 70 //step 3. 71 BSTreeHelper(head, lt, root->m_pLeft); 72 BSTreeHelper(rh, tail, root->m_pRight); 73 74 //step 2. 75 if (NULL != lt) 76 { 77 lt->m_pRight = root; 78 root->m_pLeft = lt; 79 } 80 else 81 { 82 head = root; 83 } 84 85 if (NULL != rh) 86 { 87 root->m_pRight = rh; 88 rh->m_pLeft = root; 89 } 90 else 91 { 92 tail = root; 93 } 94 } 95 96 template<typename T> 97 BSTTreeNode<T>* TreeToLinkedList(BSTTreeNode<T>* root) 98 { 99 BSTTreeNode<T>* head = NULL; 100 BSTTreeNode<T>* tail = NULL; 101 102 BSTreeHelper(head, tail, root); 103 104 return head; 105 } 106 107 int _tmain(int argc, _TCHAR* argv[]) 108 { 109 int arr[] = {4, 6, 8, 10, 12, 14, 16}; 110 111 BSTTreeNode<int> node4(4); 112 BSTTreeNode<int> node8(8); 113 BSTTreeNode<int> node6(6, &node4, &node8); 114 BSTTreeNode<int> node12(12); 115 BSTTreeNode<int> node16(16); 116 BSTTreeNode<int> node14(14, &node12, &node16); 117 BSTTreeNode<int> node10(10, &node6, &node14); 118 BSTTreeNode<int>* pRoot = &node10; 119 120 printf("Travel BSTree: \n"); 121 TravelBSTree<int>(pRoot); 122 printf("\n"); 123 124 TreeToLinkedList<int>(pRoot); 125 126 printf("Travel BSTree: \n"); 127 TravelBSTreeAsList<int>(&node4, false); 128 printf("\n"); 129 130 TravelBSTreeAsList<int>(&node16, true); 131 printf("\n"); 132 133 return 0; 134 }