【题目具体】
将二叉搜索树转换成一个排序的双向链表,要求不能创建任何新的结点,只能调整树中结点指针的指向,也就是left当prev,right当next。
以如下的二叉树为例:
要将此二叉树转化称为如下的双向链表:
将pleft指针当作指向前一个结点的指针,将pright指针当作指向后一个结点的指针。
则步骤可以分以下:
1.先找到最左边的结点0作为头结点phead。
2.递归处理左子树,将它的上一个结点0用prev记录住,找到最左边的结点后。
3.处理当前结点0,将0的pleft指针指向prev,若prev为空,则不用对它进行操作,将prev指向当前结点,当前结点没有右子树,返回到上一层递归。
4.处理当前结点1,将结点1的pleft指针指向prev也就是结点0,此时prev结点不为空,则将prev的pright指针指向当前结点1,将prev指向当前结点。
5.当前结点1有右孩子,再对右子树进行左子树同等操作,1的右孩子2,2的pleft指向prev也就是结点1,此时prev不为空,则将prev的pright指向当前结点2,再更新prev指向当前结点2,然后返回到上一层。
此时结果如下:
6.按照以上的方法一直进行递归实现。
【代码实现】
/将链表转化为一个双向链表 Node* ToDb_List() { return _ToDb_List(_proot); } void PrintList(Node* phead) { _PrintList(phead); } // private: ///将链表转为一个双向链表 Node* _ToDb_List(Node* proot) { assert(proot); Node *pCur = proot; ///找链表的头结点 while (pCur->_pLeft) { pCur = pCur->_pLeft; } Node * phead = pCur; Node* last_node = NULL; //指向上一个结点 _ConvertNode(proot,last_node); //调用递归函数 return phead; } void _ConvertNode(Node* proot,Node * &last_node) ///递归实现函数 { if (proot == NULL) return; ///处理左子树 if(proot->_pLeft != NULL) _ConvertNode(proot->_pLeft,last_node); /调整left指针指向上一个结点 proot->_pLeft = last_node; 将上一个结点的右指向当前结点 if(last_node != NULL) last_node->_pRight = proot; /更新last的值 last_node = proot; 处理右子树 if(proot->_pRight != NULL) _ConvertNode(proot->_pRight,last_node); } void _PrintList(Node* phead) ///打印双向链表的函数 { if (!phead) return; Node* pcur = phead; while(pcur) { cout<<pcur->_key<<"->"; pcur = pcur ->_pRight; } cout<<"NULL"<<endl; }
测试代码
BinarySearchTree<int,int> s1; s1.Insert(5,0); s1.Insert(3,0); s1.Insert(1,0); s1.Insert(7,0); s1.Insert(8,0); s1.Insert(2,0); s1.Insert(6,0); s1.Insert(0,0); s1.Insert(9,0); BSTNode<int,int>* phead = s1.ToDb_List(); s1.PrintList(phead);
运行结果: