BinaryTree

本文介绍了一种在Linux环境下实现二叉树的方法,包括递归建立二叉树及先序、中序、后序和层序遍历等核心操作。通过具体的代码示例和测试用例展示了二叉树的创建过程及其遍历结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 二叉树是一个比较重要的数据结构,这篇文章将基于linux下实现BinaryTree


 一.进入工作目录,我自己在工作目录下建了一个DataStruct的目录。

 $touch BinaryTree.cpp 的文件

 $vim BinaryTree.cpp 


wKiom1dEgavAyOF_AAAkKfdqRTU485.png


 二.二叉树

  1).二叉树的建立 -- 递归建立


wKioL1dEgznTjs8xAAAnsZo0mMk827.png


 需要注意的点

  a.index为数组下标索引,因为是递归建立,所以必须传引用。

  b.invaild为无效数值,可以终止数的向下生长。

 2).二叉树的先序遍历

wKioL1dEhA3S4G71AAAfc59h28M282.png

  a.先序遍历根节点,再遍历左子树,后遍历右子树。

 3).二叉树的中序遍历

wKioL1dEhPSDJ2E1AAAfNG5wDZ8250.png

a.先序遍历左子树,再遍历根节点,后遍历右子树。

 4).二叉树的后序遍历

wKioL1dEhTmxk37JAAAf-nZYNFQ460.png

a.先序遍历左子树,再遍历右子树,后遍历根节点。

 5).二叉树的层序遍历

wKioL1dEhaezWG-BAAA3ZC74P34777.png


a.借用队列先进先出的特性,先压根节点,之后访问根节点,pop根节点,压入左右子数,以此访问。


 三.测试用例

wKioL1dEhmjihkQjAAAfFbANyHU133.png


wKiom1dEhbbiN9r0AABYigy2Aro631.png


$g++ -o BinaryTree BinaryTree.cpp -g (-g 是加入调试信息,方便gdb调试)

$./BinaryTree


结果

wKioL1dEhzHjGanyAAAZ78xiBrM228.png


附件:


代码:

#pragma once
#include<iostream>
using namespace std;
#include<queue>


template<class T>
struct BinaryTreeNode
{
	BinaryTreeNode(const T& x)
	:_data(x)
	, _left(NULL)
	, _right(NULL)
	{}


	T _data;
	BinaryTreeNode<T>* _left;
	BinaryTreeNode<T>* _right;
};

template<class T>
class BinaryTree
{
	typedef BinaryTreeNode<T> Node;
public:
	BinaryTree()
		:_root(NULL)
	{}

	BinaryTree(const T* a, size_t size, const T& invaild)
	{
		size_t index = 0;
		_root = _BinaryTree(a, size, index, invaild);
	}

	~BinaryTree()
	{}

	BinaryTree(const BinaryTree<T>& t)
	{
		_root = _Copy(t._root);
	}

	void prevOrder()   //前序遍历
	{
		_prevOrder(_root);
		cout << endl;
	}

	void inOrder()     //中序遍历
	{
		_inOrder(_root);
		cout << endl;
	}

	void nextOrder()    //后序遍历
	{
		_nextOrder(_root);
		cout << endl;

	}

	void levelOrder()
	{
		_levelOrder(_root);
	}

	size_t size()
	{
		return _size(_root);
	}

	size_t Depth()
	{
		return _Depth(_root);
	}

	size_t leafsize()
	{
		return _leafsize(_root);
	}

	size_t GetKLevel(int k)
	{
		return _GetKLevel(int k);
	}

protected:

	void _Destroy(Node* root)
	{
		if (root == NULL)
		{
			return;
		}
		//--------------------------------------------------
		_Destroy(root->_left);
		_Destroy(root->_right);

		_Destroy root;

	}

	Node* _Copy(Node* root)
	{
		if (root == NULL)
		{
			return NULL;
		}

		Node* newRoot = new Node(root->_data);
		newRoot->_left = _Copy(root->_left);
		newRoot->_right = _Copy(root->_right);

		return newRoot;
	}


	Node* _BinaryTree(const T* a, size_t size, size_t& index, const T& invaild)    //必须要给index加引用
	{
		Node* root = NULL;
		if (index < size && a[index] != invaild)
		{
			root = new Node(a[index]);
			root->_left = _BinaryTree(a, size, ++index, invaild);
			root->_right = _BinaryTree(a, size, ++index, invaild);
		}
		return root;
	}
	

	void _prevOrder(Node* root)
	{
		//Node* cur = root;
		if (root == NULL)
		{
			return;
		}
		cout << root->_data << " ";
		_prevOrder(root->_left);
		_prevOrder(root->_right);
	}

	void _inOrder(Node* root)
	{
		if (root == NULL)
		{
			return;
		}
		_inOrder(root->_left);
		cout << root->_data << " ";
		_inOrder(root->_right);
	}

	void _nextOrder(Node* root)
	{
		if (root == NULL)
		{
			return;
		}
		_nextOrder(root->_left);
		_nextOrder(root->_right);
		cout << root->_data << " ";
	}

	size_t _size(Node* root)
	{
		if (root == NULL)
		{
			return 0;
		}
		//左子树加上右子树加上根节点

		return _size(root->_left) + _size(root->_right) + 1;
	}

	//size_t _Depth(Node* root)
	//{
	//	if (root == NULL)
	//	{
	//		return 0;
	//	}
	//	return _Depth(root->_left) > _Depth(root->_right) ? _Depth(root->_left)+1 : _Depth(root->_right)+1;   //效率太低
	//}

	size_t _Depth(Node* root)
	{
		if (root == NULL)
		{
			return 0;
		}
		int leftdepth = _Depth(root->_left);   //---------------------------------
		int rightdepth = _Depth(root->_right);

		return leftdepth > rightdepth ? leftdepth+1 : rightdepth+1;
	}

	size_t _leafsize(Node* root)
	{
		static size_t size = 0;
		if (root == NULL)
		{
			return 0;
		}

		if (root->_left == NULL && root->_right == NULL)
		{
			++size;
			return size;
		}
		
		_leafsize(root->_left);
		_leafsize(root->_right);

		return size;
	}

	size_t _GetKLevel(int k)
	{
		if (_root == NULL)
		{
			return 0;
		}

		if (k == 1)
		{
			return 1;
		}


		Node* cur = _root;
		static size_t LeafKSize = 0;
		static size_t Level = 1;

		if (Level == k - 1)
		{
			
			if (_root->_left != NULL)
			{
				leafsize++;
			}

			if (_root->_right != NULL)
			{
				leafsize++;
			}

		}

		Level++;
		_GetKLevel(_root->_left);
		_GetKLevel(_root->_right);
	}

	void _levelOrder(Node* root)
	{
		if (root == NULL)
		{
			return;
		}
		queue<Node*> qTree;
		qTree.push(root);
		while (!qTree.empty())
		{
			Node* cur = qTree.front();
			qTree.pop();
			cout << cur->_data << " ";
			if (cur->_left)
			{
				qTree.push(cur->_left);
			}

			if (cur->_right)
			{
				qTree.push(cur->_right);
			}
		}
		cout << endl;
	}
	

protected:
	Node* _root;
};

 以上就是本人在学习过程中的一些经验总结。当然,本人能力有限,难免会有纰漏,希望大家可以指正。

本文出自 “做一个小小小司机” 博客,请务必保留此出处http://10799170.blog.51cto.com/10789170/1782797

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值