二叉树C++ Version

本文介绍了一种二叉排序树的基本操作实现方法,包括插入、查找和删除节点等核心功能,并通过C++代码示例展示了这些算法的具体实现过程。

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

#include <iostream.h>
#include <cstring>

typedef int KeyType;
#define NUM 11
class BinStree;
class BinSTreeNode
{
public:
    KeyType key;
    BinSTreeNode *lchild;
    BinSTreeNode *rchild;
    BinSTreeNode()
    {
        lchild = NULL;
        rchild = NULL;
    }
};

class BinSTree
{
public:
    BinSTreeNode *root;
    BinSTree()
    {
        root = NULL;
    }
    ~BinSTree()
    {
        //delete root;
    }
    BinSTreeNode *BSTreeSearch( BinSTreeNode *bt, KeyType k, BinSTreeNode *&p );
    void BSTreeInsert( BinSTreeNode *&bt, KeyType k );
    int BSTreeDelete( BinSTreeNode *&bt, KeyType k );
    void BSTreePreOrder(BinSTreeNode *bt);
    bool IsEmpty()
    {
        return root == NULL;
    }
};

/**
  *  二叉树排序查找算法
  *  在根指针为bt的二叉排序树中查找元素k的节点,若查找成功,则返回指向该节点的指针
  *  参数p指向查找到的结点,否则返回空指针,参数p指向k应插入的父结点
  */
BinSTreeNode* BinSTree::BSTreeSearch( BinSTreeNode *bt, KeyType k, BinSTreeNode *&p )
{
    BinSTreeNode *q = NULL;
    q = bt;
    while(q)
    {
        p = q;
        if( q->key == k )
        {
            return(p);
        }
        if( q->key > k )
            q = q->lchild;
        else
            q = q->rchild;
    }
    return NULL;
}

/**
  *  二叉排序树的插入节点算法
  *  bt指向二叉排序树的根结点,插入元素k的结点
  */
void BinSTree::BSTreeInsert( BinSTreeNode *&bt, KeyType k )
{
    BinSTreeNode *p = NULL, *q;
    q = bt;
    if( BSTreeSearch( q, k, p ) == NULL )
    {
        BinSTreeNode *r = new BinSTreeNode;
        r->key = k;
        r->lchild = r->rchild = NULL;
        if( q == NULL )//这里的q代表的bt,不是search函数里面的q
        {
            bt = r;         //被插入节点做为树的根节点
        }
        if( p && k < p->key )
            p->lchild = r;
        else if( p )
            p->rchild = r;
    }
}
/**
 * 中序遍历 
 */ 
void BinSTree::BSTreePreOrder(BinSTreeNode *bt)
{
    if(bt != NULL)
    {
        cout << bt->key << " ";
        BSTreePreOrder(bt->lchild);
        BSTreePreOrder(bt->rchild);
    }
}
/**
  * 二叉排序树的删除结点算法
  * 在二叉排序树中删除元素为k的结点,*bt指向二叉排序树的根节点
  * 删除成功返回1,不成功返回0.
  */
int BinSTree::BSTreeDelete( BinSTreeNode *&bt, KeyType k )
{
    BinSTreeNode *f, *p, *q, *s;
    p = bt;
    f = NULL;
    //查找关键字为k的结点,同时将此结点的双亲找出来
    while( p && p->key != k )
    {
        f = p;
        if( p->key > k )
            p = p->lchild;
        else
            p = p->rchild;
    }
    if( p == NULL )   //找不到待删除的结点时返回
        return 0;
    if( p->lchild == NULL )  //待删除结点的左子树为空
    {
        if( f == NULL )  //待删除结点为根节点
            bt = p->rchild;
        else if( f->lchild == p )  //待删结点是其双亲结点的左节点
            f->lchild = p->rchild;
        else
            f->rchild = p->rchild;  //待删结点是其双亲结点的右节点
        delete p;
    }
    else                    //待删除结点有左子树
    {
        q = p;
        s = p->lchild;
        while( s->rchild )  //在待删除结点的左子树中查找最右下结点
        {
            q = s;
            s = s->rchild;
        }
        if( q == p )
            q->lchild = s->lchild;
        else
            q->rchild = s->lchild;

        p->key = s->key;
        delete s;
    }
    return 1;
}
int main( void )
{
    int a[NUM] = { 34, 18, 76, 13, 52, 82, 16, 67, 58, 73, 72 };
    int i;
    BinSTree bst;
    BinSTreeNode *pBt = NULL, *p = NULL, *pT = NULL;

    for( i = 0; i < NUM; i++ )
    {
        bst.BSTreeInsert( pBt, a[i] ); //创建二叉排序树
    }
    pT = bst.BSTreeSearch( pBt, 52, p ); //搜索排序二叉树
    bst.BSTreePreOrder(pBt);
    cout << endl;
    bst.BSTreeDelete( pBt, 13 );   //删除无左孩子的情况
    bst.BSTreePreOrder(pBt);
    cout << endl;
    bst.BSTreeDelete( pBt, 76 );   //删除有左孩子的情况
    bst.BSTreePreOrder(pBt);
    cout << endl;
    return 0;
}



注意:? *& bt 和 *bt 和&bt的不同。

### 最优二叉树 最优二叉树通常指的是哈夫曼树,这是一种带权路径长度最短的二叉树。其构建目的是为了最小化访问各个节点所需的总成本。 #### 哈夫曼树的特点 - 对于给定的一组带有权重(频率)的数据项,通过特定算法可以构造一棵具有最小加权外部路径长度的二叉树。 - 这种类型的树广泛应用于文件压缩领域,如Huffman编码方案中[^2]。 #### 构建过程 要创建一个哈夫曼树,一般遵循如下逻辑: 1. 初始化森林F={T_1,T_2,...,T_n},其中每个Ti只含一个根节点i; 2. 在所有可能的选择中挑选两棵拥有最小权重的独立树作为新的内部节点的孩子,并将其组合成更大的子树; 3. 将新形成的较大子树重新加入到剩余未处理树木集合当中; 4. 重复上述两个步骤直到只剩下一棵树为止。 ```cpp // C++ code snippet to build Huffman tree (simplified version) struct MinHeapNode { char data; unsigned freq; struct MinHeapNode *left, *right; }; struct MinHeap { unsigned size; unsigned capacity; struct MinHeapNode **array; }; ``` --- ### 线索二叉树 线索二叉树是在标准二叉链表表示的基础上改进而来的一种特殊形式的二叉树结构。它旨在解决传统二叉树遍历时效率低下的问题,特别是当遇到大量叶节点时会存在大量的空链接浪费资源的情况。 #### 主要特性 - 当某个节点p不存在左(右)孩子,则让它的前置(predecessor)/后继(successor)指向该位置来代替原来的NULL值; - 此外还需要增加额外标志位用来区分是指向实际孩子的指针还是已经进行了线索化的指示器[^3]。 #### 结构定义 这里给出一种简单的实现方式,使用布尔变量`isThreadedLeft` 和 `isThreadedRight` 来标记是否为线索连接而非真实子节点关系: ```c++ typedef enum { Link, Thread } PointerTag; template<typename T> class ThreadingBinaryTreeNode { public: T value; bool isThreadedLeft : 1; bool isThreadedRight : 1; ThreadingBinaryTreeNode<T>* leftChildOrPredecessor; ThreadingBinaryTreeNode<T>* rightChildOrSuccessor; // Constructor and other methods... }; ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值