二叉树后继

来源:互联网 发布:开淘宝食品经营许可证 编辑:程序博客网 时间:2024/04/27 19:09

二叉树后继

如果有指向父亲的结点,则:

1.如果当前结点有右儿子,或者当前结点是根结点,则后继结点为右子树的最左叶节点;2.否则,如果当前结点是父结点的左儿子,则后继结点就是父结点;(其实是第三种情况的一个特例,即自己是第0代祖先,返回第一代祖先)3.否则,向上遍历,直到n-1代祖先是n代祖先的左儿子,则后继结点为n代祖先;或者遍历到根节点后未找到符合的n代结点,则该结点为中序遍历的最后结点,没有后继。

时间复杂度为树的高度O(lgN)。

    struct TreeNode      {          char key;          TreeNode *left;          TreeNode *right;          TreeNode *parent;      };      TreeNode *FindSuccessor(TreeNode *x)      {          if(x->right!=NULL)          {              TreeNode *q=x->right;              while(q->left)                  q=q->left;              return q;          }          TreeNode *p=x->parent;          while(p&&x==p->right)          {              x=p;              p=p->parent;          }          return p;      }  

如果没有父指针,则通过栈来实现中序遍历:

struct TreeNode {    int val;    struct TreeNode *left;    struct TreeNode *right;    TreeNode(int x) :            val(x), left(NULL), right(NULL) {    }};class Successor {public:    int findSucc(TreeNode *root,int p){        stack<TreeNode *> st;        bool isFound=false;        TreeNode *cur=root;        while(cur||!st.empty()){            if(cur!=NULL){                st.push(cur);                cur=cur->left;            } else {                cur=st.top();st.pop();                if(isFound==true)return cur->val;                if(cur->val==p)isFound=true;                cur=cur->right;            }        }        return -1;    }};

也可以通过递归实现:

class Successor {public:    int findSucc(TreeNode* root, int p) {        // write code here        bool sign=0;        return findSucc1(root,p,sign);    }    int findSucc1(TreeNode* root,int p,bool &sign)    {        if(root==NULL)            return -1;        int left=findSucc1(root->left,p,sign);        if(left!=-1)            return left;        if(sign==true)            return root->val;        if(root->val==p)            sign=true;        return findSucc1(root->right,p,sign);    }};
原创粉丝点击