剑指offer 编程题(25):二叉树搜索与双向链表

来源:互联网 发布:苹果系统怎么卸载软件 编辑:程序博客网 时间:2024/05/21 06:22

题目描述

输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。

在二叉搜索树中,每个结点都有两个分别指向其左、右子树的指针,左子树结点的值总是小于父结点的值,右子树结点的值总是大于父结点的值。而在双向链表中,每个结点也有两个指针,它们分别指向前一个结点和后一个结点。所以这两种数据结构的结点是一致,二叉搜索树之所以为二叉搜索树,双向链表之所以为双向链表,只是因为两个指针的指向不同而已,通过改变其指针的指向来实现是完全可能的。

例如如下的二叉搜索树,
这里写图片描述
若采用中序遍历,其遍历顺序为1-2-3-4-5-6-7,通过适当的指针变换操作,可变成的双向有序链表如下:
这里写图片描述

class Solution {public:    TreeNode* Convert(TreeNode* pRootOfTree)    {        if(pRootOfTree == nullptr) return nullptr;        TreeNode* pre = nullptr;        convertHelper(pRootOfTree, pre);        TreeNode* res = pRootOfTree;        while(res ->left)            res = res ->left;        return res;    }    void convertHelper(TreeNode* cur, TreeNode*& pre)    {        if(cur == nullptr) return;        convertHelper(cur ->left, pre);        cur ->left = pre;        if(pre) pre ->right = cur;        pre = cur;        convertHelper(cur ->right, pre);    }};
class Solution {public:    TreeNode* Convert(TreeNode* pRootOfTree)    {        if (pRootOfTree == NULL)return NULL;        TreeNode *pointer = NULL;        convert2List(pRootOfTree, pointer);        while (pointer->left!=NULL)        {            pointer = pointer->left;        }        return pointer;    }    void convert2List(TreeNode* pRoot,TreeNode *&pointer)    {        if (pRoot == NULL)        {            return;        }        {            if (pRoot->left != NULL)            {                convert2List(pRoot->left,pointer);            }            pRoot->left = pointer;            if (pointer != NULL)            {                pointer->right = pRoot;            }            pointer = pRoot;            if (pRoot->right!=NULL)            {                convert2List(pRoot->right, pointer);            }        }    }};

可以中序遍历,然后push到一个vector里面,再连接成链表,此方法可以实现,但是违反题目不能创建新空间的规定,属于犯规作弊

class Solution {public:    vector<TreeNode*> nodes;    void tranverse(TreeNode* pRoot) {        if (nullptr == pRoot)            return;        tranverse(pRoot->left);        nodes.push_back(pRoot);        tranverse(pRoot->right);    }    TreeNode* adjustTree() {        for (int i = 0; i < nodes.size() - 1; ++i)            nodes[i]->right = nodes[i+1];        nodes[nodes.size()-1]->right = nullptr;        for (int i = nodes.size() - 1; i > 0; --i)            nodes[i]->left = nodes[i-1];        nodes[0]->left = nullptr;        return nodes[0];    }    TreeNode* Convert(TreeNode* pRoot)    {        if (nullptr == pRoot)            return nullptr;        tranverse(pRoot);        return adjustTree();    }};

非递归中序遍历

void inOrder2(BinTree *root)      //非递归中序遍历  {      stack<BinTree*> s;      BinTree *p=root;      while(p!=NULL||!s.empty())      {          while(p!=NULL)          {              s.push(p);              p=p->lchild;          }          if(!s.empty())          {              p=s.top();              cout<<p->data<<" ";              s.pop();              p=p->rchild;          }      }      }  
/*非递归中序遍历,加个指针pre记录上一次出栈值*/class Solution {public:    TreeNode* Convert(TreeNode* pRootOfTree)    {        TreeNode *head = NULL, *pre = NULL;//head 输出,pre记录上一次出栈值        stack<TreeNode*> s;        while (pRootOfTree || !s.empty())        {            while (pRootOfTree)            {                s.push(pRootOfTree);                pRootOfTree = pRootOfTree->left;            }            if (!s.empty())            {                pRootOfTree = s.top();                s.pop();                if (pre != NULL)                {                    pre->right = pRootOfTree;                    pRootOfTree->left = pre;                }                else//pre为空,表示s第一次出栈,第一次出栈值为最左值,即输出值                    {                    head = pRootOfTree;                }                pre = pRootOfTree;                pRootOfTree = pRootOfTree->right;            }        }        return head;    }};
原创粉丝点击