C++_树的经典算法

目录:

1.有序链表转换成平衡二叉树

2.二叉搜索树转化成有序双链表

3.判断是否为平衡二叉树

4.二叉树的最近公共祖先

1.有序链表转换成平衡二叉树


#include <iostream>
using namespace std;

struct ListNode{
    int val;
    ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
};

struct TreeNode{
    int val;
    TreeNode* left;
    TreeNode* right;
    TreeNode(int x) : val(x), left(NULL), right(NULL){}
};
/*有序链表转换成二叉搜索树*/
/*
TreeNode* sortedChild(ListNode* head, ListNode* tail){
    if(head == tail) return NULL;
    //快慢指针找出中间点
    ListNode* mid = head, *tmp = head;
    while(tmp != tail && tmp->next != tail){
        mid = mid->next;
        tmp = tmp->next->next;
    }
    //构造二叉树
    TreeNode* root = new TreeNode(mid->val);
    root->left = sortedChild(head, mid);
    root->right = sortedChild(mid->next, tail);
    return root;
}
TreeNode* sortedListToBST(ListNode* head){
    return sortedChild(head, NULL);
}
*/

/*另外一种解法*/
TreeNode* buildBST(ListNode* head, int start, int end){
    if(start > end) return NULL;
    int mid = (start + end) / 2;
    ListNode* cur = head;
    for(int i = start; i < mid; i++){
        cur = cur->next;
    }
    TreeNode* root = new TreeNode(cur->val);
    root->left = buildBST(head, start, mid - 1);
    root->right = buildBST(cur->next, mid + 1, end);
    return root;
}

TreeNode* sortedListToBST(ListNode* head){
    if(!head) return NULL;
    //计算单链表长度
    int len = 0;
    ListNode* cur = head;
    while(cur){
        len++;
        cur = cur->next;
    }
    return buildBST(head, 0, len - 1);
}

int main(){
    ListNode* node = new ListNode(0);
    node->next = new ListNode(1);
    node->next->next = new ListNode(2);
    TreeNode* t = sortedListToBST(node);
    cout<<t->val<<endl;
    cout<<t->left->val<<endl;
    cout<<t->right->val<<endl;
    return 0;
}

2.二叉搜索树转化成有序双链表


#include <iostream>
using namespace std;

struct TreeNode{
    int val;
    TreeNode* left;
    TreeNode* right;
    TreeNode(int x) : val(x), left(NULL), right(NULL){}
};
/*二叉搜索树转化成有序双链表*/
void tree2list_inorder(TreeNode* root, TreeNode*& prev){
    /*
    1.把左子树调整为双向链表;
    2.把根和左子树调整后的链表相连;
    3.调整右子树。
    */
    if(!root) return;
    TreeNode* cur = root;
    tree2list_inorder(cur->left, prev);
    if(prev){
        prev->right = cur;
    }
    cur->left = prev;
    prev = cur;
    tree2list_inorder(cur->right, prev);
}

TreeNode* tree2list(TreeNode* root){
    TreeNode* prev = NULL;
    if(root) tree2list_inorder(root, prev);
    while(root->left)  // 寻找链表的头
        root = root->left;
    return root;
}

int main(){
    TreeNode* node = new TreeNode(1);
    node->left = new TreeNode(0);
    node->right= new TreeNode(2);
    TreeNode* t = tree2list(node);
    cout<<t->val<<endl;
    cout<<t->right->val<<endl;
    cout<<t->right->right->val<<endl;
    return 0;
}

3.判断是否为平衡二叉树

#include <iostream>
using namespace std;

struct TreeNode{
    int val;
    TreeNode* left;
    TreeNode* right;
    TreeNode(int x) : val(x), left(NULL), right(NULL){}
};
/*判断二叉树是否是平衡二叉树*/
int depth(TreeNode* root){
    if(!root) return 0;
    return max(depth(root->left), depth(root->right)) + 1;
}
bool isBalance(TreeNode* root){
    if(!root) return true;
    if(abs(depth(root->left) - depth(root->right)) > 1) return false;
    else return isBalance(root->left) && isBalance(root->right);
}

int main(){
    TreeNode* node = new TreeNode(5);
    node->left = new TreeNode(6);
    node->right= new TreeNode(7);

    cout<<isBalance(node)<<endl;
    return 0;
}

4.二叉树的最近公共祖先

/*二叉搜索树的最近公共祖先*/
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q){
    if(root == NULL) return NULL;
    while (root){
        if(p->val > root->val && q->val > root->val)
            root = root->right;
        else if(p->val < root->val && q->val < root->val)
            root = root->left;
        else
            return root;
    }
}

/*二叉树的最近公共祖先(LCA)*/
TreeNode* _lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q){
    // 发现目标节点则返回值标记该子树发现了目标节点
    if(root == NULL || root == p || root == q) return root;
    // 分别查看左右子树是否有目标节点
    TreeNode* left = _lowestCommonAncestor(root->left,p,q);
    TreeNode* right = _lowestCommonAncestor(root->right,p,q);
    // 都不为空,左右子树都有目标节点,则公共祖先就是本身
    if(left != NULL && right != NULL) return root;
    // 发现了目标节点,则继续向上标记为该目标节点
    else return left == NULL ? right : left;
}

猜你喜欢

转载自blog.csdn.net/Gentlemanman/article/details/84786535