关于树的一些基本算法

来源:互联网 发布:网络可爱美女图片 编辑:程序博客网 时间:2024/06/11 00:16
树是一种递归定义的数据结构,也是一种无向无环图。

树的非递归遍历

中序遍历
vector<int> inorderTraversal(TreeNode* root) {
    vector<int> result;
    if(root==NULL)
        return result;;
    stack<TreeNode *> s;
    s.push(root);
    TreeNode * _front;
    bool flag=true;
    while(!s.empty()){
            _front=s.top();
            while(flag && (_front->left!=NULL)){
                s.push(_front->left);
                _front=_front->left;
            }
            flag=false;
            s.pop();
            result.push_back(_front->val);
            if(_front->right!=NULL){
                s.push(_front->right);
                flag=true;
            }
    }
    return result;
}
前序遍历
vector<int> preorderTraversal(TreeNode *root) {
        stack<TreeNode *> s;
        vector<int> result;
        if(root!=NULL){
            s.push(root);
            while(!s.empty()){
                TreeNode * current=s.top();
                s.pop();
                result.push_back(current->val);
                if(current->right!=NULL)
                    s.push(current->right);
                if(current->left!=NULL)
                    s.push(current->left);
            }
        }
        return result;
    }

后序遍历
vector<int> postorderTraversal(TreeNode *root) {
        stack<TreeNode *> s;
        vector<int> result;
        if(root!=NULL){
            s.push(root);
            while(!s.empty()){
                TreeNode * current=s.top();
                s.pop();
                result.push_back(current->val);
                if(current->left!=NULL)
                    s.push(current->left);
                if(current->right!=NULL)
                    s.push(current->right);
            }
        }
        reverse(result.begin(), result.end());
        return result;
    }
层序遍历
vector<vector<int>> levelOrder(TreeNode* root) {
        if (!root) { return {}; }
        vector<int> row;
        vector<vector<int> > result;
        queue<TreeNode*> q;
        q.push(root);
        int count = 1;

            while (!q.empty()) {
            if (q.front()->left) { q.push(q.front()->left); }
            if (q.front()->right) { q.push(q.front()->right); }
            row.push_back(q.front()->val), q.pop();
            if (--count == 0) {
                result.emplace_back(row), row.clear();
                count = q.size();
            }
        }
        return result;
    }

二叉搜索树,从一个有序的链表创建一个p平衡二叉搜索树
    TreeNode *sortedListToBST(ListNode *head)
    {
        return sortedListToBST( head, NULL );
    }

private:
    TreeNode *sortedListToBST(ListNode *head, ListNode *tail)
    {
        if( head == tail )
            return NULL;
        if( head->next == tail )    //
        {  
            TreeNode *root = new TreeNode( head->val );
            return root;
        }
        ListNode *mid = head, *temp = head;
        while( temp != tail && temp->next != tail )    // 寻找中间节点
        {
            mid = mid->next;
            temp = temp->next->next;
        }
        TreeNode *root = new TreeNode( mid->val );
        root->left = sortedListToBST( head, mid );
        root->right = sortedListToBST( mid->next, tail );
        return root;
    }

求path的和
vector<vector<int>> result;
void help(TreeNode *root,int num,int sum,vector<int> temp){
    if(root==NULL)
        return;
    temp.push_back(root->val);
    num+=root->val;
    if(root->left==NULL && root->right==NULL){
        if(num==sum)
            result.push_back(temp);
    }
    else{
        help(root->left,num,sum,temp);
        help(root->right,num,sum,temp);
    }
}
vector<vector<int> > pathSum(TreeNode *root, int sum) {
    vector<int> temp;
    int num=0;
    help(root,num,sum,temp);
    return result;
}

vector<vector<int>> result;
void help(TreeNode *root,int& num,int sum,vector<int>& temp){
    if(root==NULL)
        return;
    temp.push_back(root->val);
    num+=root->val;
    if(root->left==NULL && root->right==NULL){
        if(num==sum)
            result.push_back(temp);
    }
    else{
        help(root->left,num,sum,temp);
        help(root->right,num,sum,temp);
    }
    num-=root->val;
    temp.pop_back();
}
vector<vector<int> > pathSum(TreeNode *root, int sum) {
    vector<int> temp;
    int num=0;
    help(root,num,sum,temp);
    return result;
}
层序遍历
检查二叉排序树的有效性
int x=-100;
void f(TreeNode *root, bool& flag){
    if(flag==false)
        return;
    if(root==NULL)
        return;
    f(root->left,flag);
    if(x==-100){
        x=root->val;
    }
    else{
        if(flag==false) return;
        flag=(root->val>x);
        x=root->val;
    }
    f(root->right,flag);
}
bool isValidBST(TreeNode *root) {
    bool flag=true;
    f(root,flag);
    return flag;
}

一个二叉树的最大深度

int maxDepth(TreeNode *root) {
        if(root==NULL)
            return 0;
        return max(maxDepth(root->left),maxDepth(root->right))+1;
    }

最大路径和

    int maxnum=INT_MIN;
    int f(TreeNode *root){
        if(root==NULL)
            return 0;
        int l=f(root->left);
        int r=f(root->right);
        maxnum=max(max(l,0)+max(r,0)+root->val,maxnum);
        return max(max(l+root->val,r+root->val),root->val);
    }
    int maxPathSum(TreeNode *root) {
        if(root==NULL)
            return 0;
        f(root);
        return maxnum;
    }

拍平一个二叉树

TreeNode * p=NULL;
void f(TreeNode * root){
    if(root==NULL)
        return;
    p->right=root;
    p=p->right;
    TreeNode * l=root->left;
    TreeNode * r=root->right;
    root->left=NULL;
    f(l);
    f(r);
}
void flatten(TreeNode *root) {
    p=new TreeNode(0);
    f(root);
}

算一个完全二叉树的节点数

int leftheight(TreeNode* root){
    int h=0;
    while(root){
        root=root->left;
        h++;
    }
    return h;
}
int rightheight(TreeNode* root){
    int h=0;
    while(root){
        root=root->right;
        h++;
    }
    return h;
}
int countNodes(TreeNode* root) {
    if(root==NULL)
        return 0;
    if(root->left==NULL && root->right==NULL)
        return 1;
    if(root->left!=NULL && root->right==NULL)
        return 2;
    int l=leftheight(root->left);
    int r=rightheight(root->right);
    if(l==r) return pow(2,l+1)-1;
    else return countNodes(root->left)+countNodes(root->right)+1;
}

转换一个有序链表到二叉排序树

TreeNode * f(ListNode *head, int length){
    if(length==0)
        return NULL;
    else if(length==1)
        return new TreeNode(head->val);
    else{
        ListNode * p=head;
        for(int i=0;i<length/2-1;i++){
            p=p->next;
        }
        TreeNode * root=new TreeNode(p->next->val);
        root->right=f(p->next->next,length-1-length/2);
        p->next=NULL;
        root->left=f(head,length/2);
        return root;
    }
}


TreeNode *sortedListToBST(ListNode *head) {
    int L=0;
    for(ListNode * p=head;p!=NULL;p=p->next){
        L++;
    }
    return f(head, L);
}

转换一个有序数组到二叉排序树

    TreeNode *sortedArrayToBST(vector<int> &num) {
        return sortedArrayToBST2(num,0,num.size()-1);
    }
    TreeNode *sortedArrayToBST2(vector<int> &num, int m, int n){
        int size=n-m+1;
        if(size==0){
            return NULL;
        }
        else if(size==1){
            TreeNode * a=new TreeNode(num[m]);
            return a;
        }
        else if(size==2){
            TreeNode * a=new TreeNode(num[m]);
            TreeNode * b=new TreeNode(num[m+1]);
            a->right=b;
            return a;
        }
        else if(size==3){
            TreeNode * a=new TreeNode(num[m]);
            TreeNode * b=new TreeNode(num[m+1]);
            TreeNode * c=new TreeNode(num[m+2]);
            b->left=a;
            b->right=c;
            return b;
        }
        else{
            TreeNode * a=new TreeNode(num[(m+n)/2]);
            a->left=sortedArrayToBST2(num,m,(m+n)/2-1);
            a->right=sortedArrayToBST2(num,(m+n)/2+1,n);
            return a;
        }
    }

卡特兰数,生成多少二叉树

vector<TreeNode *> generateTrees(int n) {
        return f(1,n);
    }
    vector<TreeNode *> f(int start, int end){
        vector<TreeNode *> result;
        if(start>end){
            result.push_back(NULL);
            return result;
        }
        for(int k=start;k<=end;k++){
            vector<TreeNode *> left=f(start,k-1);
            vector<TreeNode *> right=f(k+1,end);
            for(int i=0;i<left.size();i++){
                for(int j=0;j<right.size();j++){
                    TreeNode * root=new TreeNode(k);
                    root->left=left[i];
                    root->right=right[j];
                    result.push_back(root);
                }
            }
        }
        return result;
    }

最小高度

int minDepth(TreeNode *root) {
    if(root==NULL)
        return 0;
    if(root->left==NULL && root->right==NULL)
        return 1;
    else if(root->left==NULL && root->right!=NULL)
        return minDepth(root->right)+1;
    else if(root->left!=NULL && root->right==NULL)
        return minDepth(root->left)+1;
    else
        return min(minDepth(root->left),minDepth(root->right))+1;
}

int level;
int result;
int minDepth(TreeNode *root) {
    level++;
    if(root==NULL){

    }
    else if(root->left==NULL && root->right==NULL){
        if(result==0)
            result=level;
        else
            result=min(level,result);
    }
    else{
        minDepth(root->left);
        minDepth(root->right);
    }
    level--;
    return result;
}

判断一棵树是不是平衡二叉树

int height(TreeNode *root, bool & result){
    if(root==NULL || result==false)
        return 0;
    int l=height(root->left, result);
    int r=height(root->right, result);
    if(abs(l-r)>1)
        result=false;
    return max(l,r)+1;
}

bool isBalanced(TreeNode *root) {
    bool result=true;
    height(root,result);
    return result;
}

找一棵二叉搜素树的最近公共祖先

TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q){
    if(p==root || q==root) return root;
    switch((p->val > root->val)+(q->val > root->val)){
        case 0:
            return lowestCommonAncestor(root->left,p,q);
        case 1:
            return root;
        case 2:
            return lowestCommonAncestor(root->right,p,q);
    }
}

判断一棵树是不是对称的

bool help(TreeNode * root0, TreeNode * root1){
    if(root0==NULL && root1==NULL)
        return true;
    if(root0==NULL || root1==NULL)
        return false;
    return root0->val==root1->val && help(root0->left,root1->right) && help(root0->right,root1->left);
}
bool isSymmetric(TreeNode *root) {
    if(root==NULL)
        return true;
    return help(root->left,root->right);
}

判断两棵树是不是一样的

bool isSameTree(TreeNode *p, TreeNode *q) {
    if(p==NULL && q==NULL)
        return true;
    if(p==NULL || q==NULL)
        return false;
    return p->val==q->val && isSameTree(p->left,q->left) && isSameTree(p->right,q->right);
}

层序遍历

    vector<vector<int> > levelOrder(TreeNode *root) {
        vector<vector<int> > result;
        if(root!=NULL){
            deque<TreeNode *> queue;
            queue.push_back(root);
            vector<int> vec;
            int size=1;
            while(!queue.empty()){
                if(queue.front()!=NULL){
                    vec.push_back(queue.front()->val);
                    if(queue.front()->left!=NULL)
                        queue.push_back(queue.front()->left);
                    if(queue.front()->right!=NULL)
                        queue.push_back(queue.front()->right);
                    queue.pop_front();
                    size--;
                }
                if(size==0){
                    size=queue.size();
                    result.push_back(vec);
                    vec.clear();
                }
            }
        }
        return result;
    }

倒排的层序遍历

    vector<vector<int> > levelOrderBottom(TreeNode *root) {
        vector<vector<int> > result;
        if(root!=NULL){
            deque<TreeNode *> queue;
            queue.push_back(root);
            vector<int> vec;
            int size=1;
            while(!queue.empty()){
                if(queue.front()!=NULL){
                    vec.push_back(queue.front()->val);
                    if(queue.front()->left!=NULL)
                        queue.push_back(queue.front()->left);
                    if(queue.front()->right!=NULL)
                        queue.push_back(queue.front()->right);
                    queue.pop_front();
                    size--;
                }
                if(size==0){
                    size=queue.size();
                    result.insert (result.begin(),vec);
                    vec.clear();
                }
            }
        }
        return result;
    }

右向视图

vector<int> rightSideView(TreeNode *root) {
    vector<int> result;
    if(root==NULL)
        return result;
    int first=0;
    int second=0;
    queue<TreeNode*> Q;
    Q.push(root);
    first++;
    while(!Q.empty()){
        TreeNode *head=Q.front();
        Q.pop();
        first--;
        //cout<<first<<endl;
        if(head->left!=NULL){
            Q.push(head->left);
            second++;
        }
        if(head->right!=NULL){
            Q.push(head->right);
            second++;
        }
        if(first==0){
            result.push_back(head->val);
            first=second;
            second=0;
        }
    }
    return result;
}

实现字典树

class TrieNode {
public:
    int bitmap;
    vector<TrieNode *> children;
    // Initialize your data structure here.
    TrieNode() {
        bitmap=0;
    }
};

class Trie {
public:
    Trie() {
        root = new TrieNode();
    }

    // Inserts a word into the trie.
    void insert(string word) {
        TrieNode* temp=root;
        for(int i=0;i<word.length();i++){
            int offset=word[i]-'a';
            int index=0;
            int sum=0;
            while(index<offset){
                sum+=(temp->bitmap>>index)&0x01;
                index++;
            }
            if(temp->bitmap & 0x01<<offset){
                temp=(temp->children)[sum];
            }
            else{
                TrieNode* a=new TrieNode();
                temp->bitmap |= 0x01<<offset;
                temp->children.insert(temp->children.begin()+sum,a);
                temp=a;
            }
        }
        temp->bitmap |= 0x80000000;
    }

    // Returns if the word is in the trie.
    bool search(string word) {
        TrieNode* temp=root;
        for(int i=0;i<word.length();i++){
            int offset=word[i]-'a';
            int index=0;
            int sum=0;
            while(index<offset){
                sum+=(temp->bitmap>>index)&0x01;
                index++;
            }
            if(temp->bitmap & 0x01<<offset){
                temp=(temp->children)[sum];
            }
            else{
                return false;
            }
        }
        return (temp->bitmap & 0x80000000) !=0;
    }

    // Returns if there is any word in the trie
    // that starts with the given prefix.
    bool startsWith(string prefix) {
        TrieNode* temp=root;
        for(int i=0;i<prefix.length();i++){
            int offset=prefix[i]-'a';
            int index=0;
            int sum=0;
            while(index<offset){
                sum+=(temp->bitmap>>index)&0x01;
                index++;
            }
            if(temp->bitmap & 0x01<<offset){
                temp=(temp->children)[sum];
            }
            else{
                return false;
            }
        }
        return true;
    }

private:
    TrieNode* root;
};
0 0
原创粉丝点击