二叉树实现

#include<iostream>
#include<stack>
#include<stdio.h>
using namespace std;
template<class T>
struct BinTreeNode   // 二叉树结点类定义
{
	T data;                      // 数据域
	BinTreeNode<T>* leftChild;   // 左子女链域
	BinTreeNode<T>* rightChild;  // 右子女链域
	BinTreeNode() : leftChild(NULL), rightChild(NULL) {}
	BinTreeNode(T x, BinTreeNode<T>* l = NULL, BinTreeNode<T>* r = NULL) : data(x), leftChild(l), rightChild(r) {}
};

template<class T>
class BinaryTree
{
public:
	BinaryTree() : root(NULL) {}         // 构造函数,初始化根节点为空
	~BinaryTree() { Destroy(root); }  // 析构函数,用于释放二叉树内存
	BinTreeNode<T>* Create(BinTreeNode<T>*& subTree);  // 前序遍历建二叉树
	int getHeight(BinTreeNode<T>* p);       // 返回树高数
	int countLeaf(BinTreeNode<T>* p);   // 求叶子结点总数
	void preOrder();                    // 前序遍历
	void inOrder();                     // 中序遍历
	void postOrder();                   // 后序遍历
	void NPreOrder();                   // 非递归前序遍历
	void NInOrder();                    // 非递归中序遍历
	void NPostOrder();                  // 非递归后序遍历
	BinTreeNode<T>* root;               // 二叉树的根指针
	void Destroy(BinTreeNode<T>* subTree);                 // 删除二叉树
	void Visit(BinTreeNode<T>* p);                 // 访问结点
	void PreOrder(BinTreeNode<T>* subTree);  // 前序遍历
	void InOrder(BinTreeNode<T>* subTree);   // 中序遍历
	void PostOrder(BinTreeNode<T>* subTree);    // 后序遍历
};
template<class T>
void BinaryTree<T>::preOrder()
{
	PreOrder(root);
}
template<class T>
void BinaryTree<T>::inOrder()
{
	InOrder(root);
}
template<class T>
void BinaryTree<T>::postOrder()
{
	PostOrder(root);
}
template<class T>   // 删除
void BinaryTree<T>::Destroy(BinTreeNode<T>* subTree)
{
	if (subTree != NULL)
	{
		Destroy(subTree->leftChild);   // 递归删除subTree的左子树
		Destroy(subTree->rightChild);  // 递归删除subTree的右子树
		delete subTree;                // 释放subTree
	}
}

template<class T>
void BinaryTree<T>::Visit(BinTreeNode<T>* p)    // 访问结点
{
	cout << p->data;
}

template<class T>
void BinaryTree<T>::PreOrder(BinTreeNode<T>* subTree)              // 前序遍历
{
	if (subTree != NULL)
	{
		Visit(subTree);                // 访问根节点
		PreOrder(subTree->leftChild);  // 递归前序遍历左子树
		PreOrder(subTree->rightChild); // 递归前序遍历右子树
	}
}

template<class T>
void BinaryTree<T>::InOrder(BinTreeNode<T>* subTree)              // 中序遍历
{
	if (subTree != NULL)
	{
		InOrder(subTree->leftChild);   // 递归中序遍历左子树
		Visit(subTree);                // 访问根节点
		InOrder(subTree->rightChild);  // 递归中序遍历右子树
	}
}

template<class T>
void BinaryTree<T>::PostOrder(BinTreeNode<T>* subTree)              // 后序遍历
{
	if (subTree != NULL)
	{
		PostOrder(subTree->leftChild);   // 递归后序遍历左子树
		PostOrder(subTree->rightChild);  // 递归后序遍历右子树
		Visit(subTree);                  // 访问根节点
	}
}
template<class T>
BinTreeNode<T>* BinaryTree<T>::Create(BinTreeNode<T>*& subTree)
{
	T value;
	cin >> value;
	if (value == '#')
	{
		subTree = nullptr;
	}
	else
	{
		subTree = new BinTreeNode<T>();
		subTree->data = value;
		// 递归创建左子树和右子树
		Create(subTree->leftChild);
		Create(subTree->rightChild);
	}
	return subTree;
}

template<class T>
void BinaryTree<T>::NPreOrder()
{
	BinTreeNode<T>* p;
	p = root;
	stack<BinTreeNode<T>*> S;
	while (p != nullptr || !S.empty())
	{
		while (p != nullptr)
		{
			// 先序遍历,访问当前节点并压入右子树
			cout << p->data << " ";
			if (p->rightChild != nullptr)
			{
				S.push(p->rightChild);
			}
			p = p->leftChild;
		}
		if (!S.empty())
		{
			p = S.top();
			S.pop();
		}
	}
}

template<class T>
void BinaryTree<T>::NInOrder()
{
	BinTreeNode<T>* p;
	p = root;
	stack<BinTreeNode<T>*> S;
	while (p != nullptr || !S.empty())
	{
		while (p != nullptr)
		{
			// 中序遍历,将节点压入栈中
			S.push(p);
			p = p->leftChild;
		}
		if (!S.empty())
		{
			p = S.top();
			S.pop();
			cout << p->data << " ";
			p = p->rightChild;
		}
	}
}

template<class T>
void BinaryTree<T>::NPostOrder() {
	if (root == nullptr) {
		return;
	}

	stack<BinTreeNode<T>*> nodeStack;
	stack<BinTreeNode<T>*> resultStack;

	nodeStack.push(root);

	while (!nodeStack.empty()) {
		BinTreeNode<T>* p = nodeStack.top();
		nodeStack.pop();
		resultStack.push(p);

		if (p->leftChild) {
			nodeStack.push(p->leftChild);
		}

		if (p->rightChild) {
			nodeStack.push(p->rightChild);
		}
	}

	while (!resultStack.empty()) {
		cout << resultStack.top()->data << " ";
		resultStack.pop();
	}
}

template<class T>
int BinaryTree<T>::countLeaf(BinTreeNode<T>* subTree) {
	int count = 0;
	if (subTree != nullptr) {
		if (subTree->leftChild == nullptr && subTree->rightChild == nullptr) {
			// 叶子节点
			count++;
		}
		// 递归统计左右子树的叶子节点
		count += countLeaf(subTree->leftChild);
		count += countLeaf(subTree->rightChild);
	}
	return count;
}
template<class T>
int BinaryTree<T>::getHeight(BinTreeNode<T>* p) {
	if (p == NULL) {
		return 0;
	}
	int leftHeight = getHeight(p->leftChild);
	int rightHeight = getHeight(p->rightChild);
	return 1 + (leftHeight > rightHeight ? leftHeight : rightHeight);
}

void menu()
{
	cout << "1------建立一棵二叉树" << endl;
	cout << "2------前序遍历递归算法" << endl;
	cout << "3------前序遍历非递归算法" << endl;
	cout << "4------中序遍历递归算法" << endl;
	cout << "5------中序遍历非递归算法" << endl;
	cout << "6------后序遍历递归算法" << endl;
	cout << "7------后序遍历非递归算法" << endl;
	cout << "8------求树高" << endl;
	cout << "9------求叶子总数" << endl;
	cout << "0-----退出" << endl;
}

int main()
{
	BinaryTree<char> binaryTree;
	int n;
	while (1)
	{
		menu();
		cout << "请输入你的选择: ";
		cin >> n;
		switch (n)
		{
		case 1:
			cout << "请输入二叉树:";
			binaryTree.Create(binaryTree.root);
			cout << endl;
			break;
		case 2:
			cout << "前序遍历(递归):" << endl;
			binaryTree.preOrder();
			cout << endl << endl;
			break;
		case 3:
			cout << "前序遍历(非递归):" << endl;
			binaryTree.NPreOrder();
			cout << endl << endl;
			break;
		case 4:
			cout << "中序遍历(递归):" << endl;
			binaryTree.inOrder();
			cout << endl << endl;
			break;
		case 5:
			cout << "中序遍历(非递归):" << endl;
			binaryTree.NInOrder();
			cout << endl << endl;
			break;
		case 6:
			cout << "后序遍历(递归):" << endl;
			binaryTree.postOrder();
			cout << endl << endl;
			break;
		case 7:
			cout << "后序遍历(非递归):" << endl;
			binaryTree.NPostOrder();
			cout << endl << endl;
			break;
		case 8:
			cout << "树的高度:" << binaryTree.getHeight(binaryTree.root);
			cout << endl << endl;
			break;
		case 9:
			cout << "树的叶子节点数:" << binaryTree.countLeaf(binaryTree.root);
			cout << endl << endl;
			break;
		case 0:
			exit(0);
			break;
		}
	}

	return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值