二叉树的前序遍历建树及其输出所有结点,用队列找父亲结点,用递归找出度为1的结点个数

实现功能

1.结点类的释放
2.前序遍历建树
3.前序遍历输出二叉树结点
4.用队列实现查找给定结点的父亲结点
5.查找二叉树中出度为1的结点的个数


Note:关于树的输入,是一维数组的形式输入且是前序序列形式建树需要以#号代表该出无子树

比如以下数组





a b # # c # #

就是会形成一个如下图所示的简单二叉树

   a
  / \
 b   c
 //对应上#的话就是这样的树,然后#就代表NULL,不存在
      a
     / \
    b   c
   / \ / \
  #   ##  #

代码如下:

#include <iostream>
#include <queue>
using namespace std;

template<class T> class BTree;
template<class T>
class BNode {
    char data;
    BNode<T> *lch, *rch;
public:
    BNode() :lch(NULL), rch(NULL) {}
    BNode(T item, BNode<T>*left = NULL, BNode<T>*right = NULL) :data(item), lch(left), rch(right) {}
    void Release();
    friend class BTree<T>;
};

template<class T>
class BTree {
private:
    BNode<T>*root;
public:
    BTree() :root(NULL) {}
    ~BTree();
    void PreOderBuild(BNode<T> *&BT, int &index);
    void PreOder(BNode<T>*BT);
    BNode<T>*SF(char Value);
    int CountOneChild(BNode<T> *BT)const;
};

char tree[100];
int N = 0, index;
BNode<char> *BT = NULL;
int CntLeft, CntRight;

template<class T>
void BNode<T>::Release() {
    if (lch) {
        
        lch->Release();
        delete lch;
        lch = NULL;
    }
    if (rch) {
    
        rch->Release();
        delete rch;
        rch = NULL;
    }
}

template<class T>
BTree<T>::~BTree() {  //析构
    if (BT) {
        cout << "Destruction Performed Successfully!" << endl;
        BT->Release();
        delete BT;
        BT = NULL;
    }
}

template<class T>
void BTree<T>::PreOderBuild(BNode<T> *&BT, int &index) {  //建树
    if (index >= 15) return;
    if (tree[index] == '#') {
        BT = NULL;
        index++;
    }
    else {  
        BT = new BNode<T>;
        BT->data = tree[index];
        index++;
        PreOderBuild(BT->lch, index);
        PreOderBuild(BT->rch, index);
    }
}

template<class T>
void BTree<T>::PreOder(BNode<T> *BT) {  //遍历
    if (BT) {
        cout << BT->data << " ";
        PreOder(BT->lch);
        PreOder(BT->rch);
    }

    return;
}

queue<BNode<char>*> Q;
template<class T>
BNode<T>* BTree<T>::SF(char Value) {    //寻找父结点
    
    Q.push(BT);
    BNode<char>*ptr;
    ptr = Q.front();
    while (!Q.empty()) {
        ptr = Q.front();
        Q.pop();
        if (ptr->lch ) {
            if (ptr->lch->data == Value) {
                cout <<"该点的父亲结点的值为: "<< ptr->data << endl;
                return ptr;
            }
        }
        if (ptr->rch) {
            if (ptr->rch->data == Value) {
                cout << "该点的父亲结点的值为:" << ptr->data << endl;
                return ptr;
            }
        }
        if (ptr->lch) {
            Q.push(ptr->lch);
        }
        if (ptr->rch) {
            Q.push(ptr->rch);
        }
    }
}

template<class T>
int BTree<T>::CountOneChild(BNode<T>*BT)const {
    if (!BT) { 
        cout << "该结点不存在" << endl;
        return 0; }
    if ((!BT->lch) && (!BT->rch)) {
        cout << BT->data << "为叶子结点" << endl;
        return 0;
    }
    if (BT->lch && (!BT->rch)) {
        cout <<BT->data<< "的出度为1且是左子树" << endl;
        return (CountOneChild(BT->lch) + 1);
    }
    if (BT->rch && (!BT->lch)){
        cout << BT->data<<"的出度为1且是右子树" << endl;
        return (CountOneChild(BT->rch) + 1); 
    }
    if (BT->lch && (BT->rch)) {
        cout << BT->data << "结点的出度为2" << endl;
        return CountOneChild(BT->lch) + CountOneChild(BT->rch);
    }
}


int main()
{
    //FILE *is;
    //freopen_s(&is, "C:\\Users\\Administrator\\Desktop\\in.txt", "r", stdin);

    int num;
    cin >> num;
    for (int i = 0; i < num; ++i) {
        cin >> tree[i];
    }
    char child;
    BTree<char> L;
    L.PreOderBuild(BT, index);
    cout << "请输入想找的结点: " << endl;
    cin >> child;
    cout << "该结点的父亲结点地址为:" << L.SF(child) << endl;
    cout << "前序遍历输:" << endl;
    L.PreOder(BT);
    cout << endl;
    cout << "出度为1的结点的个数为: " << L.CountOneChild(BT) << endl;
    L.~BTree();
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/drake233/p/10041087.html