常用数据结构-二叉树的链式存储、建立和遍历

1. 链式二叉树简介

        二叉树是数据结构——树的一种,一般定义的树是指有一个根节点,由此根节点向下分出数个分支结点,以此类推以至产生一堆结点。树是一个具有代表性的非线性数据结构,所谓的非线性,就是指不再是一对一,而是一对多,不过我觉得其实无论是线性还是非线性,无非就是指针指向的对象个数而已,毕竟双向链表中,一个结点也是指向了两个结点,这是不是也是一对多呢?由此观之,数据结构就是结点的不同组合方式而已。

        二叉树是指,任意一个结点的子节点最多有两个,具体还分为满二叉树(除了最下层的结点,其余结点的度都为2)、完全二叉树(满二叉树转化而来,留左不留右)等,还具有一些计算上的性质,如计算满二叉树的结点等。二叉树也是树中最容易表达的种类,因此非二叉树、森林等都可以转化为二叉树进行存储。

        用链式存储二叉树是因为二叉树某些结点可能为空,如果采用数组存储,可能造成空间的浪费,其实对于满二叉树,完全二叉树而言采用数组存储可能更好。


2. 链式二叉树的建立

      1. 二叉树的建立  

       1. 建立结点结构体,每个结点包括一个数据域和左右子结点的指针域

       2. 建立节点的左右子结点

       3. 对2中建立的子结点再重复第2步,以此类推直到结束


const int MAXSIZE = 200;

template <class T>
/*typedef struct Node
{
    T data;
    struct Node* leftChild;
    struct Node* rightChild;
}*BitTree, BitNode;*/
struct Node
{
    T data;
    struct Node<T>* leftChild;
    struct Node<T>* rightChild;
};


template <class T>
class myBitTree
{
public:
    struct Node<T>* pRootNode;

    //Node<T>* rootNode;

    myBitTree();
    //BitNode* CreateBitTree();
    Node<T>* CreateBitTree();
    void PreOrderTraversal(Node<T>* node);
    void InOrderTraversal(Node<T>* node);
    void PostOrderTraversal(Node<T>* node);
};

template <class T>
myBitTree<T>::myBitTree()
{
    pRootNode = new Node<T>;
    pRootNode = CreateBitTree();
}

template <class T>
Node<T>* myBitTree<T>::CreateBitTree()
{
    T ch;
    cin>>ch;
    Node<T>* pNode = new Node<T>;;//产生新的结点空间
    if ('#' == ch)//录入“#”表示空结点,非空则递归循环产生子结点
    {
        pNode = nullptr;
        cout<<"Haha."<<endl;
    }
    else
    {
        //pNode = new Node<T>;

        pNode->data = ch;
        cout<<pNode->data;
        pNode->leftChild = CreateBitTree();
        pNode->rightChild = CreateBitTree();
    }
    return pNode;
}

       2. 二叉树的遍历

        二叉树的遍历分为前序中序和后序,所谓的前中后就是根节点的遍历位置(此处的根节点是相对的),具体而言,前序遍历就是指先访问根结点,再访问根节点的左子树,最后访问根节点的右子树,其中访问左右子树的时候,依旧按照“中-左-右”的顺序访问。同理,中序遍历即“左中右”,后序遍历即“左右中”,说起来复杂,实现起来非常简单,代码如下:


template <class T>
void myBitTree<T>::PreOrderTraversal(Node<T>* node)
{
    if (node)
    {
        cout<<node->data<<endl;
        //cout<<"1"<<endl;
        //cout<<node->rightChild->data;
        PreOrderTraversal(node->leftChild);
        PreOrderTraversal(node->rightChild);
    }
}

template <class T>
void myBitTree<T>::InOrderTraversal(Node<T>* node)
{
    if (node)
    {
        InOrderTraversal(node->leftChild);
        cout<<node->data<<endl;
        //cout<<"1"<<endl;
        //cout<<node->rightChild->data;

        InOrderTraversal(node->rightChild);
    }
}

template <class T>
void myBitTree<T>::PostOrderTraversal(Node<T>* node)
{
    if (node)
    {
        PostOrderTraversal(node->leftChild);
        PostOrderTraversal(node->rightChild);
        cout<<node->data<<" ";
        //cout<<"1"<<endl;
        //cout<<node->rightChild->data;
    }
}


3. 注意的问题

    1. 写了这个之后其实发现数据结构并不是很难的东西,稍微熟练一些就好了,毕竟不是让我去想出这些结构,而是去用现成的~

    2. 二叉树的建立和遍历都用到了递归

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值