数据结构——二叉树

二叉树

线性表、栈和队列都是一种线性的数据结构,数据元素在组织结构上呈现线性排列,从二维视角来看,一个元素向前最多只会有
一个元素,向后只最多只会有一个元素。但数据的结构可能更复杂,比如说数据排列可以呈现一种分支的情况,一个元素向某个方向
可能有多个分支,这里就需要其他数据结构来描述。树是一种能够一对多的数据结构,可以描述一个节点和多个节点之间的关系。数
据结构中的树是一棵倒着的树,树根在上方,而叶子在下方,数据储存在分支处、根处或者叶子处。
计算机中有很多一对多关系的场景,比如说文件系统,一个文件夹内可能会有多个子文件夹或者文件,这些文件就是文件系统二叉
树的叶子节点,而子文件夹就是子树的根节点。根据二叉树的特性可以很方便地定义和操作这类一对多关系,在应用中,只需要保持
根节点可见,就可以找到这棵树的任意一个节点。
同其他数据结构一样,二叉树也是通过一些属性来描述的。比如说节点的度,就是指这节点下的分支个数,节点的层次就是这个节
点所在的层,根节点在第一层,向下层次依次递增,树的高度指树的层数,路径指一个节点到另一个节点所经过的线段的总和。
树,一般采用链式储存结构,因为树的特性就是一对多,顺序储存结构描述这种一对多的关系比较麻烦,而使用链式储存结构时,
多一个节点只需要在节点的结构体定义时多加一个指针字段就可以了。当然,也是可以使用顺序储存结构来描述二叉树的,比如堆这
种满二叉树就比较适合用顺序储存结构来描述,用下标来表示关系。由于是满二叉树,那么数组中的每个位置都保存了数据,一个下标
为x的节点两个子节点的下标分别是2x和2x+1。
下面是二叉树数据结构的接口定义
template<typename T>
	struct BinTreeNode
	{
		T data;
		BinTreeNode<T>* lc;
		BinTreeNode<T>* rc;
		BinTreeNode<T>* p;
	};
	template<typename T>
	class BinTree
	{
	public:
		BinTree();
		~BinTree();
		BinTreeNode<T>* GetRoot() const;
		void InitRoot(const T &t);
		bool Empty() const;
		bool GetElem(const BinTreeNode<T>* cur, T &t)const;
		bool SetElem(const BinTreeNode<T>* cur, const T &t)const;
		void InOrder(void(*visit)(const T &t))const;
		void PreOrder(void(*visit)(const T &t))const;
		void PostOrder(void(*visit)(const T &t))const;
		void LevelOrder(void(*visit)(const T &t))const;
		int NodeCount()const;
		BinTreeNode<T>* LeftChild(const BinTreeNode<T>* cur)const;
		BinTreeNode<T>* RightChild(const BinTreeNode<T>* cur)const;
		BinTreeNode<T>* Parent(const BinTreeNode<T>* cur)const;
		void InsertLeftChild(BinTreeNode<T>* cur, const T &t);
		void InsertRightChild(BinTreeNode<T>* cur, const T &t);
		void DeleteLeftChild(BinTreeNode<T>* cur, T &t);
		void DeleteRightChild(BinTreeNode<T>* cur, T &t);
		int Height()const;
	private:
		BinTreeNode<T>* root;
		void DeleteHelper(BinTreeNode<T>* r);
		void InOrderHelper(BinTreeNode<T>* r,void(*visit)(const T &t))const;
		void PreOrderHelper(BinTreeNode<T>* r, void(*visit)(const T &t))const;
		void PostOrderHelper(BinTreeNode<T>* r, void(*visit)(const T &t))const;
		void LevelOrderHelper(BinTreeNode<T>* r, void(*visit)(const T &t))const;
		void NodeCountHelper(BinTreeNode<T>* r, int &count) const;
		int HeightHelper(BinTreeNode<T>* r)const;
	};





下面是对接口的实现
template<typename T>
	BinTree<T>::BinTree()
	{
		root = NULL;
	}

	template<typename T>
	void BinTree<T>::DeleteHelper(BinTreeNode<T>* r)
	{
		if(r->lc)
		{
			DeleteHelper(r->lc);
		}

		if(r->rc)
		{
			DeleteHelper(r->rc);
		}

		delete r;
	}

	template<typename T>
	BinTree<T>::~BinTree()
	{
		DeleteHelper(root);
	}

	template<typename T>
	void BinTree<T>::InitRoot(const T &t)
	{
		root = new BinTreeNode<T>;
		root->data = t;
	}
	
	template<typename T>
	BinTreeNode<T>* BinTree<T>::GetRoot()const
	{
		return root;
	}

	template<typename T>
	bool BinTree<T>::Empty()const
	{
		return root == NULL;
	}

	template<typename T>
	bool BinTree<T>::GetElem(const BinTreeNode<T> *cur, T &t)const
	{
		t = cur->data;
		return true;
	}

	template<typename T>
	bool BinTree<T>::SetElem(const BinTreeNode<T>  *cur, const T &t)const
	{
		cur->data = t;
		return true;
	}

	template<typename T>
	void BinTree<T>::InOrderHelper(BinTreeNode<T>* r, void(*visit)(const T &t))const
	{
		if(r)
		{
			if(r->lc)
			{
				InOrderHelper(r->lc, visit);
			}
			visit(r->data);
			if (r->rc) 
			{
				InOrderHelper(r->rc, visit);
			}
		}
	}

	template<typename T>
	void BinTree<T>::InOrder(void(*visit)(const T &t))const
	{
		InOrderHelper(root, visit);
	}

	template<typename T>
	void BinTree<T>::PreOrderHelper(BinTreeNode<T>* r, void(*visit)(const T &t))const
	{
		if (r)
		{
			visit(t);
			if (r->lc)
			{
				PreOrderHelper(r->lc, visit);
			}
			if (r->rc)
			{
				PreOrderHelper(r->rc, visit);
			}
		}
	}

	template<typename T>
	void BinTree<T>::PreOrder(void(*visit)(const T &t))const
	{
		PreOrderHelper(root, visit);
	}

	template<typename T>
	void BinTree<T>::PostOrderHelper(BinTreeNode<T>* r, void(*visit)(const T &t))const
	{
		if (r)
		{
			if (r->lc)
			{
				PostOrderHelper(r->lc, visit);
			}
			if (r->rc)
			{
				PostOrderHelper(r->rc, visit);
			}
			visit(t);
		}
	}

	template<typename T>
	void BinTree<T>::PostOrder(void(*visit)(const T &t))const
	{
		PostOrderHelper(visit, visit);
	}

	template<typename T>
	void BinTree<T>::LevelOrderHelper(BinTreeNode<T>* r, void(*visit)(const T &t))const
	{
		if (r)
		{
			int count = 0;
			NodeCountHelper(r, count);
			BinTreeNode<T>** queue = new BinTreeNode<T>*[count];//遍历所需要的辅助队列,在其中储存节点的指针
			BinTreeNode<T>* node;
			int front = 0, rear = 0;
			queue[rear++] = r;
			while (front != rear) //如果队列中还有元素
			{
				node = queue[front++];
				visit(node->data);
				if(node->lc)
				{
					queue[rear++] = node->lc;
				}
				if (node->rc)
				{
					queue[rear++] = node->rc;
				}
			}
			delete queue;
		}
	}

	template<typename T>
	void BinTree<T>::LevelOrder(void(*visit)(const T &t))const
	{
		LevelOrderHelper(root, visit);
	}


	template<typename T>
	void BinTree<T>::NodeCountHelper(BinTreeNode<T>* r, int &count)const 
	{
		if(r)
		{
			++count;
			if (r->lc) 
			{
				NodeCountHelper(r->lc, count);
			}
			if (r->rc)
			{
				NodeCountHelper(r->rc, count);
			}
		}
	}
	template<typename T>
	int BinTree<T>::NodeCount()const
	{
		int count = 0;
		NodeCountHelper(root, count);
		return count;
	}

	template<typename T>
	BinTreeNode<T>* BinTree<T>::LeftChild(const BinTreeNode<T>* cur)const
	{
		return cur->lc;
	}

	template<typename T>
	BinTreeNode<T>* BinTree<T>::RightChild(const BinTreeNode<T>* cur)const
	{
		return cur->rc;
	}

	template<typename T>
	BinTreeNode<T>* BinTree<T>::Parent(const BinTreeNode<T>* cur)const
	{
		return cur->p;
	}

	template<typename T>
	void BinTree<T>::InsertLeftChild(BinTreeNode<T>* cur, const T &t)
	{
		BinTreeNode<T>* newNode = new BinTreeNode<T>;
		newNode->data = t;
		newNode->lc = NULL;
		newNode->rc = NULL;
		newNode->p = cur;
		cur->lc = newNode;
	}

	template<typename T>
	void BinTree<T>::InsertRightChild(BinTreeNode<T>* cur, const T &t)
	{
		BinTreeNode<T>* newNode = new BinTreeNode<T>;
		newNode->data = t;
		newNode->lc = NULL;
		newNode->rc = NULL;
		newNode->p = cur;
		cur->rc = newNode;
	}

	template<typename T>
	void BinTree<T>::DeleteLeftChild(BinTreeNode<T>* cur, T &t)
	{
		BinTreeNode<T>* node = cur->lc;
		cur->lc = NULL;
		node->p = NULL;
		t = node->data;
		delete node;
	}

	template<typename T>
	void BinTree<T>::DeleteRightChild(BinTreeNode<T>* cur, T &t)
	{

		BinTreeNode<T>* node = cur->rc;
		cur->rc = NULL;
		node->p = NULL;
		t = node->data;
		delete node;
	}
	
	template<typename T>
	int BinTree<T>::HeightHelper(BinTreeNode<T>* r)const
	{
		int count = 1;
		if(r->lc)
		{
			count += HeightHelper(r->lc);
		}else if(r->rc)
		{
			count += HeightHelper(r->rc);
		}
		return count;
	}

	template<typename T>
	int BinTree<T>::Height()const
	{
		return HeightHelper(root);
	}
main函数中对二叉树的功能进行测试
#include "stdafx.h"
#include <iostream>
#include "bintree.h"
using namespace std;
using namespace dataStructure;
void visit(const int &t) 
{
	cout << t << ",";
}
int main()
{
	BinTree<int> *bt = new BinTree<int>;
	bt->InitRoot(0);
	BinTreeNode<int>* r = bt->GetRoot();
	bt->InsertLeftChild(r, 1);
	bt->InsertRightChild(r, 2);
	BinTreeNode<int> *rlc = bt->LeftChild(r);
	BinTreeNode<int> *rrc = bt->RightChild(r);
	bt->InsertLeftChild(rlc, 3);
	bt->InsertRightChild(rlc, 4);
	bt->InsertLeftChild(rrc, 5);
	bt->InsertRightChild(rrc, 6);
	bt->InOrder(visit);
	delete bt;
	system("pause");
	return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值