c++数据结构-树(详细总结附代码,一看就懂)

树的定义

一棵树是由n(n>0)个元素组成的有限集合,其中:

(1)每个元素称为结点(node)

(2)有一个特定的结点,称为根结点或树根(root)

(3)除根节点外,其余节点能分成m(m>=0)个互不相交的有限集合 T(0)-T(m-1)。其中的每一个子集都是一个树,这些集合被称为这棵树的子树。

如下图是一棵树:

树的基本概念

A. 树是由递归定义的

B. 一棵树中至少有1个结点。这个节点就是根节点,他没有前驱,其余每个节点都有且只有一个前驱节点。每个节点可以有任意个后继结点。因此,树是非线性结构,但也是有序结构。

C. 一个节点的子树个数称为这个结点的度,例如上图根节点的度为2。度为0的结点被称为叶结点;度不为0的结点被称为分支结点,根以外的分支节点称为内部结点,树中各节点的度的最大值称为这棵树的度。

D. 在用图形表示的树形结构中,对两个用线段(我们称为树枝)连接的相关联的结点,称上端结点为下端节点的父节点,反之为子节点。

E. 定义一棵树的根的层次为1,其他结点的层次等于他的父节点的层次加一。一棵树中所有节点的层次的最大值称为这棵树的深度。

F. 对于树中任意两个不同的结点,从一个结点出发一定能到达另一个结点。

G.m(m>=0)棵树的结合称为森林。

树的遍历

在解决问题时,常常要按照某种次序来获取树中全部节点的信息,这种操作叫做树的遍历。

A. 先序遍历 先访问根节点,然后按照左右先后顺序遍历各子树(根左右)

B. 中序遍历 先访问左子树,然后访问根,最后访问右子树(左根右)

C. 层次遍历 按层次的大笑从小到大遍历,同一层次按照从左到右的顺序。

二叉树基本概念

二叉树(binary tree,简称BT),是一种特殊的树,它的度是2。一个节点有两个子节点,其中左边的是左子节点,右边的是右子节点。左边的叫左子树,右边的叫右子树。

二叉树的性质

(1)在二叉树的第 i 层上最多有 个结点(i>=1)

(2)深度为 k 的二叉树至多有 个结点(k>=1)

特别的,深度为 k ,且有 个结点的二叉树称为满二叉树。

(3)对于任意一棵二叉树,如果其叶子结点数为 ,度为 2 的结点数为 ,那么

(4)具有 n 个结点的完全二叉树的深度为

二叉树的实现

上面我们介绍了树和二叉树,那么我们现在研究一下二叉树的实现,注意,这里默认你有一些 C++ 基础。

首先我们来创建一个二叉树结点类 BSTNode,然后在类中创建几个 BSTNode 类型的变量,值,左子节点,右子节点,父节点。

int _key;  
BSTNode *_left;  //左子节点
BSTNode *_right; //右子节点
BSTNode *_parent;  //父节点

然后我们初始化,这里使用列表初始化。

BSTNode(int k = 0, BSTNode *l = NULL, BSTNode *r = NULL, BSTNode *p = NULL) : _key(k), _left(l), _right(r), _parent(p) {};

接下来,我们来创建一个二叉树类 BinaryTree ,来写二叉树的各种操作函数。

我们先声明函数

void insert(int _key);  //将_key节点插入到二叉树中
void PreOrder();  //前序二叉树遍历
void InOrder();  //中序二叉树遍历
void PostOrder();  //后序二叉树遍历

BSTNode *search(int _key);  //递归实现,在二叉树中查找_key节点
BSTNode *IteratorSearch(int _key);  //迭代实现,在二叉树中查找_key节点

BSTNode *successor(BSTNode *x);  //找节点(x)的后继节点。即,查找"二叉树中数据值大于该节点"的"最小节点"
BSTNode *predecessor(BSTNode *x);  //找节点(x)的前驱节点。即,查找"二叉树中数据值小于该节点"的"最大节点"

void remove(int _key);  //删除_key节点

void destroy();  //销毁二叉树

这里包括了二叉树的基本操作。

类的private部分:

BSTNode *_root;  //根节点
void PreOrder(BSTNode *tree); //前序二叉树遍历
void InOrder(BSTNode *tree);  //中序二叉树遍历
void PostOrder(BSTNode *tree);  //后序二叉树遍历

BSTNode *search(BSTNode *x, int _key);  //递归实现,在”二叉树x“中查找_key节点
BSTNode *IteratorSearch(BSTNode *x, int _key);  //迭代实现,在“二叉树x”中查找_key节点

BSTNode *minimum(BSTNode *tree);  //查找最小节点:返回tree为根节点的二叉树的最小节点
BSTNode *maximum(BSTNode *tree);  //查找最大节点:返回tree为根节点的二叉树的最大节点

void insert(BSTNode *&tree, BSTNode *z);  // 将节点(z)插入到二叉树(tree)中

BSTNode *remove(BSTNode *tree, BSTNode *z);  // 删除二叉树(tree)中的节点(z),并返回被删除的节点

void destroy(BSTNode *&tree);  //销毁二叉树

也是声明了一些函数。

插入元素

void BinaryTree::insert(int _key)  //将_key节点插入到二叉树中
{
    BSTNode *z = new BSTNode(_key, NULL, NULL, NULL);
    if (z == NULL)
    {
        return;  
    }
    insert(_root, z); 
}
void BinaryTree::insert(BSTNode *&tree, BSTNode *z)  // 将节点(z)插入到二叉树(tree)中
{
    BSTNode *y = NULL;
    BSTNode *x = tree;
 
    while (x != NULL) 
    {
        y = x;
        if (z->_key < x->_key)
        {
            x = x->_left;
        }
        else
        {
            x = x->_right;
        }
    }
 
    z->_parent = y;
    if (y == NULL)
    {
        tree = z;
    }
    else
        if (z->_key < y->_key)
        {
            y->_left = z;
        }
        else
        {
            y->_right = z;
        }
}

首先创建一个结点,如果节点的值(key)是空(NULL)的话就结束函数,如果不为空的话就执行insert函数。insert函数的内容是循环树只要不为空,按照树的顺序找到合适的位置插入元素。

删除结点

BSTNode *BinaryTree::remove(BSTNode *tree, BSTNode *z)  // 删除二叉树(tree)中的节点(z),并返回被删除的节点
{
    BSTNode *x = NULL;
    BSTNode *y = NULL;
 
    if (z->_left == NULL || z->_right == NULL)
    {
        y = z;
    }
    else
    {
        y = successor(z);
    }
 
    if (y->_left != NULL)
    {
        x = y->_left;
    }
    else
    {
        x = y->_right;
    }
 
    if (x != NULL)
    {
        x->_parent = y->_parent;
    }
 
    if (y->_parent == NULL)
    {
        tree = x;
    }
    else
        if (y == y->_parent->_left)
        {
            y->_parent->_left = x;
        }
        else
        {
            y->_parent->_right = x;
        }
 
    if (y != z)
    {
        z->_key = y->_key;
    }
    return y;
}
void BinaryTree::remove(int _key)  // 删除二叉树(tree)中的节点(z),并返回被删除的节点
{
    BSTNode *z, *node;
    z = IteratorSearch(_root, _key); 
    if (z == _root){
        cout<<"Root can't be delete!"<<endl;
    }
    if (z != NULL && z->_parent != NULL && z != _root)
    {
        node = remove(_root, z);  
        if (node != NULL)
        {
            delete node;
        }
    }
}

销毁二叉树

void BinaryTree::destroy(BSTNode *&tree)  //销毁二叉树
{
    if (tree == NULL)
    {
        return; 
    }
    if (tree->_left != NULL)
    {
        return destroy(tree->_left);
    }
    if (tree->_right != NULL)
    {
        return destroy(tree->_right);
    }
    delete tree;
    tree = NULL;
}
 
 
void BinaryTree::destroy()  //销毁二叉树
{
    destroy(_root);
}

完整代码

/*
    文件创建者: 112233-星澜-imimbert
    创建日期: 2023.1.12 12:33
    功能: 二叉树
*/
#include <iostream>
using namespace std;
 
class BSTNode
{
public:
    int _key;  
    BSTNode *_left;  //左子节点
    BSTNode *_right; //右子节点
    BSTNode *_parent;  //父节点
     
    BSTNode(int k = 0, BSTNode *l = NULL, BSTNode *r = NULL, BSTNode *p = NULL) : _key(k), _left(l), _right(r), _parent(p) {};  //初始化列表
};
 
 
class BinaryTree
{
/****
    * @author 112233-imimbert-星澜
    * @since -verson: 1.0.0
    * @date 2021-01-12
    * @pre 二叉树已经创建
    * @include iostream
****/
public:
    BinaryTree();  
    ~BinaryTree();  
 
    void insert(int _key);  //将_key节点插入到二叉树中
    void PreOrder();  //前序二叉树遍历
    void InOrder();  //中序二叉树遍历
    void PostOrder();  //后序二叉树遍历
 
    BSTNode *search(int _key);  //递归实现,在二叉树中查找_key节点
    BSTNode *IteratorSearch(int _key);  //迭代实现,在二叉树中查找_key节点
 
    BSTNode *successor(BSTNode *x);  //找节点(x)的后继节点。即,查找"二叉树中数据值大于该节点"的"最小节点"
    BSTNode *predecessor(BSTNode *x);  //找节点(x)的前驱节点。即,查找"二叉树中数据值小于该节点"的"最大节点"
 
    void remove(int _key);  //删除_key节点
 
    void destroy();  //销毁二叉树
 
 
private:
    BSTNode *_root;  //根节点
    void PreOrder(BSTNode *tree);  //前序二叉树遍历
    void InOrder(BSTNode *tree);  //中序二叉树遍历
    void PostOrder(BSTNode *tree);  //后序二叉树遍历
 
    BSTNode *search(BSTNode *x, int _key);  //递归实现,在”二叉树x“中查找_key节点
    BSTNode *IteratorSearch(BSTNode *x, int _key);  //迭代实现,在“二叉树x”中查找_key节点
 
    BSTNode *minimum(BSTNode *tree);  //查找最小节点:返回tree为根节点的二叉树的最小节点
    BSTNode *maximum(BSTNode *tree);  //查找最大节点:返回tree为根节点的二叉树的最大节点
 
    void insert(BSTNode *&tree, BSTNode *z);  // 将节点(z)插入到二叉树(tree)中
 
    BSTNode *remove(BSTNode *tree, BSTNode *z);  // 删除二叉树(tree)中的节点(z),并返回被删除的节点
 
    void destroy(BSTNode *&tree);  //销毁二叉树
};

 
BinaryTree::BinaryTree() :_root(NULL) {}; 
 
BinaryTree::~BinaryTree() 
{
    destroy();
}
 
 
void BinaryTree::insert(int _key)  //将_key节点插入到二叉树中
{
    BSTNode *z = new BSTNode(_key, NULL, NULL, NULL);
    if (z == NULL)
    {
        return;  
    }
    insert(_root, z); 
}
 
 
void BinaryTree::PreOrder(BSTNode *tree)  //前序二叉树遍历
{
    if (tree != NULL)
    {
        cout << tree->_key << " ";
        PreOrder(tree->_left);
        PreOrder(tree->_right);
    }
}
void BinaryTree::PreOrder()
{
    PreOrder(_root); 
}
 
 
void BinaryTree::InOrder(BSTNode *tree)  //中序二叉树遍历
{
    if (tree != NULL)
    {
        InOrder(tree->_left);
        cout << tree->_key << " ";
        InOrder(tree->_right);
    }
}
void BinaryTree::InOrder()
{
    InOrder(_root);  
}
void BinaryTree::PostOrder(BSTNode *tree)  //后序二叉树遍历
{
    if (tree != NULL)
    {
        PostOrder(tree->_left);
        PostOrder(tree->_right);
        cout << tree->_key << " ";
    }
}
void BinaryTree::PostOrder()
{
    PostOrder(_root);  
}
BSTNode *BinaryTree::search(BSTNode *x, int _key)  //递归实现,在”二叉树x“中查找_key节点
{
    if (x == NULL || _key == x->_key)
    {
        return x;
    }
    if (_key < x->_key)
    {
        return search(x->_left, _key);
    }
    else
    {
        return search(x->_right, _key);
    }
}
BSTNode *BinaryTree::search(int _key)
{
    return search(_root, _key);  
}
BSTNode *BinaryTree::IteratorSearch(BSTNode *x, int _key)  //迭代实现,在“二叉树x”中查找_key节点
{
    while (x != NULL && _key != x->_key)
    {
        if (_key < x->_key)
        {
            x = x->_left;
        }
        else
        {
            x = x->_right;
        }
    }
    return x;
}
BSTNode *BinaryTree::IteratorSearch(int _key)
{
    return IteratorSearch(_root, _key);  //传入根节点和待查找的关键字_key
}
BSTNode *BinaryTree::minimum(BSTNode *tree)  //查找最小节点:返回tree为根节点的二叉树的最小节点。
{
    if (tree == NULL)
    {
        return NULL;
    }
    while (tree->_left != NULL)
    {
        tree = tree->_left;
    }
    return tree;
}

BSTNode *BinaryTree::maximum(BSTNode *tree)  //查找最大节点:返回tree为根节点的二叉树的最大节点。
{
    while (tree->_right != NULL)
    {
        tree = tree->_right;
    }
    return tree;
}
BSTNode *BinaryTree::successor(BSTNode *x)  //找节点(x)的后继节点,也就是该节点的右子树中的最小节点
{
    BSTNode *y = NULL;
    if (x->_right != NULL)
    {
        return minimum(x->_right);  
    }
    y  = x->_parent;
    while (y != NULL && x == y->_right)
    {
        x = y;
        y = y->_parent;
    }
    return y;
}
 
 
BSTNode *BinaryTree::predecessor(BSTNode *x)  //找节点(x)的前驱节点是该节点的左子树中的最大节点。
{
    BSTNode *y = NULL;
    if (x->_left != NULL)
    {
        return maximum(x->_left);
    }
    y = x->_parent;
    while (y != NULL && x == y->_left)
    {
        x = y;
        y = y->_parent;
    }
    return y;
}
 
 
void BinaryTree::insert(BSTNode *&tree, BSTNode *z)  // 将节点(z)插入到二叉树(tree)中
{
    BSTNode *y = NULL;
    BSTNode *x = tree;
 
    while (x != NULL) 
    {
        y = x;
        if (z->_key < x->_key)
        {
            x = x->_left;
        }
        else
        {
            x = x->_right;
        }
    }
 
    z->_parent = y;
    if (y == NULL)
    {
        tree = z;
    }
    else
        if (z->_key < y->_key)
        {
            y->_left = z;
        }
        else
        {
            y->_right = z;
        }
}
 
 
BSTNode *BinaryTree::remove(BSTNode *tree, BSTNode *z)  // 删除二叉树(tree)中的节点(z),并返回被删除的节点
{
    BSTNode *x = NULL;
    BSTNode *y = NULL;
 
    if (z->_left == NULL || z->_right == NULL)
    {
        y = z;
    }
    else
    {
        y = successor(z);
    }
 
    if (y->_left != NULL)
    {
        x = y->_left;
    }
    else
    {
        x = y->_right;
    }
 
    if (x != NULL)
    {
        x->_parent = y->_parent;
    }
 
    if (y->_parent == NULL)
    {
        tree = x;
    }
    else
        if (y == y->_parent->_left)
        {
            y->_parent->_left = x;
        }
        else
        {
            y->_parent->_right = x;
        }
 
    if (y != z)
    {
        z->_key = y->_key;
    }
    return y;
}
 
 
void BinaryTree::remove(int _key)  // 删除二叉树(tree)中的节点(z),并返回被删除的节点
{
    BSTNode *z, *node;
    z = IteratorSearch(_root, _key); 
    if (z == _root){
        cout<<"Root can't be delete!"<<endl;
    }
    if (z != NULL && z->_parent != NULL && z != _root)
    {
        node = remove(_root, z);  
        if (node != NULL)
        {
            delete node;
        }
    }
}
 
 
void BinaryTree::destroy(BSTNode *&tree)  //销毁二叉树
{
    if (tree == NULL)
    {
        return; 
    }
    if (tree->_left != NULL)
    {
        return destroy(tree->_left);
    }
    if (tree->_right != NULL)
    {
        return destroy(tree->_right);
    }
    delete tree;
    tree = NULL;
}
 
 
void BinaryTree::destroy()  //销毁二叉树
{
    destroy(_root);
}


int main()
{
    /************************/
    /*          插入
    /************************/
    BinaryTree *tree = new BinaryTree();
    int array[6] = {12, 33, 18, 24, 44, 66};
    cout << "二叉树数值:" << endl;
    for (int i = 0; i < 6; i++)
    {
        cout << array[i] << " ";
        tree->insert(array[i]);  //调用插入函数,生成二叉查找树
    }
 
    cout << endl << endl;
 
 
    /************************/
    /*          遍历           
    /************************/
    cout << "前序遍历:";
    tree->PreOrder();
    cout << endl;
 
    cout << "中序遍历:";
    tree->InOrder();
    cout << endl;
 
    cout << "后序遍历:";
    tree->PostOrder();
    cout << endl << endl;
 
 
    /************************/
    /*          查找           
    /************************/
    int _keyword;  //查找节点的关键字
    cout << "请输入要查找的节点:";
    cin >> _keyword;
    cout << endl;
    BSTNode *node = tree->IteratorSearch(_keyword);  //获取数值的地址
    if (node)  //判断有没有地址
    {
        cout << "关键字为“" << _keyword << "”的节点,存在。" << endl ;
    }
    else
    {
        cout << "关键字为“" << _keyword << "”的节点,不存在。" << endl;
    }
    cout << endl << endl;
 
 
    /************************/
    /*          删除
    /************************/
    int DelNode;  //要删除的节点
    cout << "请输入要删除的节点:";
    cin >> DelNode;
    tree->remove(DelNode);
    cout << endl;
 
    cout << "删除操作后,(前序)遍历:";
    tree->PreOrder();
    cout << endl;
    cout << "删除操作后,(中序)遍历:";
    tree->InOrder();
    cout << endl;
    cout << "删除操作后,(后序)遍历:";
    tree->PostOrder();
    cout << endl << endl;
    
 
    /************************/
    /*          销毁
    /************************/
    tree->destroy();
    system("pause");
    return 0;
}

猜你喜欢

转载自blog.csdn.net/m0_64036070/article/details/128734095
今日推荐