/** * 题目: * 1.把二元查找树转变成排序的双向链表(树) 题目: 输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。 要求不能创建任何新的结点,只调整指针的指向。 10 / / 6 14 / / / / 4 8 12 16 转换成双向链表 4=6=8=10=12=14=16。 */ /* * 想法:如果采用中序遍历,那么就是从小到大排序的输出,但是这里要求不能创建任何新的节点,只能调整指针的指向 * 每遍历一个节点,实际上要做两件事:①让前一个节点的右指针指向当前节点 ②让当前节点的左指针指向前一个节点 * * 那么势必要记录前一个节点,而且还需要处理头指针的问题 * * 骨架为中序遍历,但是在之前输出中序遍历值的位置,并不是输出值,而是做上面①和②两点的操作 * */ #include <iostream> #include <stack> using namespace std; /* * 类的成员变量以m_开头 */ struct BSTreeNode { int m_iValue; BSTreeNode* m_pLeft; BSTreeNode* m_pRight; BSTreeNode(int key) : m_iValue(key), m_pLeft(), m_pRight() { } }; struct BSTree { BSTreeNode* root; BSTree() : root(NULL) { //初始的时候给一个空指针给root,因为是空树 } void BSTree_Insert(int key); //申明 void BSTree_Travel_1(BSTreeNode* t); void BSTree_Travel_2(BSTreeNode* t); }; /* * 实现插入函数 */ void BSTree::BSTree_Insert(int key) { BSTreeNode* x = this->root; BSTreeNode* y = NULL; BSTreeNode* n = new BSTreeNode(key); while (x != NULL) { y = x; if (key < x->m_iValue) { x = x->m_pLeft; } else { x = x->m_pRight; } } if (y == NULL) { this->root = n; } else if (key < y->m_iValue) { y->m_pLeft = n; } else { y->m_pRight = n; } } //递归中序遍历 void BSTree::BSTree_Travel_1(BSTreeNode* t) { if (t != NULL) { BSTree_Travel_1(t->m_pLeft); cout << t->m_iValue << ' '; BSTree_Travel_1(t->m_pRight); } } //非递归中序遍历 void BSTree::BSTree_Travel_2(BSTreeNode* t) { stack<BSTreeNode*> s; while (t != NULL || !s.empty()) { // if (t != NULL) { while (t != NULL) { //这里要用while,因为要一口气将左边的路径上的节点全部入栈 s.push(t); t = t->m_pLeft; } if (!s.empty()) { t = s.top(); cout << t->m_iValue << ' '; s.pop(); t = t->m_pRight; } } } typedef struct BSTreeNode pDoubleList; pDoubleList* pHead = NULL; pDoubleList* pListTmp = NULL; /* * 转换过程 */ void conversion(BSTreeNode*& pCurrent) { pCurrent->m_pLeft = pListTmp; //指向前 if (pCurrent->m_pLeft != NULL) { pCurrent->m_pLeft->m_pRight = pCurrent; //前一个的指向后,也就是指向当前 } else { pHead = pCurrent; } pListTmp = pCurrent; //决定下一个的指向前目标 } /* * 将二叉搜索树转换为双向链表 */ pDoubleList* convert_To_Double_List(BSTreeNode* pCurrent) { if (pCurrent == NULL) { return NULL; } if (pCurrent->m_pLeft != NULL) { convert_To_Double_List(pCurrent->m_pLeft); } conversion(pCurrent); if (pCurrent->m_pRight != NULL) { convert_To_Double_List(pCurrent->m_pRight); } return pHead; } /* * 简洁版 */ void change(BSTreeNode *p, BSTreeNode *&last) //中序遍历 { if (!p) //为空则返回 return; change(p->m_pLeft, last); //处理左 if (last) //处理当前 last->m_pRight = p; p->m_pLeft = last; last = p; change(p->m_pRight, last); //处理右 } int main() { pHead = NULL; pListTmp = NULL; BSTree* bst = new BSTree(); bst->BSTree_Insert(5); bst->BSTree_Insert(8); bst->BSTree_Insert(1); bst->BSTree_Insert(99); bst->BSTree_Insert(-2); bst->BSTree_Travel_1(bst->root); cout << endl; bst->BSTree_Travel_2(bst->root); cout << endl; pHead = convert_To_Double_List(bst->root); while (pHead != NULL) { cout << pHead->m_iValue << ' '; pHead = pHead->m_pRight; } cout << endl; return 0; }