二叉树

这篇博客介绍了二叉树的定义,包括其特殊性质——每个节点最多有两个子节点。文章详细讲解了如何构造二叉树,并通过结构体表示节点。接着,文章探讨了二叉树的四种遍历方式:前序、中序和后序的递归与非递归实现,举例展示了不同遍历顺序。

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

二叉树是一棵特殊的树,它最多有两个孩子结点,左孩子和右孩子
1.建立二叉树
二叉树一个结点指针所指向的内容包含三项,该结点的值,指向左孩子的指针和指向右孩子的指针。所以需要建立一个结构体包含这三项内容

struct BinaryTreeNode
{
    BinaryTreeNode<T> *_left;//左孩子
    BinaryTreeNode<T> *_right;//右孩子
    T _data;
    BinaryTreeNode(const T& x)
        :_left(NULL)
        , _right(NULL)
        ,_data(x)
    {}
};

构造二叉树可以使用递归的方法来构造

BinaryTree(T* a, size_t n, T invalid)
{
    int index = 0;
    _root = CreateTree(a,n,invalid,index);
}
Node* CreateTree(T* a, int n, T invalid, int& index)
{
    Node* root = NULL;
    if (index < n&&a[index] != invalid)
    {
        root = new Node(a[index]);
        root->_left = CreateTree(a, n, invalid, ++index);//用递归创建子树
        root->_right = CreateTree(a, n, invalid, ++index);
    }
    return root;
}

2.二叉树创建后要实现一些功能
2.1 前序二叉树(递归)
先访问头结点,再访问左孩子,最后访问右孩子
这里写图片描述
该图的遍历顺序应为1 2 3 4 5 6 7

void _PrevOrder(Node* root)
    {

        if (root != NULL)
        {
            cout << root->_data << " ";//先遍历打印根节点
            _PrevOrder(root->_left);   //再遍历左子树
            _PrevOrder(root->_right);  //最后遍历右子树
        }
    }

2.2 前序二叉树(非递归)

void PrevOrderNonR()
    {
        Node* cur = _root;
        stack<Node*> s;
        while (cur || !s.empty())
        {
            while (cur)
            {
                s.push(cur);
                cout << cur->_data << " ";
                cur = cur->_left;
            }
            Node *top = s.top();
            s.pop();
            cur = top->_right;
        }
        cout << endl;
    }

2.3 中序二叉树(递归)
遍历顺序应为3 2 4 1 7 6 5

void _InOrder(Node* root)
    {
        if (root != NULL)
        {
            _InOrder(root->_left);//先遍历左子树
            cout << root->_data << " ";//再遍历打印根节点
            _InOrder(root->_right);//最后遍历右子树
        }
    }

2.4 中序二叉树(非递归)

void InOrderNonR()
    {
        Node* cur = _root;
        stack<Node*> s;
        while (cur || !s.empty())
        {
            while (cur->_left)
            {
                s.push(cur);
                cur = cur->_left;
            }
            cout << cur->_data << " ";
            Node *top = s.top();

            cout << top->_data << " ";
            s.pop();
            cur = top->_right;
        }
        cout << endl;
    }

2.5 后序二叉树(递归)
遍历顺序应为3 4 2 7 6 5 1

void _PostOrder(Node* root)
    {
        if (root != NULL)
        {
            _PostOrder(root->_left);
            _PostOrder(root->_right);
            cout << root->_data << " ";
        }
    }

2.6 后序二叉树(非递归)

void PostOrderNonR()
    {
        if (_root == NULL)
            return;
        stack<Node*> s;
        Node* cur = _root;
        Node* previsited = NULL;//前一个遍历的结点
        while (cur || !s.empty())
        {
            while (cur)
            {
                s.push(cur);
                cur = cur->_left;
            }
            Node* top = s.top();
            cur = top->_right;
            if (cur == NULL || cur == previsited)
            {
                cout << top->_data << " ";
                previsited = top;
                s.pop();
                cur = NULL;
            }
        }
        cout << endl;
    }

二叉树的基本功能

#pragma once
#include<iostream>
#include<queue>
#include<assert.h>
#include<stack>

using namespace std;
template<class T>

struct BinaryTreeNode
{
    BinaryTreeNode<T> *_left;
    BinaryTreeNode<T> *_right;
    T _data;
    BinaryTreeNode(const T& x)
        :_left(NULL)
        , _right(NULL)
        ,_data(x)
    {}
};

template<class T>

class BinaryTree
{
    typedef BinaryTreeNode<T> Node;
public:
    BinaryTree()
        :_root(NULL)
    {}
    BinaryTree(T* a, size_t n, T invalid)
    {
        int index = 0;
        _root = CreateTree(a,n,invalid,index);
    }
    Node* CreateTree(T* a, int n, T invalid, int& index)
    {
        Node* root = NULL;
        if (index < n&&a[index] != invalid)
        {
            root = new Node(a[index]);
            root->_left = CreateTree(a, n, invalid, ++index);
            root->_right = CreateTree(a, n, invalid, ++index);
        }
        return root;
    }

    ~BinaryTree()
    {
        _Destory(_root);
    }
    void PrevOrder()
    {
        _PrevOrder(_root);
        cout << endl;
    }

    void InOrder()
    {
        _InOrder(_root);
        cout << endl;
    }

    void PostOrder()
    {
        _PostOrder(_root);
        cout << endl;
    }
    size_t Size()
    {
        int count = 0;
        _Size(_root,count);
        return count;
    }

    size_t GetLeafSize()
    {
        size_t count = 0;
        _GetLeafSize(_root,count);
        return count;
    }
    size_t GetKlevelSize(size_t k)
    {
        return _GetKlevelSize(_root,k);
    }

    size_t Depth()
    {
        return _Depth(_root);
    }

    Node* Find(const T& x)
    {
        return _Find(x, _root);
    }

    void PrevOrderNonR()
    {
        Node* cur = _root;
        stack<Node*> s;
        while (cur || !s.empty())
        {
            while (cur)
            {
                s.push(cur);
                cout << cur->_data << " ";
                cur = cur->_left;
            }
            Node *top = s.top();
            s.pop();
            cur = top->_right;
        }
        cout << endl;
    }

    void InOrderNonR()
    {
        Node* cur = _root;
        stack<Node*> s;
        while (cur || !s.empty())
        {
            while (cur->_left)
            {
                s.push(cur);
                cur = cur->_left;
            }
            cout << cur->_data << " ";
            Node *top = s.top();

            cout << top->_data << " ";
            s.pop();
            cur = top->_right;
        }
        cout << endl;
    }
    void PostOrderNonR()
    {
        Node* cur = _root;
        stack<Node*> s;
        while (cur || !s.empty())
        {
            while (cur->_left)
            {
                s.push(cur);
                cur = cur->_left;
            }


            while (cur->_right)
            {

                s.push(cur);
                cur = cur->_right;
            }

            cout << cur->_data << " ";
            cur = s.top();
            s.pop();
            cur = cur->_right;

        }
        cout << endl;
    }
void _levelOrder()
    {
        _levelOrder(_root);
        cout << endl;
    }

protected:
    Node* _root;
    void _PrevOrder(Node* root)
    {

        if (root != NULL)
        {
            cout << root->_data << " ";
            _PrevOrder(root->_left);
            _PrevOrder(root->_right);
        }
    }

    void _InOrder(Node* root)
    {
        if (root != NULL)
        {
            _InOrder(root->_left);
            cout << root->_data << " ";
            _InOrder(root->_right);
        }
    }

    void _PostOrder(Node* root)
    {
        if (root != NULL)
        {
            _PostOrder(root->_left);
            _PostOrder(root->_right);
            cout << root->_data << " ";
        }
    }
    size_t _Size(Node* root, int& count)  //二插树的结点个数
    {
        if (root != NULL)
        {
            count++;
            _Size(root->_left,count);
            _Size(root->_right,count);
        }
        return count;
    }
    size_t _GetLeafSize(Node* root, size_t& count)//叶子结点的个数
    {
        if (root != NULL)
        {
            if (root->_left == NULL&&root->_right == NULL)
            {
                count++;
            }
            _GetLeafSize(root->_left, count);
            _GetLeafSize(root->_right, count);
        }
        return count;
    }
    //第K层结点的个数
    size_t _GetKlevelSize(Node*root,size_t k)
    {
        if (root != NULL)
        {
            if (k == 1)
                return 1;
            return _GetKlevelSize(root->_left,k-1) + _GetKlevelSize(root->_right,k-1);
        }
        return 0;
    }
    //二叉树的深度
    size_t _Depth(Node* root)
    {
        if (root == NULL)
            return 0;
        int left=_Depth(root->_left)+1;
        int right=_Depth(root->_right)+1;
        return left > right ? left:right;
    }

    //查找某一个结点
    Node* _Find(const T& x,Node* root)
    {
        if (root == NULL)
            return NULL;
        if (root->_data == x)
            return root;
        Node* left = _Find( x,root->_left);
        if (left)
            return left;
        return _Find(x,root->_right);
    }

    //删除某个结点
    void _Destory(Node* root)
    {
        if (root == NULL)
            return;
        _Destory(root->_left);
        _Destory(root->_right);
        delete root;
    }
//层序遍历
    void _levelOrder(Node* root)
    {
        if (root == NULL)
            return;
        queue<Node*> q;
        q.push(root);

        while (!q.empty())
        {
            Node* front = q.front();
            cout << front->_data << " ";

            if (front->_left!=NULL)
                q.push(front->_left);
            if (front->_right != NULL)
                q.push(front->_right);
            q.pop();
        }
    }
};

void test()
{
    int a[] = { 1, 2, 3, '#', '#', 4, '#','#', 5, 6 };
    BinaryTree<int> bt((int*)a, 10, '#');
    bt.PrevOrder();
    bt.InOrder();
    bt.PostOrder();
    cout << bt.Size() << endl;;
    cout << bt.GetLeafSize() << endl;;
    cout << bt.GetKlevelSize(4) << endl;
    cout << bt.Depth() << endl;
    cout << bt.Find(2) << endl;
    bt.PrevOrderNonR();
    bt.InOrderNonR();
    bt.PostOrderNonR();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值