首页 > 技术文章 > 二叉数(二)

IcoveJLearningBlog 2020-11-09 10:46 原文

二叉树

不在邓公所用的头文件下的二叉数实现。

在学习邓公的二叉树的过程中知道了二叉树要么是一棵空树,要么有两个指针,分别指向左右两个子树。而树的问题,大多采用递归来处理。

在这里我选择采用链式存储结构:

//二叉树头文件
#pragma once
#ifndef BITREE_H_INCLUDED
#define BITREE_H_INCLUDED
#include<iostream>
#include <string>
using namespace std;
struct BiNode {
	char data; 
	BiNode *LChild, *RChild; 
};

class BiTree {
private:
	BiNode * root;
	int height;
	void PreOrder(BiNode * t);
	void InOrder(BiNode * t);
	void PostOrder(BiNode * t);
	BiNode* create(string& s, int& pos);
	void GetHeight(BiNode * t, int h);
public:
	BiTree() { root = NULL; height = 0; }
	//按照前序遍历序列创建二叉树
	void createBiTree(string s);
	//前序遍历二叉树
	void preOrder();
	//中序遍历二叉树
	void inOrder();
	//递归后序遍历二叉树
	void postOrder_1();
	//非递归后序遍历二叉树
	void postOrder_2();
	//层序遍历二叉树
	void levelOrder();
	//求树的高度
	int get_Height();
};

#endif // BITREE_H_INCLUDED


//测试文件
#include "BinTree.h"
#include "queue"
#include "stack"
#include "vector"
#include <iostream>
using namespace std;

//递归创建二叉树
BiNode * BiTree::create(string& s, int& pos) {
	++pos;
	BiNode * t;
	if ((unsigned)pos >= s.size()) return 0;
	else {
		if (s[pos] == '#')
			t = NULL;
		else {
			t = new BiNode;
			t->data = s[pos];
			t->LChild = create(s, pos);
			t->RChild = create(s, pos);
		}
		return t;
	}
}

//按照前序遍历序列创建二叉数
void BiTree::createBiTree(string s) {
	int pos = -1;
	root = create(s, pos);
}

//前序遍历二叉树
void BiTree::preOrder() {
	PreOrder(root);
	cout << endl;
}
void BiTree::PreOrder(BiNode * t) {
	if (t != NULL) {
		cout << t->data << ' ';
		PreOrder(t->LChild);
		PreOrder(t->RChild);
	}
}

//中序遍历二叉树
void BiTree::inOrder() {
	InOrder(root);
	cout << endl;
}
void BiTree::InOrder(BiNode * t) {
	if (t != NULL) {
		InOrder(t->LChild);
		cout << t->data << ' ';
		InOrder(t->RChild);
	}
}

//递归后序遍历二叉树
void BiTree::postOrder_1() {
	PostOrder(root);
	cout << endl;
}
void BiTree::PostOrder(BiNode * t) {
	if (t != NULL) {
		PostOrder(t->LChild);
		PostOrder(t->RChild);
		cout << t->data << ' ';
	}
}

//非递归后序遍历二叉树
void BiTree::postOrder_2() {
	BiNode *p, *r;
	r = NULL;
	p = root;
	stack<BiNode*> my_stack;
	while (p != NULL || !my_stack.empty()) {
		if (p) {
			my_stack.push(p);
			p = p->LChild;
		}
		else {
			p = my_stack.top();
			if (p->RChild != NULL & p->RChild != r) {
				p = p->RChild;
				my_stack.push(p);
				p = p->LChild;
			}
			else {
				p = my_stack.top();
				my_stack.pop();
				cout << p->data << ' ';
				r = p;
				p = NULL;
			}
		}
	}
	cout << endl;
}

//使用队列进行层序遍历二叉树
void BiTree::levelOrder() {
	if (root == NULL)
		return;
	queue<BiNode*> q;
	q.push(root);
	while (!q.empty()) {
		BiNode * t;
		t = q.front();
		q.pop();
		cout << t->data << ' ';
		if (t->LChild != NULL)
			q.push(t->LChild);
		if (t->RChild != NULL)
			q.push(t->RChild);
	}
	cout << endl;
}

//求树的高度
int BiTree::get_Height() {
	GetHeight(root, 0);
	return height;
}
void BiTree::GetHeight(BiNode* t, int h) {
	if (t != NULL) {
		++h;
		if (h > height)
			height = h;
		GetHeight(t->LChild, h);
		GetHeight(t->RChild, h);
	}
}

//测试
int main() {
	BiTree a;
	string s;
	s = "AB##C##";//注意,无论是键盘实现输入,还是整体s输入,都要将其补成满二叉树
	a.createBiTree(s);
	cout << "前序遍历" << endl;
	a.preOrder();
	cout << "中序遍历" << endl;
	a.inOrder();
	cout << "递归后序遍历" << endl;
	a.postOrder_1();
	cout << "非递归后序遍历" << endl;
	a.postOrder_2();
	cout << "层序遍历" << endl;
	a.levelOrder();
	cout << "树高" << endl;
	cout << a.get_Height() << endl;
	system("pause");
	return 0;
}
//在测试的代码中,生成的二叉树是根节点为A,其左右子节点分别为BC,再下面皆为空节点
//可能会有疑惑,为什么不是根节点是A,其左右子节点分别为B和空,这就在于我们的创建函数:它总是沿着一边进行创建,即创建了左子节点后,再继续创建其的左子节点,直至最后一个元素
//所以当输入ABC时,实际上只创建了一条单边,即根节点为A,左子节点为B,左左子节点为C,其高度为3,就不会是2.

推荐阅读