二叉链表(8种遍历方式)

目录

结点类:

二叉链表类(8种遍历方式等):

测试程序:


二叉链表的八种遍历方式:非递归先序遍历、非递归中序遍历、非递归后序遍历、非递归层序遍历、递归先序遍历、递归中序遍历、递归后序遍历、递归层序遍历

结点类:

#pragma once

#include <string>

template<typename T>
class tree_node
{
private:
	T _data;
	tree_node<T>* _left;
	tree_node<T>* _right;
public:
	tree_node(T data = 0, tree_node<T>* left = NULL, tree_node<T>* right = NULL) :_data(data),
		_left(left), _right(right) {}
	~tree_node() = default;

	T get_data(void) const
	{
		return _data;
	}

	tree_node<T>* get_node(std::string direction) const
	{
		if (direction == "left")
		{
			return _left;
		}
		else
		{
			return _right;
		}
	}

	void set(std::string instruction, T data = 0, tree_node<T>* node=NULL)
	{
		if (instruction == "data")
		{
			_data = data;
		}
		else if (instruction == "left")
		{
			_left = node;
		}
		else
		{
			_right = node;
		}
		return;
	}
};

二叉链表类(8种遍历方式等):

#pragma once

#include <string>
#include <vector>
#include <stack>

#include "tree_node.h"

//二叉树链式存储
template<typename T>
class binary_tree
{
private:
	int _number_node;
	int _layer;
	tree_node<T>* _head;
	//备用指针用于打印时显示空结点
	tree_node<T>* _spare_node;	
	//备用参数,递归层序遍历时有用
	int _spare_number;

public:
	binary_tree(int number_node = 0, tree_node<T>* head = NULL) :
		_number_node(number_node),_head(head)
	{
		int layer = 1;
		for (int number = number_node; number >= 2; number /= 2)
		{
			layer++;
		}
		_layer = layer;
		_spare_node = new tree_node<T>;
		_spare_number = 0;
	}
	~binary_tree(void) = default;

	//传入一个数组,层序顺序构造完全二叉树
	void set_tree(std::vector<T> data_list)
	{
		//node_list是一个数组头指针
		tree_node<T>* node_list = new tree_node<T>[_number_node];
		for (int x = 0; x < _number_node; x++)
		{
			node_list[x].set("data", data_list[x], NULL);
		}
		for (int x = 1; x <= _number_node; x++)
		{
			if (x * 2 > _number_node)
			{
				break;
			}
			node_list[x - 1].set("left", 0, &node_list[x * 2 - 1]);
			if (x * 2 + 1 > _number_node)
			{
				break;
			}
			node_list[x - 1].set("right", 0, &node_list[x * 2]);
		}
		//输入头结点
		_head = node_list;
		return;
	}

	//实现二叉树的4种遍历算法的递归和非递归形式, 返回值是结点指针
	//recursion代表是否递归,order代表顺序
	void traverse(std::string recursion, std::string order, std::vector<tree_node<T>*> &node_list, 
		tree_node<T>* temp_node)
	{
		//递归
		if (recursion == "recursion")
		{
			if (temp_node == NULL)
			{
				_spare_number = 0;
				return;
			}
			//先序遍历
			if (order == "preorder")
			{
				node_list.push_back(temp_node);
				traverse(recursion, order, node_list, temp_node->get_node("left"));
				traverse(recursion, order, node_list, temp_node->get_node("right"));
			}
			//中序遍历
			else if (order == "inorder")
			{
				traverse(recursion, order, node_list, temp_node->get_node("left"));
				node_list.push_back(temp_node);
				traverse(recursion, order, node_list, temp_node->get_node("right"));
			}
			//后序遍历
			else if (order == "postorder")
			{
				traverse(recursion, order, node_list, temp_node->get_node("left"));
				traverse(recursion, order, node_list, temp_node->get_node("right"));
				node_list.push_back(temp_node);
			}
			//层序遍历
			else
			{
				if (_spare_number == 0)
				{
					node_list.push_back(temp_node);
					if (temp_node->get_node("left"))
					{
						node_list.push_back(temp_node->get_node("left"));
					}
					if (temp_node->get_node("right"))
					{
						node_list.push_back(temp_node->get_node("right"));
					}
					_spare_number++;
				}
				else
				{
					if (temp_node->get_node("left"))
					{
						node_list.push_back(temp_node->get_node("left"));
					}
					if (temp_node->get_node("right"))
					{
						node_list.push_back(temp_node->get_node("right"));
					}
					_spare_number++;
				}
				if (_spare_number < node_list.size())
				{
					traverse(recursion, order, node_list, node_list[_spare_number]);
				}
			}
		}
		//非递归
		else 
		{
			//先序遍历
			if (order == "preorder")
			{
				std::stack<tree_node<T>*> node_stack;
				while (temp_node != NULL || !node_stack.empty())
				{
					while (temp_node != NULL)
					{
						node_list.push_back(temp_node);
						node_stack.push(temp_node);
						temp_node = temp_node->get_node("left");
					}
					if (!node_stack.empty())
					{
						temp_node = node_stack.top();
						node_stack.pop();
						temp_node = temp_node->get_node("right");
					}
				}
			}
			//中序遍历
			else if (order == "inorder")
			{
				std::stack<tree_node<T>*> node_stack;
				while (temp_node != NULL || !node_stack.empty())
				{
					while (temp_node != NULL)
					{
						node_stack.push(temp_node);
						temp_node = temp_node->get_node("left");
					}
					if (!node_stack.empty())
					{
						temp_node = node_stack.top();
						node_list.push_back(temp_node);
						node_stack.pop();
						temp_node = temp_node->get_node("right");
					}
				}
			}
			//后序遍历
			else if (order == "postorder")
			{
				std::stack<tree_node<T>*> node_stack;
				tree_node<T>* pre_node = NULL;
				node_stack.push(temp_node);
				while (!node_stack.empty())
				{
					temp_node = node_stack.top();
					if ((temp_node->get_node("left") == NULL && temp_node->get_node("right") == NULL) ||
						(pre_node != NULL && (pre_node == temp_node->get_node("left") ||
							pre_node == temp_node->get_node("right"))))
					{
						node_list.push_back(temp_node);
						node_stack.pop();
						pre_node = temp_node;
					}
					else
					{
						if (temp_node->get_node("right") != NULL)
							node_stack.push(temp_node->get_node("right"));
						if (temp_node->get_node("left") != NULL)
							node_stack.push(temp_node->get_node("left"));
					}
				}
			}
			//层序遍历
			else
			{
				node_list.push_back(temp_node);
				for (int x = 0; x < node_list.size(); x++)
				{
					if (node_list[x]->get_node("left"))
					{
						node_list.push_back(node_list[x]->get_node("left"));
					}
					if (node_list[x]->get_node("right"))
					{
						node_list.push_back(node_list[x]->get_node("right"));
					}
				}
			}
		}
		return;
	}


	//按照形状打印树
	void print(void) const
	{
		//层序遍历,保留空结点
		std::vector<tree_node<T>*> node_list;
		node_list.push_back(_head);
		for (int x = 0; x < (std::pow(2, _layer - 1) - 1); x++)
		{
			if (node_list[x]->get_node("left") != NULL)
			{
				node_list.push_back(node_list[x]->get_node("left"));
			}
			else
			{
				node_list.push_back(_spare_node);
			}
			if (node_list[x]->get_node("right") != NULL)
			{
				node_list.push_back(node_list[x]->get_node("right"));
			}
			else
			{
				node_list.push_back(_spare_node);
			}
		}
		//打印
		std::cout << "数的高度:"<< _layer << std::endl;
		std::cout << "整棵树如下:" << std::endl;
		std::cout << node_list[0]->get_data() << std::endl;
		node_list.erase(node_list.begin());
		for (int x = 1; x <= (_layer - 1); x++)
		{
			for (int y = (int)std::pow(2, x); y < (int)std::pow(2, x + 1); y++)
			{
				if (node_list[0] == _spare_node)
				{
					std::cout << "#" << " ";
					node_list.erase(node_list.begin());
				}
				else
				{
					std::cout << node_list[0]->get_data() << " ";
					node_list.erase(node_list.begin());
				}
			}
			std::cout << std::endl;
		}
		return;
	}

	//按照结点指针数组打印树
	void print(std::vector<tree_node<T>*> node_list) const
	{
		for (auto x : node_list)
		{
			std::cout << x->get_data() << " ";
		}
		std::cout << std::endl;
	}

	//按照给定遍历顺序遍历并打印树
	void print(std::string recursion, std::string order)
	{
		std::vector<tree_node<T>*> node_list;
		traverse(recursion, order, node_list, _head);
		print(node_list);
	}

	//查找叶子结点
	void print_leaf_node(void)
	{
		std::vector<tree_node<T>*> node_list;
		int number=0;
		traverse("non-recursion", "levelorder", node_list, _head);
		std::cout << "叶子结点:";
		for (auto x : node_list)
		{
			if (x->get_node("left")==NULL && x->get_node("right")==NULL)
			{
				number++;
				std::cout << x->get_data() <<" ";
			}
		}
		std::cout << std::endl << "叶子结点数目:"<< number ;
	}
};

测试程序:

#include <iostream>
#include <vector>
#include <string>

#include "binary_tree.h"

int main(void)
{
	binary_tree<int> instance_binary_tree(10);
	std::vector<int> number_list;
	for (int x = 0; x < 10; x++)
	{
		number_list.push_back(x + 1);
	}
	instance_binary_tree.set_tree(number_list);

	instance_binary_tree.print();
	std::cout << std::endl;

	std::cout << "递归先序遍历:";
	instance_binary_tree.print("recursion", "preorder");
	std::cout << "递归中序遍历:";
	instance_binary_tree.print("recursion", "inorder");
	std::cout << "递归后序遍历:";
	instance_binary_tree.print("recursion", "postorder");
	std::cout << "递归层序遍历:";
	instance_binary_tree.print("recursion", "levelorder");
	std::cout << "非递归先序遍历:";
	instance_binary_tree.print("non-recursion", "preorder");
	std::cout << "非递归中序遍历:";
	instance_binary_tree.print("non-recursion", "inorder");
	std::cout << "非递归后序遍历:";
	instance_binary_tree.print("non-recursion", "postorder");
	std::cout << "非递归层序遍历:";
	instance_binary_tree.print("non-recursion", "levelorder");
	std::cout << std::endl;

	instance_binary_tree.print_leaf_node();
	std::cout << std::endl;


	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值