二叉树的一些功能

本文介绍了如何在二叉树中寻找指定值的祖先节点,判断一棵二叉树是否为完全二叉树,并详细展示了哈夫曼树的构建过程以及哈夫曼编码的生成方法。通过这些算法,可以有效地操作和压缩数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

//寻找值为x的节点的祖先节点
stack<BTNode *> FindAncestorsNode(BTNode *b, ElemType x) {
    BTNode *p = b, *r;
    stack<BTNode *> sq;
    bool flag;
    do {
        while (p != NULL) {
            sq.push(p);
            p = p->lchild;
        }
        r = NULL;
        flag = true;
        while (!sq.empty() && flag) {
            p = sq.top();
            if (p->rchild == r) {
                if (p->data == x) {
                    sq.pop();
                    return sq;
                } else {
                    sq.pop();
                }
                r = p;
            } else {
                p = p->rchild;
                flag = false;
            }
        }
    } while (!sq.empty());
    return sq;
}

//判别给定的二叉树是否为完全二叉树
//我们将二叉树中的结点和层次遍历一样加入到队列中,同时为空的用NULL加到队列中,
// 这样会发现完全二叉树所有的NULL会出现在非空结点的后面,这样我们就可以设计算法了
bool JudgeCompleteBinaryTree(BTNode *b) {
    BTNode *p;
    queue<BTNode *> q, sq;
    q.push(b);
    while (!q.empty()) {
        p = q.front();
        sq.push(p);
        q.pop();
        if (p != NULL) {
            q.push(p->lchild);
            q.push(p->rchild);
        }
    }//按层次遍历的方法将二叉树的节点输入队列中
    bool flag = false;//判断是否过了非空结点
    while (!sq.empty()) {
        p = sq.front();
        sq.pop();
        if (p == NULL)
            flag = true;
        if (p != NULL && flag)
            return false;
    }
    return true;
}

//线索二叉树
struct TBTNode {
    ElemType data;
    int ltag, rtag;
    TBTNode *lchild;
    TBTNode *rchile;
};

//哈夫曼树的构造
struct HTNode {
    char data;          //结点值
    double weight;      //权重
    int parent;         //双亲结点
    int lchild;         //左孩子结点
    int rchild;         //右孩子结点
};

//n0为叶子结点
void CreateHT(HTNode ht[], int n0) {
    int i, k, lnode, rnode;
    double min1, min2;
    //将ht[]初始化
    for (i = 0; i < 2 * n0 - 1; i++)
        ht[i].parent = ht[i].lchild = ht[i].rchild = -1;
    for (i = n0; i < 2 * n0 - 1; i++) {
        min1 = min2 = 32767;
        lnode = rnode = -1;
        for (k = 0; k < i; k++) {//找到权最小的两个
            if (ht[k].parent == -1) {
                if (ht[k].weight < min1) {
                    min2 = min1;
                    rnode = lnode;
                    min1 = ht[k].weight;
                    lnode = k;
                } else if (ht[k].weight < min2) {
                    rnode = k;
                    min2 = ht[k].weight;
                }
            }
        }
        //将两个权最小的合成
        ht[i].weight = min1 + min2;
        ht[i].rchild = rnode;
        ht[i].lchild = lnode;
        ht[lnode].parent = ht[rnode].parent = i;
    }
}

//哈夫曼编码
struct HCode {
    char cd[N];
    int start;
};

void CreateHCode(HTNode ht[], HCode hcd[], int n0) {
    int i, f, c;
    HCode hc;
    for (i = 0; i < n0; i++) {
        hc.start = n0;
        c = i;
        f = ht[i].parent;
        while (f != -1) {
            if (ht[f].lchild == c) {
                hc.cd[hc.start--] = '0';
                //cout << '0';
            } else {
                hc.cd[hc.start--] = '1';
                //cout << '1';
            }
            c = f;
            f = ht[f].parent;
        }
        hc.start++;
        hcd[i] = hc;
    }
}
void DisHTCode(HTNode ht[], HCode hcd[], int n0){
        for(int i=0;i<n0;i++){
            cout<<ht[i].data<<"的哈夫曼编码为:";
            for(int j=hcd[i].start;j<=n0;j++){
                cout<<hcd[i].cd[j];
            }
            cout<<endl;
        }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值