这个地方我感觉理解简单,但是把自己想的转化为代码还是有点困难的,这篇文章主要包括了二叉搜索树的构造,前序遍历,中序遍历,后序遍历,层次遍历,节点的数目,高度等相关操作,下面是代码:
main.cpp
//
// main.cpp
// BinaryTreeDemo
//
// Created by xin wang on 4/16/15.
// Copyright (c) 2015 xin wang. All rights reserved.
//
#include <iostream>
#include "queue.h"
class BadInput{
public:
BadInput(){
std::cout<<"empty tree"<<std::endl;
}
};
//链表二叉树的节点类
template <class T>
class BinaryTreeNode{
public:
BinaryTreeNode(){LeftChild = RightChild=0;}
BinaryTreeNode(const T& e){
data=e;
LeftChild=RightChild =0;
}
BinaryTreeNode(const T& e,BinaryTreeNode *l,BinaryTreeNode *r){
data = e;
LeftChild =l;
RightChild =r;
}
T data;
BinaryTreeNode<T> *LeftChild,*RightChild;
};
template <class T>
class BinaryTree{
public:
BinaryTree(){root =0;}
~BinaryTree(){};
bool IsEmpty()const{
return ((root) ? false : true);
}
bool Root(T& x)const;
void MakeTree(const T& element,BinaryTree<T>& left,BinaryTree<T>& right);//产生一棵树
void BreakTree(const T& element,BinaryTree<T>& left,BinaryTree<T> &right);//拆掉一棵树
void PreOrder(void(*Visit)(BinaryTreeNode<T> *u)){PreOrder(Visit,root);}//前序遍历
void InOrder(void(*Visit)(BinaryTreeNode<T> *u)){InOrder(Visit,root);}//中序遍历
void PostOrder(void(*Visit)(BinaryTreeNode<T> *u)){PostOrder(Visit,root);}//后序遍历
void LevelOrder(void(*Visit)(BinaryTreeNode<T> *u)){LevelOrder(Visit,root);}//层次遍历
void GernerateTree(T& u);//构造一棵树
//二叉树的扩充
void PreOutput();//输出前序遍历
void InOutput();//输出中序遍历
void PostOutput();//输出后序遍历
void LevelOutput();//输出层次遍历
void Delete();//删除节点
int Height(BinaryTreeNode<T> *t)const;//计算树的高度
int Size();//计算节点数
BinaryTreeNode<T> *root;//根节点
private:
void PreOrder(void(*Visit)(BinaryTreeNode<T> *u),BinaryTreeNode<T> *t);
void InOrder(void(*Visit)(BinaryTreeNode<T> *u),BinaryTreeNode<T> *t);
void PostOrder(void(*Visit)(BinaryTreeNode<T> *u),BinaryTreeNode<T> *t);
void LevelOrder(void(*Visit)(BinaryTreeNode<T> *u),BinaryTreeNode<T> *t);
};
//返回是否是根节点
template <class T>
bool BinaryTree<T>::Root(T& x)const{
if (root) {
x=root->data;
return true;
}else{
return false;
}
}
template <class T>
void BinaryTree<T>::MakeTree(const T& element, BinaryTree<T>& left, BinaryTree<T>& right){
//创建新树
root = new BinaryTreeNode<T>(element,left.root,right.root);
//阻止访问left和right
left.root = right.root =0;
}
template <class T>
void BinaryTree<T>::BreakTree(const T& element, BinaryTree<T>& left, BinaryTree<T>& right){
if (!root) {
throw BadInput();
}
element = root->data;
left.root = root->LeftChild;
right.root = root->RightChild;
delete root;
root=0;
}
//前序遍历
template <class T>
void BinaryTree<T>::PreOrder(void(*Visit)(BinaryTreeNode<T> *u),BinaryTreeNode<T> *t){
if (t) {
Visit(t);
PreOrder(Visit,t->LeftChild);
PreOrder(Visit,t->RightChild);
}
}
//中序遍历
template <class T>
void BinaryTree<T>::InOrder(void(*Visit)(BinaryTreeNode<T> *u),BinaryTreeNode<T> *t){
if(t){
InOrder(Visit,t->LeftChild);
Visit(t);
InOrder(Visit, t->RightChild);
}
}
//后序遍历
template <class T>
void BinaryTree<T>::PostOrder(void(*Visit)(BinaryTreeNode<T> *u),BinaryTreeNode<T> *t){
if (t) {
PostOrder(Visit,t->LeftChild);
PostOrder(Visit,t->RightChild);
Visit(t);
}
}
//层次遍历
template <class T>
void BinaryTree<T>::LevelOrder(void(*Visit)(BinaryTreeNode<T> *u),BinaryTreeNode<T> *u){
LinkedQueue<BinaryTreeNode<T> *> Q;
BinaryTreeNode<T> *t;
t=root;
while (t) {
Visit(t);
if (t->LeftChild) {
Q.Add(t->LeftChild);
}
if (t->RightChild) {
Q.Add(t->RightChild);
}
try{
Q.Delete(t);
}catch(OutOfBounds){
return;
}
}
}
//计算树的高度
template <class T>
int BinaryTree<T>::Height(BinaryTreeNode<T> *t)const{
if (!t) {
return 0;
}
int hl=Height(t->LeftChild);
int hr = Height(t->RightChild);
if (hl>hr) {
return ++hl;
}else{
return ++hr;
}
}
int _count;
template <class T>
static void Add1(BinaryTreeNode<T> *t){
_count++;
}
//计算节点数
template <class T>
int BinaryTree<T>::Size(){
_count=0;
PreOrder(Add1,root);
return _count;
}
//输出
template <class T>
static void OutPut(BinaryTreeNode<T> *t){
std::cout<<t->data<<" ";
}
template <class T>
void BinaryTree<T>::PreOutput(){
PreOrder(OutPut,root);
}
template <class T>
void BinaryTree<T>::InOutput(){
InOrder(OutPut,root);
}
template <class T>
void BinaryTree<T>::PostOutput(){
PostOrder(OutPut,root);
}
template <class T>
void BinaryTree<T>::LevelOutput(){
LevelOrder(OutPut,root);
}
//构造一棵树
template <class T>
void BinaryTree<T>::GernerateTree(T& u){
if (!root) {//如果没有根的话,就新建一个根节点,并赋给他根节点的值
root = new BinaryTreeNode<T>;
root->data =u;
root->LeftChild=0;
root->RightChild=0;
return;
}
//如果有根节点的话
BinaryTreeNode<T> *newNode = new BinaryTreeNode<T>;
newNode->data = u;
LinkedQueue<BinaryTreeNode<T> *>myQueue;
BinaryTreeNode<T> *t;
t=root;
while(t){
std::cout<<"t.data"<<t->data<<std::endl;
if (t->LeftChild) {//如果有左孩子的话
myQueue.Add(t->LeftChild);//就加到队列里面
std::cout<<"Left is"<<t->LeftChild->data<<std::endl;
}
if (t->RightChild) {//如果有右孩子的话,就加到队列里面
myQueue.Add(t->RightChild);
std::cout<<"Right is"<<t->RightChild->data<<std::endl;
}
if (!t->LeftChild) {//如果没有左孩子的话,就让新的节点为左孩子
std::cout<<"Put "<<newNode->data<<" in Left"<<std::endl;
t->LeftChild=newNode;
return;
}else{
std::cout<<"t.Leftdata="<<t->LeftChild->data<<std::endl;
}
if(!t->RightChild){//如果没有右孩子的话,就让新的节点为右孩子
std::cout<<"Put "<<newNode->data<<" in Right"<<std::endl;
t->RightChild=newNode;
return;
}else{
std::cout<<"t.Rightdata="<<t->RightChild->data<<std::endl;
}
if (!myQueue.IsEmpty()) {//对队列里面的数再进行如上判断
myQueue.Delete(t);
}
}
}
int main()
{
BinaryTree<int> y;
int myInput;
while (true) {
std::cin>>myInput;
if (myInput == 0) {
break;
}else{
y.GernerateTree(myInput);
}
}
std::cout<<"前序遍历:";
y.PreOutput();
std::cout<<"中序遍历:";
y.InOutput();
std::cout<<"后序遍历:";
y.PostOutput();
std::cout<<"逐层遍历";
y.LevelOutput();
std::cout<<"高度:";
std::cout<<y.Height(y.root)<<std::endl;
std::cout<<"节点数:";
std::cout<<y.Size()<<std::endl;
return 0;
}
queue.h
//
// queen.h
// BinaryTreeDemo
//
// Created by xin wang on 4/17/15.
// Copyright (c) 2015 xin wang. All rights reserved.
//
template <class T>
class Node{
public:
T data;
Node<T> *link;
};
//FIIFO对象
template <class T>
class LinkedQueue{
public:
LinkedQueue(){front=rear=0;}
~LinkedQueue();
bool IsEmpty()const{return ((front)?false:true);}
bool IsFull()const;
T First()const; //返回队首元素
T Last()const; //返回队尾元素
LinkedQueue<T>& Add(const T& x);
LinkedQueue<T>& Delete(T& x);
void Output();
Node<T> *front; //指向第一个节点
Node<T> *rear; //最后一个节点
};
template <class T>
LinkedQueue<T>::~LinkedQueue(){
Node<T> *next;
while (front){
next = front->link;
delete front;
front = next;
}
}
class OutOfBounds{
public:
OutOfBounds(){
//cout<<"Out Of Bounds!"<<endl;
}
};
//内存不足的异常类
class NoMem{
public:
NoMem(){
std::cout<<"No Memory!"<<std::endl;
}
};
//该队列的输出方法
template<class T>
void LinkedQueue<T>::Output(){
Node<T> *temp = front;
while(temp){
std::cout<<temp->data<<" ";
temp=temp->link;
}
std::cout<<""<<std::endl;
}
//判断当前队列是否已满
template <class T>
bool LinkedQueue<T>::IsFull()const{
Node<T>*p;
try{
p = new Node<T>;
delete p;
return false;
}
catch (NoMem)
{
return true;
}
}
//返回队列的第一个元素
template <class T>
T LinkedQueue<T>::First()const{
if(IsEmpty())
throw OutOfBounds();
return front->data;
}
//返回队列的最后一个元素
template <class T>
T LinkedQueue<T>::Last()const{
if(IsEmpty())
throw OutOfBounds();
return rear->data;
}
//将x添加到队列的尾部
template<class T>
LinkedQueue<T>& LinkedQueue<T>::Add(const T&x){
Node<T>*p = new Node<T>;
p->data=x;
p->link=0;
//在队列尾部添加新节点
if (front){
rear->link = p;
}
else{
front=p;
}
rear=p;
return *this;
}
//删除第一个元素并将其放到X中去
template<class T>
LinkedQueue<T>& LinkedQueue<T>::Delete(T&x){
if (IsEmpty()){
throw OutOfBounds();
}
x = front->data;
Node<T>*p = front;
front = front->link;
delete p;
return *this;
}