二叉树-创建、重建、转化

来源:互联网 发布:图哈切夫斯基 知乎 编辑:程序博客网 时间:2024/06/06 07:45

篇一:二叉树-遍历终极版
篇二:二叉树-创建、重建、转化
篇三:二叉树-详解二叉排序树
篇四:二叉树-详解平衡二叉树AVL
篇五:二叉树-常见简单算法题

对于二叉树的创建,一般我们只熟悉最简单的二叉树创建方式,即逐个输入节点,然后按照先序遍历或者中序、后序遍历方式来递归建立二叉树。但是,光掌握这个是不够的,我们还得掌握二叉树的重建(先序中序重建二叉树,后序中序重建二叉树),数组转换为二叉树,链表转换为二叉树等等。

1、最简单的创建方式

我们可以根据先序遍历递归创建二叉树,当然也可以中序或者后序遍历方式创建二叉树。

//创建二叉树BTress CreateTree(BTress &T){    char a;    cin>>a;    if(a=='0')        T=NULL;    else    {        T=new BNode();        T->data=a;        CreateTree(T->LChild);        CreateTree(T->RChild);    }    return T;}

2、根据前序序列和中序序列建二叉树

根据二叉树的前序后中序遍历的结果来重建二叉树。
前序:A B D E H I C F G
中序:D B H E I A F C G

怎么做了?注意,前序遍历第一个节点A肯定是根节点;那么,我们可以在中序遍历中找到这个根节点A,那么中序遍历中根节点A左边的点(D B H E I)就是A的左子树的节点,右边的点(F C G)就是A节点右子树的节点。再看前序遍历的节点B,对于节点B也是一样,中序遍历中根节点B左边的点(D)就是B的左子树的节点,右边的点(H E I)就是B节点右子树的节点………

根据上述这种思想递归下去,可以逐步找到每个点的位置,然后就可以将树建立起来,具体看代码(是leetcode上的题)

代码:

class Solution {public:    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder)     {        return buildTreeHelp(preorder,inorder,0,preorder.size()-1,0,inorder.size()-1);    }    TreeNode* buildTreeHelp(vector<int>& preorder, vector<int>& inorder,int pr_s,int pr_e,int in_s,int in_e)    {        if(pr_s>pr_e||in_s>in_e) return NULL;        int pivot=preorder[pr_s];        //找到在中序序列中的位置        int k=0;        for(int i=in_s;i<=in_e;i++)        {            if(inorder[i]==pivot)            {                k=i;                break;            }        }        TreeNode* node = new TreeNode(pivot);          node->left=buildTreeHelp(preorder,inorder,                                 pr_s+1, pr_s+(k-in_s),                                 in_s, k-1);        node->right=buildTreeHelp(preorder,inorder,                                   pr_s+(k-in_s)+1, pr_e,                                  k+1, in_e);        return node;    }};

3、根据后序序列和中序序列建二叉树

后续其实跟前序差不多,只不过是倒着来的,它是先右后左。

class Solution {public:    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder)     {        return buildTreeHelp(postorder,inorder,0,postorder.size()-1,0,inorder.size()-1);    }    TreeNode* buildTreeHelp(vector<int>& postorder, vector<int>& inorder,int po_s,int po_e,int in_s,int in_e)    {        if(po_s>po_e||in_s>in_e) return NULL;        int pivot=postorder[po_e];        int k=0;        for(int i=in_s;i<=in_e;i++)        {            if(inorder[i]==pivot)            {                k=i;                break;            }        }        TreeNode* node = new TreeNode(pivot);          node->left=buildTreeHelp(postorder,inorder,                                   po_s, po_s+k-in_s-1,                                  in_s, k-1);        node->right=buildTreeHelp(postorder,inorder,                                 po_e-(in_e-k), po_e-1,                                  k+1, in_e);        return node;    }};

4、将有序数组装换为平衡二叉树

既然是平衡二叉树,那么对于每个节点,都是左边的比自己小,右边的比自己大。因此思路就有了,每次确定节点时,就是中间的节点,这个有些像二分查找。

class Solution {public:    TreeNode* sortedArrayToBST(vector<int>& nums)     {        return generateBST(0,nums.size()-1,nums);    }    TreeNode* generateBST(int left,int right,vector<int>& nums)    {        if(left>right) return NULL;        int mid=(right+left)/2;        TreeNode*node=new TreeNode(nums[mid]);        node->left=generateBST(left,mid-1,nums);        node->right=generateBST(mid+1,right,nums);        return node;    }};

5、将有序链表转化为平衡二叉树

class Solution {public:    TreeNode* sortedListToBST(ListNode* head)    {        if(head==NULL) return NULL;        return toBST(head,NULL);    }    TreeNode* toBST(ListNode* head, ListNode* tail)    {        ListNode* slow = head;        ListNode* fast = head;        if(head==tail) return NULL;        while(fast!=tail&&fast->next!=tail)        {            fast = fast->next->next;            slow = slow->next;        }        TreeNode* thead = new TreeNode(slow->val);        thead->left = toBST(head,slow);        thead->right = toBST(slow->next,tail);        return thead;    }};
0 0
原创粉丝点击