二叉树

1、二叉搜索树和双向链表

二叉搜索树结构:左子节点比根节点小,右子节点比根节点大

查找和插入的步骤类似,但是插入是失败的查找,它要找到一个空的左子结点或者右子结点。它们的算法复杂度都是O(logn),与二叉树的高度有关。即:较平衡的二叉树对应较低的复杂度。

因此,出现了AVL二叉搜索树,也就是对它的结构有了更严格的要求。它的任一子树,左子树和右子树的高度的绝对值之差不超过一。每个节点都可以用平衡因子这个指标,取正负1,0时,该节点是平衡的。

在删除某结点时,可能会破坏原有的结构,不再满足二叉搜索树的条件(通过平衡因子可以容易的判断出来),此时需要进行调整。

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

思路:就是二叉树的中序遍历

我用的递归法,返回的是链表的头部。

而在和根节点连接时,需要的是左子树的末尾和右子树的头部。

所以得到左子树返回的链表的头部后,需要一个while循环,得到这个链表的尾部。

一定要注意的是,这个循环结束后pleft这个变量不再是链表头部,所以一定要拷贝一下这个指到p变量中去。

当左子结点不存在时,根节点就是首部

TreeNode* p=pRootOfTree;
因此这个初值很关键。
class Solution {
public:
    TreeNode* Convert(TreeNode* pRootOfTree)
    {
        TreeNode* pleft=pRootOfTree;
        TreeNode* pright=pRootOfTree;
        TreeNode* p=pRootOfTree;
        if(pRootOfTree==NULL)
            return NULL;
        //if(pRootOfTree->left==NULL&&pRootOfTree->right==NULL)//叶节点
            //return pRootOfTree;
        if(pRootOfTree->left!=NULL)
        {
            pleft=Convert(pRootOfTree->left);
            p=pleft;
            while(pleft->right!=NULL)
            {
                pleft=pleft->right;
            }
            pleft->right=pRootOfTree;
            pRootOfTree->left = pleft;
        }
        if(pRootOfTree->right!=NULL)
        {
            pright=Convert(pRootOfTree->right);
            pright->left=pRootOfTree;
            pRootOfTree->right = pright;
        }
      
        return p;
    }
};

2、Huffman树

带权路径长度(计算公式如下)最小的二叉树:权值较大的放在离根节点较近的地方。


Wk为第k个叶子结点的权值;Lk为该结点的路径长度(与深度有关,离根节点较近,该值越小)。

这个和霍夫曼编码思想是一样的:出现频率大的码字对应短码,出现频率小的码字对应长码。码长对应路径长度。

在进行霍夫曼编码时,需要对原始数据扫描两次,第一遍得到每一个取值的频率;建立二叉树之后(小值优先的原则),第二遍扫描,编码。规定左子树为0,右子树1.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值