二叉树操作

本文章主要包括了以下内容:
创建二叉树类。二叉树的存储结构使用链表。
供操作:前序遍历、中序遍历、后序遍历、层次遍历、计算二叉树结点数目、计算二叉树高度。
接收键盘录入的二叉树前序序列和中序序列(各元素各不相同),输出该二叉树的后序序列。
下面是c++代码:


#include <stdio.h>
#include<iostream>
#include<string.h>
using namespace std;
#include <stdio.h>
#include <iostream>  
#include <cstdlib>
#include <cstdio>
#include <stack>  
using namespace std; 

class BinaryTreeNode//二叉树的节点类
{
public:
    BinaryTreeNode() { leftChild = rightChild = 0; }
    BinaryTreeNode(char c) { data = c; leftChild = rightChild = 0; }
    BinaryTreeNode(char c, BinaryTreeNode* left, BinaryTreeNode* right) { data = c; leftChild = left; rightChild = right; }

    char data;
    BinaryTreeNode* leftChild;
    BinaryTreeNode* rightChild;
};




class Node  //队列类中用链表存
{
public:
    BinaryTreeNode *data;
    Node *next;
    Node() { next = NULL; }
    Node(BinaryTreeNode *item, Node* link = NULL) { data = item; next = link; }
};





//队列类,作为层次遍历的辅助数据结构用
class LinkQueue
{
private:
    Node *front, *rear;
public:
    LinkQueue() { rear = front = new Node; };
    bool empty() 
    { 
        return front == rear;
    }
    void outQueue(BinaryTreeNode * &e)//出队列
    {
        Node *tmpPtr = front->next;
        e = tmpPtr->data;
        front->next = tmpPtr->next;
        if (rear == tmpPtr) rear = front;
        delete tmpPtr;
    }
    void inQueue(BinaryTreeNode * &e)//入队列
    {
        Node *tmpPtr = new Node(e);
        rear->next = tmpPtr;
        rear = tmpPtr;
    }

};








//二叉树类
class BinaryTree
{
public:
    BinaryTree() { root = 0; }
    void getRoot(char* c);

    void insertLeftChild(BinaryTreeNode* t, char c)//插入左孩子
    {
        t->leftChild = new BinaryTreeNode(c);
    }
    void insertRightChild(BinaryTreeNode* t, char c)//插入右孩子
    {
        t->rightChild = new BinaryTreeNode(c);
    }
    void preOrder(BinaryTreeNode *t)//前序遍历
    {
        if (t)
        {
            cout << t->data;
            preOrder(t->leftChild);
            preOrder(t->rightChild);
        }
    }
    void inOrder(BinaryTreeNode* t)//中序遍历
    {
        if (t)
        {
            inOrder(t->leftChild);
            cout << t->data;
            inOrder(t->rightChild);
        }
    }
    void postOrder(BinaryTreeNode* t)//后续遍历
    {
        if (t)
        {
            postOrder(t->leftChild);
            postOrder(t->rightChild);
            cout << t->data;
        }
    }
    void levelOrder(BinaryTreeNode* t)//层次遍历
    {
        LinkQueue q;
        bool isNullAtFirst = true;
        while (t)
        {
            cout << t->data;

            if (t->leftChild) q.inQueue(t->leftChild);
            if (t->rightChild) q.inQueue(t->rightChild);

            if (q.empty()) return;

            q.outQueue(t);
        }
    }
    void preOrderForCount(BinaryTreeNode* t)//用了前序遍历的方法来计算二叉树节点数目
    {
        if (t)
        {
            count++;
            preOrderForCount(t->leftChild);
            preOrderForCount(t->rightChild);
        }
    }
    int height(BinaryTreeNode* t)//返回一个节点的高度
    {
        if (!t) return 0;
        int heightLeft = height(t->leftChild);
        int heightRight = height(t->rightChild);
        if (heightLeft > heightRight) return ++heightLeft;
        else return ++heightRight;
    }
    int size()//返回二叉树节点数目
    {
        count = 0;
        preOrderForCount(root);
        return count;
    }

    BinaryTreeNode* root;
    int count = 0;
};

//前序中序生成后序
//前序遍历的第一个元素为根节点,在中序遍历中找到这个根节点,从而可以将中序遍历分为左右两个部分,左边部分为左子树的中序遍历,
//右边部分为右子树的中序遍历,进而也可以将前序遍历除第一个元素以外的剩余部分分为两个部分,第一个部分为左子树的前序遍历,第二
//个部分为右子树的前序遍历。 
//上述分析结果,可以递归调用构建函数,根据左子树、右子树的前序、中序遍历的结果输出后序遍历的结果。 

void generatePostOrder(char* preOrder, char* inOrder, int length)
{
    if (length == 0) return;

    BinaryTreeNode* t = new BinaryTreeNode(*preOrder);
    int rootIndex = 0;
    //前序遍历的第一个元素为根节点,在中序遍历中找到这个根节点
    for (; rootIndex < length; rootIndex++)
    {
        if (inOrder[rootIndex] == *preOrder)
            break;
    }
    //左子树递归 
    generatePostOrder(preOrder + 1, inOrder, rootIndex);
    //右子树递归 
    generatePostOrder(preOrder + rootIndex + 1, inOrder + rootIndex + 1, length - (rootIndex + 1));
    cout << t->data;
    return;
}
int main()
{
     BinaryTree b;
    b.root = new BinaryTreeNode('G');
    b.insertLeftChild(b.root, 'D');
    b.insertRightChild(b.root, 'M');
    b.insertLeftChild(b.root->leftChild, 'A');
    b.insertRightChild(b.root->leftChild, 'F');
    b.insertLeftChild(b.root->leftChild->rightChild, 'E');
    b.insertLeftChild(b.root->rightChild, 'H');
    b.insertRightChild(b.root->rightChild, 'Z');

    cout << "The preOrder is:";
    b.preOrder(b.root);
    cout << endl;

    cout << "the inOrder is:";
    b.inOrder(b.root);
    cout << endl;

    cout << "the postOrder is:";
    b.postOrder(b.root);
    cout << endl;

    cout << "the levelOrder is:";
    b.levelOrder(b.root);
    cout << endl;

    cout << "这个二叉树的节点数目为:" << b.size() << endl;

    cout << "这个二叉树根节点的高度为:" << b.height(b.root) << endl;

    cout << endl;


    /*
     在这里输入前序中序 来输出后序
     最好直接输入上面创建好的二叉树的前序中序 来检验后序
     当然不嫌麻烦自己画个二叉树 列举出它的前中序来输出后序也可以
     */
    char *pre = new char[20];
    char *in = new char[20];
    cout << "请输入一个二叉树的前序遍历:" << endl;
    cin >> pre; //GDAFEMHZ
    cout << "请输入一个二叉树的中序遍历:" << endl;
    cin >> in;  //ADEFGHMZ

    cout << "这个二叉树的后序遍历为:" << endl;
    generatePostOrder(pre, in, strlen(pre));
    system("pause");
    return 0;
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值