二叉搜索树与双向链表
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
一、中序遍历,队列保存、
/* struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; TreeNode(int x) : val(x), left(NULL), right(NULL) { } };*/ class Solution { public: TreeNode* Convert(TreeNode* pRootOfTree) { if(pRootOfTree==NULL||(pRootOfTree->left==NULL&&pRootOfTree->right==NULL)) return pRootOfTree; queue<TreeNode*> nodequeue; CreateTree(pRootOfTree,nodequeue); TreeNode* head=nodequeue.front(); head->left=NULL; TreeNode* p=head; nodequeue.pop(); while(!nodequeue.empty()){ TreeNode* next=nodequeue.front(); nodequeue.pop(); p->right=next; next->left=p; p=next; } p->right=NULL; return head; } void CreateTree(TreeNode* pRootOfTree,queue<TreeNode*> &nodequeue){ if(pRootOfTree->left!=NULL) CreateTree(pRootOfTree->left, nodequeue); nodequeue.push(pRootOfTree); if(pRootOfTree->right!=NULL) CreateTree(pRootOfTree->right, nodequeue); } };
二、使用两个变量,记录前驱与头节点。
我们知道二叉排序树中序遍历的结果是排好序的,然后再想到线索化二叉树的过程,很容易联想到用线索化二叉树的方法去做,用一个全局变量去保存前一个节点,然后再去创建节点之间的关系(这里区别与线索化二叉树的是,线索化二叉树创建节点之间的关系是在节点的左右孩子为空的时候采取创建,这样二叉树还是二叉树。这里我们发现返回的双向链表是降序排列的,那我们设置一个变量来记录;
class Solution { private: TreeNode* pre=NULL; TreeNode* head=NULL; public: TreeNode* Convert(TreeNode* pRootOfTree) { if(pRootOfTree==NULL) return pRootOfTree; if(pRootOfTree->left!=NULL) Convert(pRootOfTree->left); if(head==NULL) head=pRootOfTree; if(pre!=NULL){ pre->right=pRootOfTree; pRootOfTree->left=pre; } pre=pRootOfTree; if(pRootOfTree->right!=NULL) Convert(pRootOfTree->right); return head; } };
三、方法二记录了一个头节点,因为遍历完之后得到的是尾节点,那么中序遍历反过来就可以得到最终的头节点
class Solution { private: TreeNode* pre=NULL; public: TreeNode* Convert(TreeNode* pRootOfTree) { if(pRootOfTree==NULL) return pRootOfTree; if(pRootOfTree->right!=NULL) Convert(pRootOfTree->right); if(pre!=NULL){ pre->left=pRootOfTree; pRootOfTree->right=pre; } pre=pRootOfTree; if(pRootOfTree->left!=NULL) Convert(pRootOfTree->left); return pre; } };