二叉树

最近在mooc上发现了清华、北大2门数据结构的课程,一直在潜心学习他们的课程,博客没有及时更新,今天刚刚学习了二叉树,趁热打铁,记录下二叉树的学习经历吧,老规矩,还是看代码

二叉树节点类的实现:

#ifndef BINARY_TREE_NODE_H
#define BINARY_TREE_NODE_H

template <typename T> class BinaryTree;

template <typename T>
class BinaryTreeNode
{
friend class BinaryTree<T>;
private:
	T  data;				     	    	//二叉树结点数据域
	BinaryTreeNode<T>* left;		   		//二叉树结点指向左子树的指针
	BinaryTreeNode<T>* right;    			//二叉树结点指向左子树的指针

public:
	//缺省构造函数
	BinaryTreeNode()	
	{
		left = right = nullptr;
	}

	//给定了结点值和左右子树的构造函数
	BinaryTreeNode(T val,BinaryTreeNode<T> *lc = nullptr,BinaryTreeNode<T> *rc = nullptr) : data(val),left(lc),right(rc)
	{

	}

	//返回当前结点的数据
	T value() const
	{
		return this->data;
	}
	//返回当前结点左子树
	BinaryTreeNode<T> * leftChild() const 
	{
		return this->left;
	}

	//返回当前结点右子树
	BinaryTreeNode<T> * rightChild() const
	{
		return this->right;
	}

	//设置当前结点的左子树
	void setLeftChild(BinaryTreeNode<T> * lc)
	{
		this->left = lc;
	}

	//设置当前结点的右子树
	void setRightChild(BinaryTreeNode<T> * rc)
	{
		this->right = rc;
	}

	//设置当前结点的数据域
	void setValue(T val)
	{
		this->data = val;
	}

	//判定当前结点是否为叶结点,若是返回true
	bool isLeaf() const
	{
		return (this->left == nullptr) && (this->right == nullptr);
	}

	//重载赋值操作符
	BinaryTreeNode<T>& operator = (const BinaryTreeNode<T>& Node)
	{
		this = Node;
	}

};


#endif

二叉树的实现:

#ifndef BINARY_TREE_H
#define BINARY_TREE_H

#include "BinaryTreeNode.h"
#include <iostream>
#include <stack>
#include <queue>
using std::cout;
using std::endl;
using std::stack;
using std::queue;


enum Tags{Left,Right};    //枚举类型

template <class T>
class StackElement  
{         //StackElement
public:
	BinaryTreeNode<T>* pointer;
	Tags tag;
};	

template <typename T>
class BinaryTree
{
private:
	BinaryTreeNode<T> *root;

public:
	BinaryTree(BinaryTreeNode<T> *r = nullptr)
	{
		root = r;
	}

	~BinaryTree()
	{
		deleteBinaryTree(root);
	}

	//以后序周游的方式删除二叉树
	void deleteBinaryTree(BinaryTreeNode<T> *r)
	{
		if(r)
		{
			deleteBinaryTree(r->left);
			deleteBinaryTree(r->right);
			delete r;
		}
	}

	//判定二叉树是否为空树
	bool isEmpty() const
	{
		return this->root == nullptr;
	}

	//返回二叉树根结点
	BinaryTreeNode<T>* getRoot()
	{
		return root;
	}

	
	//构造一棵以info为根、leftTree和rightTree为左右子树的新二叉树
	void createTree(const T& info, BinaryTree<T>& leftTree, BinaryTree<T>& rightTree)
	{
		root = new BinaryTreeNode<T>(info,leftTree.root,rightTree.root);
		leftTree.root = rightTree.root = nullptr;
	}


	void visit(BinaryTreeNode<T> *node)
	{
		cout << node->value() << "\t";;
	}

	//前序周游二叉树
	void preOrder (BinaryTreeNode<T> *root)
	{  
		if(root)
		{
			visit(root);
			preOrder(root->leftChild());
			preOrder(root->rightChild());
		}
	}

	//前序周游二叉树without递归
	void preOrderWithoutRecursion(BinaryTreeNode<T> *root)
	{
		stack<BinaryTreeNode<T> * > aStack;
		BinaryTreeNode<T> *point = root;
		while(!aStack.empty() || point)
		{
			if(point)
			{
				visit(point); //访问当前结点
				aStack.push(point);//当前结点地址入栈,为了便于查找右孩子
				point = point->leftChild();//当前链接结构指向左孩子
			}
			else //左子树访问完毕,转向访问右子树

			{
				point = aStack.top();//栈顶元素退栈  
				aStack.pop();
				point = point->rightChild();//当前链接结构指向右孩子
			}
		}
	}

	//中序周游二叉树
	void inOrder (BinaryTreeNode<T> *root)
	{  
		if(root)
		{
			inOrder(root->leftChild());
			visit(root);
			inOrder(root->rightChild());
		}
	}

	//中序周游二叉树without递归
	void inOrderWithoutRecursion(BinaryTreeNode<T> *root)
	{
		stack<BinaryTreeNode<T> * > aStack;
		BinaryTreeNode<T> *point = root;
		while(!aStack.empty() || point)
		{
			if(point)
			{
				aStack.push(point);//当前结点地址入栈
				point = point->leftChild();//当前链接结构指向左孩子
			}
			else //左子树访问完毕,转向访问右子树

			{
				point = aStack.top();//栈顶元素退栈  
				aStack.pop();
				visit(point); //访问当前结点
				point = point->rightChild();//当前链接结构指向右孩子
			}
		}
	}

	//后序周游二叉树
	void postOrder (BinaryTreeNode<T> *root)
	{  
		if(root)
		{
			postOrder(root->leftChild());
			postOrder(root->rightChild());
			visit(root);
		}
	}

	//后序周游二叉树without递归
	void postOrderWithoutRecursion(BinaryTreeNode<T> *root)
	{  
		StackElement<T> element;
		stack<StackElement<T> > aStack;
		BinaryTreeNode<T> *point;
		
		if(root == nullptr)
		{
			return ;
		}
		else
		{
			point = root;
		}

		while(!aStack.empty() || point)
		{
			while(point)
			{
				element.pointer = point;
				element.tag = Left;
				aStack.push(element);
				point = point->leftChild();//沿左子树方向向下周游
			}

			element = aStack.top();
			aStack.pop();//托出栈顶元素
			point = element.pointer;

			if(element.tag == Left)
			{
				//从左子树回来
				element.tag = Right;
				aStack.push(element);
				point = point->rightChild();
			}
			else
			{
				//从右子树回来
				visit(point); //访问当前结点
				point = nullptr;
			}
		}
	}

	//按层次周游二叉树或其子树
	void LevelOrder(BinaryTreeNode<T>* root)
	{
		queue<BinaryTreeNode<T> * > aQueue;
		BinaryTreeNode<T> *point = root;
		if(point)
		{
			aQueue.push(point);//根结点入队列
		}

		while(!aQueue.empty())//队列非空
		{
			point = aQueue.front();//取队列首结点
			aQueue.pop();//当前结点出队列
			visit(point);//访问当前结点

			if(point->leftChild() != nullptr)
			{
				aQueue.push(point->leftChild());//左子树进队列
			}

			if(point->rightChild() != nullptr)
			{
				aQueue.push(point->rightChild());//右子树进队列
			}
		}
	}
		

};


#endif


测试代码

#include "BinaryTree.h"
#include <iostream>


int main()
{
	//建一棵树(如图5.5所示)
	BinaryTree<char> a, b, c, d, e, f, g, h, i,nulltree;
	d.createTree('D', nulltree, nulltree);
	g.createTree('G', nulltree, nulltree);
	h.createTree('H', nulltree, nulltree);
	i.createTree('I', nulltree, nulltree);
	f.createTree('F', h, i);
	e.createTree('E', g, nulltree);
	b.createTree('B', d, e);
	c.createTree('C', nulltree, f);
	a.createTree('A', b, c);

	//前序周游二叉树
	cout << "Preorder sequence is: "<<endl;
	a.preOrder(a.getRoot());				//递归
	cout << endl;
	cout << "Preorder sequence Without Recursion is: " <<endl;
	a.preOrderWithoutRecursion(a.getRoot());//非递归
	cout << endl;

	//中序周游二叉树
	cout << "Inorder sequence is: "<<endl;
	a.inOrder(a.getRoot());			//递归
	cout << endl;
	cout << "Inorder sequence Without Recursion is: " <<endl;
	a.inOrderWithoutRecursion(a.getRoot());//非递归
	cout << endl;
	

	//后序周游二叉树
	cout << "Postorder sequence is: "<<endl;
	a.postOrder(a.getRoot());			//递归
	cout << endl;
	cout << "Postorder sequence Without Recursion is: " <<endl;
	a.postOrderWithoutRecursion(a.getRoot());//非递归	
	cout << endl;	

	cout << "Levelorder sequence Without Recursion is: " <<endl;
	a.LevelOrder(a.getRoot());//非递归	
	cout << endl;	

	

	//root
	cout << "Root is: " << a.getRoot()->value() <<endl;

	/*	//delete tree
	a.deleteBinaryTree(a.getRoot());
	cout<<"Tree is deleted."<<endl;        //没有问题,在析构函数中调用
	*/



	system("pause");
	return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值