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

实现功能

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


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

比如以下数组




ab##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;
}


posted @ 2018-11-29 21:43  Drake丶  阅读(803)  评论(0编辑  收藏  举报