## 1. 把二元查找树转变成排序的双向链表 ##
### 题目: 输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。 ###
要求不能创建任何新的结点,只调整指针的指向。
10
/ \
6 14
/ \ / \
4 8 12 16
转换成双向链表 4=6=8=10=12=14=16。
首先我们定义的二元查找树节点的数据结构如下:
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++泛型写的一种算法:
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 }