【数据结构】二叉树的递归与非递归创建和遍历

数据结构—二叉树的非递归建立(先序和层次)和非递归遍历(四种)   二叉树的递归建立和遍历十分简单好写,为了加深对二叉树的理解这篇文章用c++实现了二叉树的建立,遍历,以及寻找根节点和别的节点之间的路径等功能,为了实现这些功能还写了必要的栈和队列的实现。1. 二叉树节点:typedef struct Btnode { // 二叉树单个节点    char data; //可以重复    struct Btnode *rchild; //右孩子(子树)    s... 阅读详情

下面代码所用到的测试用例画成树的样子长这样:


创建树时给的是数组,用‘#’代表非法值,即该结点为空。

二叉树的递归实现:

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

template<class T>
struct BinaryTreeNode
{
	BinaryTreeNode(T value=0)
	:_value(value), _left(NULL), _right(NULL)
	{}
	T _value;
	BinaryTreeNode<T>* _left;
	BinaryTreeNode<T>* _right;
};

template<class T>
class BinaryTree
{
public:
	typedef BinaryTreeNode<T> Node;
	BinaryTree()
	{}
	BinaryTree(T* a, size_t size, const T& invalid)
	{
		size_t index = 0;
		_root=_CreatTree( a, size,index, invalid);
	}
	BinaryTree(const BinaryTree<T>& bt)
	{
		_root = _Copy(bt._root);
	}
	BinaryTree<T>& operator=(BinaryTree<T>& bt)
	{
		if (this != &bt)
		{
			BinaryTree<T> tmp(bt);
			swap(tmp._root, _root);

		}
	}
	~BinaryTree()
	{
		_Distory(_root);
	}

	void PrevOrder()
	{
		_PrevOrder(_root);
		cout << endl;
	}
	void InOrder()
	{
		_InOrder(_root);
		cout << endl;
	}
	void PostOrder()
	{
		_PostOrder(_root);
		cout << endl;
	}
	void LevelOrder()  //层序遍历
	{
		_LevelOrder(_root);
		cout << endl;
	}

	size_t Size()
	{
		return _Size(_root);
	}
	size_t Depth()
	{
		return _Depth(_root);
	}
	size_t LeafSize()
	{
		return _LeafSize(_root);
	}
	size_t GetKLevel(size_t k)  //第K层结点个数
	{

	}
protected:

	Node* _Distory(Node* root)
	{
		if (root)
		{
			_Distory(root->_left);
			_Distory(root->_right);
			Node* del = root;
			delete del;
		}
		return root;
	}
	Node* _CreatTree( T*a, size_t size,size_t& index,const T& invalid)
	{
		Node* root = NULL;
		if ((index < size)&&(a[index] != invalid))
		{
			root = new Node(a[index]);
			root->_left = _CreatTree(a, size, ++index, invalid);
			root->_right = _CreatTree(a, size, ++index, invalid);
		}
		return root;
	}

	Node* _Copy(Node* copyroot)
	{
		Node* root = NULL;
		if (copyroot!=NULL)
		{
			root = new Node(copyroot->_value);
			root->_left = _Copy(copyroot->_left);
			root->_right = _Copy(copyroot->_right);
		}
		return root;
	}

	Node* _PrevOrder(Node* root)
	{
		if (root)
		{
			cout << root->_value << " ";
			_PrevOrder(root->_left);
			_PrevOrder(root->_right);
		}
		return root;
	}

	Node* _InOrder(Node* root)
	{
		if (root)
		{
			_InOrder(root->_left);
			cout << root->_value<<" ";
			_InOrder(root->_right);
		}
		return root;
	}

	Node* _PostOrder(Node* root)
	{
		if (root)
		{
			_PostOrder(root->_left);
			_PostOrder(root->_right);
			cout << root->_value << " ";
		}
		return root;
	}

	void _LevelOrder(Node* root)
	{
		queue<Node*> q;
		q.push(root);
		while (!q.empty())
		{
			Node* tmp = q.front();
			cout << tmp->_value<<" ";
			
			if (tmp->_left)
				q.push(tmp->_left);
			if (tmp->_right)
				q.push(tmp->_right);
			q.pop();
		}
	}

	size_t _Size(Node* root)
	{
		size_t size = 0;
		if (root)
		{
			size = _Size(root->_left) + _Size(root->_right)+1;
		}
		return size;
	}

	size_t _Depth(Node* root)
	{
		size_t depth1 = 0;
		size_t depth2 = 0;
		if (root)
		{
			depth1 = _Depth(root->_left) + 1;
			depth2 = _Depth(root->_right) + 1;
		}
		return depth1 > depth2 ? depth1 : depth2;
	}

	size_t _LeafSize(Node* root)
	{
		if (root == NULL)
			return 0;
		else if (root->_left == NULL&&root->_right == NULL)
			return 1;
		return _LeafSize(root->_left) + _LeafSize(root->_right);
	}
private:
	Node* _root;
};

void test()
{
	int array[10] = { 1, 2, 3, '#', '#', 4, '#', '#', 5, 6 };
	int array1[15] = { 1, 2, '#', 3, '#', '#', 4, 5, '#', 6, '#', 7, '#', '#', 8 };
	BinaryTree<int> bt(array, 10, '#');
	bt.PrevOrder();
	bt.InOrder();
	bt.PostOrder();
	cout << bt.Size() << endl;
	cout << bt.Depth() << endl;
	cout << bt.LeafSize() << endl;
	BinaryTree<int> bt2(array1, 15, '#');
	cout << bt2.Depth() << endl;
	cout << bt2.LeafSize() << endl;
	BinaryTree<int> bt3(bt);
	bt3.PrevOrder();
	BinaryTree<int> bt4=bt3;
	bt4.PrevOrder();
	bt4.LevelOrder();
}

递归的好处在于代码简练。但递归不容易理解。

非递归的二叉树(面试经常会考的):

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

template<class T>
struct BinaryTreeNode
{
	BinaryTreeNode(T value = 0)
	:_value(value), _left(NULL), _right(NULL)
	{}
	T _value;
	BinaryTreeNode<T>* _left;
	BinaryTreeNode<T>* _right;
};

template<class T>
class BinaryTree
{
public:
	typedef BinaryTreeNode<T> Node;
	BinaryTree()
	{}
	explicit BinaryTree(T* a, size_t size, const T& invalid)    //构造函数,创建一棵树。
	{
		stack<Node*> s;
		size_t index = 0;
		Node* cur = NULL;
		while (index < size)
		{
			while ((index < size) && (a[index] != invalid))
			{
				if (index == 0)
				{
					_root = new Node(a[index++]);
					cur = _root;
				}
				else
				{
					cur->_left = new Node(a[index++]);
					cur = cur->_left;
				}
				s.push(cur);
			}
			index++;
			Node* top = s.top();
			s.pop();
			if ((index < size) && (a[index] != invalid))
			{
				cur = top;
				cur->_right = new Node(a[index++]);
				cur = cur->_right;
				s.push(cur);
			}
		}
	}

	BinaryTree(const BinaryTree<T>& bt)  //拷贝构造
	{
		Node* cur = bt._root;
		Node* root = NULL;
		stack<Node*>s;
		stack<Node*>s1;
		while (cur || !s.empty())
		{
			while (cur)
			{
				s.push(cur);
				if (root == NULL)
				{
					root = new Node(cur->_value);
					_root = root;
				}
				else
				{
					root->_left = new Node(cur->_value);
					root = root->_left;
				}
				cur = cur->_left;
				s1.push(root);
			}
			Node* top = s.top();
			Node* top1 = s1.top();
			s.pop();
			s1.pop();

			cur = top->_right;
			if (cur)
			{
				root = top1;
				root->_right = new Node(cur->_value);
				root = root->_right;
				cur = cur->_left;
			}
		}
	}

	BinaryTree<T>& operator=(BinaryTree<T> bt)
	{
		swap(_root, bt._root);
		return *this;
	}

	void PrevOrderNoR()
	{
		Node* cur = _root;
		stack<Node*> s;
		while (cur || !s.empty())
		{
			while (cur)
			{
				cout << cur->_value << " ";
				s.push(cur);
				cur = cur->_left;
			}
			Node* top = s.top();
			s.pop();
			cur = top->_right;
		}
		cout << endl;
	}
	void InOrderNoR()
	{
		Node* cur = _root;
		stack<Node*> s;
		while (cur || !s.empty())
		{
			while (cur)
			{
				s.push(cur);
				cur = cur->_left;
			}
			Node* top = s.top();
			s.pop();
			cout << top->_value << " ";
			cur = top->_right;
		}
		cout << endl;
	}

	void PostOrderNoR()
	{
		Node* cur = _root;
		Node* prev = NULL;
		stack<Node*> s;
		while (cur || !s.empty())
		{
			while (cur)
			{
				s.push(cur);
				cur = cur->_left;
			}
			Node* top = s.top();
			
			if ((top->_right == NULL) || (prev == top->_right))
			{
				prev = top;
				cout << top->_value << " ";
				s.pop();
				//cur = top->_right;
			}
			else
				cur = top->_right;
		}
		cout << endl;
	}

	size_t SizeNoR()
	{
		size_t size = 0;
		Node* cur = _root;
		stack<Node*> s;
		while (cur || !s.empty())
		{
			while (cur)
			{
				s.push(cur);
				size++;
				cur = cur->_left;
			}
			Node* top = s.top();
			s.pop();
			cur = top->_right;
		}
		return size;
	}

	size_t DepthNoR()
	{
		if (_root == NULL)
			return 0;
		size_t depth = 0;
		Node* cur = NULL;
		queue<Node*> q;
		size_t VisitNum = 0;  //有多少数据出栈
		size_t NodeNum = 1;
		size_t LeveNum = 1;  //每一层最后一个数据的序号
		q.push(_root);
		while (!q.empty())
		{
			cur = q.front();
			q.pop();
			VisitNum++;
			
			if (cur->_left)
			{
				NodeNum++;
				q.push(cur->_left);
			}
			if (cur->_right)
			{
				NodeNum++;
				q.push(cur->_right);
			}
			if (LeveNum == VisitNum)
			{
				depth++;
				LeveNum = NodeNum;
			}
		}
		return depth;
	}

	size_t LeveNum()  //叶子节点个数
	{
		size_t count = 0;
		Node* cur = _root;
		stack<Node*> s; 
		while (cur || !s.empty())
		{
			while (cur)
			{
				s.push(cur);
				if ((cur->_left == NULL) && (cur->_right == NULL))
					count++;
				cur = cur->_left;
			}

			Node* top = s.top();
			s.pop();
			cur = top->_right;
		}
		return count;
	}
	size_t GetKLeve(size_t k)  //得到第k层结点个数。
	{
		assert(k <= DepthNoR());
		if (k == 1)
			return 1;
		queue<Node*>q;
		size_t NodeNum = 1;
		size_t LeveNum = 1;
		size_t VisitNum = 0;
		size_t leve = 1;
		q.push(_root);
		while (!q.empty())
		{
			Node* cur = q.front();
			q.pop();
			VisitNum++;
			if (cur->_left)
			{
				q.push(cur->_left);
				NodeNum++;
			}
			if (cur->_right)
			{
				q.push(cur->_right);
				NodeNum++;
			}
			if (LeveNum == VisitNum)
			{
				leve++;
				if (leve == k)
					break;
				LeveNum = NodeNum;
			}
		}
		return NodeNum - VisitNum;
	}
private:
	Node* _root;
};

void test()
{
	int array[10] = { 1, 2, 3, '#', '#', 4, '#', '#', 5, 6 };
	BinaryTree<int> bt(array, 10, '#');
	bt.PrevOrderNoR();
	bt.InOrderNoR();
	bt.PostOrderNoR();
	BinaryTree<int> bt1(bt);
	bt1.PrevOrderNoR();
	BinaryTree<int> bt2 = bt1;
	bt2.PrevOrderNoR();
	cout << bt.SizeNoR() << endl;
	cout << bt.DepthNoR() << endl;
	cout << bt.LeveNum() << endl;
	cout << bt.GetKLeve(3) << endl;
}

可以看到,非递归相对来说代码量能多点,但是比较容易理解,而且几个遍历过程代码十分相似,理解其中一个,后面几个都是类似的。

C++实现二叉树的创建以及四种遍历方式(递归与非递归) C++实现二叉树的创建以及四种遍历方式(递归与非递归) 语言这个东西不用真的会忘, 我记得前前后后C++的基本语法我也看了好几遍了,一直没有动手写过什么东西,所以一遍遍的看,一遍遍的忘… … 正好最近在看数据结构,想着自己用C++来实现一下,一方面是熟悉整个逻辑过程,加深对数据结构的理解,另一方面,也熟悉一下C++。 下图是我们要创建的二叉树,其中的#代表空字符; 为了验证我们程序的正确性,现给出此二叉树的四种遍历结果: 前序遍历(Preorder traversal): A B C D E F 阅读详情

相关推荐

数据结构c语言版建立二叉树,中序非递归遍历(实验报告)

编写程序,用先序递归的方法建立二叉树,建立二叉树后,用中序非递归方法遍历该二叉树,并输出遍历序列。

数据结构(六):二叉树的创建、递归遍历与非递归遍历、层次遍历

数据结构(六)——二叉树的创建、递归遍历与非递归遍历、层次遍历

ReadyGo!!!的博客 1831

数据结构-二叉树递归-非递归实现

数据结构实验二叉树用递归实现先序遍历、中序遍历和后序遍历,用几种不同非递归方法实现了中序遍历,代码附有详细注释

二叉树——创建和遍历(递归、非递归)

递归二叉树 非递归二叉树

阿基美德的博客 1034

【模拟IC】从VCD到VEC:Cadence数模混合仿真中高效激励转换与HSIM工具链实战

本文详细解析了在Cadence数模混合仿真中,如何利用HSIM工具链的vcd2vec命令,将数字仿真生成的VCD文件高效转换为模拟仿真器所需的VEC格式激励文件。文章提供了从VCD文件预处理、io_top.sig文件编写、核心命令参数详解到Cadence ADE环境集成验证的全链路实战指南,并分享了自动化脚本方案,旨在解决数模混合验证中的“语言不通”难题,提升仿真效率。

k9l0m1的博客 123

APK静态分析(取证角度)——理论部分

APP是指应用程序(Application),是指能够在手机、平板电脑、电脑等移动设备上运行的软件。APP可以帮助用户进行各种功能操作,如社交媒体、游戏、购物、学习、工作等。用户可以通过应用商店或者在线下载安装APP,然后在设备上使用它们。APP的种类非常丰富,能够满足用户不同的需求和兴趣。

currify的博客 3210

数据结构C语言描述9(图文结合)--二叉树和特殊书的概念,二叉树“最傻瓜式创建”与前中后序的“递归”与“非递归遍历”

二叉树是n (n≥0)个结点的有限集合。每个节点最多有两个子节点,分别称为左子节点和右子节点。左子节点和右子节点可以为空。二叉树的子树也是二叉树。

羊小猪~~的博客 1614

JetBrains Air:多Agent协同的IDE运行时架构解析

IDE智能编程正从单模型增强迈向多Agent协同范式。多Agent架构通过职责分离、上下文精简与运行时隔离,显著提升代码生成稳定性与合规性;其核心依赖轻量级嵌入式运行时(如ARL),支持AST级内存共享、eBPF安全拦截与毫秒级冷启动。该架构天然适配本地化部署、离线开发与高安全合规场景(如PCI-DSS、金融内网),并为Java/Python/TS等语言提供可扩展的规则驱动开发流水线。JetBrains Air正是这一技术路径的工程化落地代表。

weixin_30443075的博客 573

数据结构复习:链式二叉树创建和递归遍历

二叉链表中,每个结点除了存储本身的数据外,还应该设置两个指针域left和right,它们分别指向左孩子和右孩子。 当需要在二叉树中经常寻找某结点的双亲,每个结点还可以加一个指向双亲的指针域parent,这就是三叉链表, 下面的两幅图分别就是,二叉链表和三叉链表的数据结构: 和 二叉树的结构有一些性质来用于帮助我们建树: ...

weixin_30897233的博客 256

Claude Code本地Windows安装教程

本文介绍了在Windows系统上安装和配置Claude Code本地调用的详细步骤。首先需要确保网络畅通和账号余额充足,然后安装Node.js v22版本作为基础环境。接着通过npm全局安装Claude Code包,并进行版本验证。安装完成后,使用命令行登录并可以指定模型启动。最后还提供了切换API秘钥的方法,通过setup-token命令重新授权账号。整个过程配有详细的命令行示例和操作截图,方便用户按步骤完成安装配置。

猿小白的博客 2万+

30. 如何使用 SEGW 的 redefine 功能对 SAP 标准 OData 服务进行扩展

SAP 发布了很多标准的 Fiori 应用,可以通过笔者的文章里提到的进行浏览。比如 My Opportunities 就是 SAP CRM 领域的一个 Fiori 应用:下图是 Opportunity 明细页面的 Info 标签页:假设我们想在这些标准字段的末尾增添一个新字段 Created By,用来维护当前 Opportunity 的创建者。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 1176

数据结构和算法--二叉树创建和递归遍历

//完全二叉树的创建以及遍历(递归) #include #include //定义数据类型 typedef int datatype_t; //定义结构体 typedef struct node{ datatype_t data; struct node *lchild; struct node *rchild; }bitree_t; //创建一个二叉树(n表示结点总数,i表示根

u011266694的专栏 421

16、保障Azure应用安全:密钥管理与身份认证

本文深入探讨了保障Azure应用安全的关键措施,包括使用网络安全工具(如Application Gateway和Azure Front Door)防范攻击,解决传统密钥和机密存储方式的安全隐患,以及通过Azure Key Vault实现敏感信息的安全管理。同时,介绍了使用托管标识实现Azure资源间安全访问的方法,并结合实际操作步骤展示了如何配置Key Vault、设置访问策略、存储机密以及授予Web应用对SQL Server的访问权限。最后,对不同安全措施进行了比较,并提出了在开发、测试及生产环境中的综合

rock5的博客 72

二叉树的创建和遍历(递归遍历 · 数据结构)

这是数据结构里面的二叉树的创建和遍历,也是按照书本的思路打的,如果大家对于我的代码有什么好的建议,可以留言告诉我,或者如果你也是大一学这个,可以参考一下我写的。#include&lt;stdio.h&gt; #include&lt;malloc.h&gt; #define MAXSIZE 10000 typedef struct TNode *Position; typedef Posit...

Mas的博客 905

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

数据结构笔记6——二叉树的递归创建和遍历

对于T->data.data和T->data,按理来说应该用前者,但是在运行过程中,一开始用前者结构是错的,后来又改成后者。在三次打印中,这两个都用到了,最后的结果也是正确的。先序,后序,中序遍历的递归算法打印。通过先序递归遍历创建。

qq_62861369的博客 264

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

数据结构: 递归先序创建二叉树及其先序,中序和后序遍历

递归先序创建二叉树及其先序,中序和后序遍历:(C语言实现如下)#include&lt;stdio.h&gt; #include&lt;stdlib.h&gt; //前序创建二叉树 //先 中 后 遍历二叉树 //层序遍历(队列) //计算二叉树的深度 #define OK 1 #define ERROR 0 #define MAXSIZE 100 typedef char BTElementyp...

-_- 1627

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

数据结构--树和二叉树--二叉树的创建和遍历(递归和非递归方式)

首先给出二叉树的定义:二叉树是一种shu xing

littlebeat123的专栏 872

数据结构: 非递归先序创建二叉树及其先序,中序和后序遍历

非递归先序创建二叉树及其先序,中序和后序遍历:#include&lt;stdio.h&gt; #include &lt;stdlib.h&gt; #include &lt;string.h&gt; #define MAXSIZE 100 typedef struct BTNode { char data; struct BTNode *lchild, *rchild; } BT...

-_- 800

数据结构(二叉树系列)先序创建三种遍历和求深度(递归实现)

typedef struct BiTNode{ // 二叉树结点结构 char data; // 结点数据 struct BiTNode *lchild; // 左孩子 struct BiTNode *rchild; // 右孩子 }BiTNode,*BiTree; BiTree CreateBiTree(BiTree T);void TraversalBiTree1(BiTree T);void

mr253727942的专栏 1604

二叉树的创建与遍历(递归)

一.二叉树的创建 typedef struct TreeNode { char data; struct TreeNode *left; struct TreeNode *right; } 1.C语言 void CreateTree(TreeNode **T) { char data; scanf("%d",&data); //输入节点数...

weixin_30332705的博客 298

数据结构实验-C语言-二叉树的创建,前、中、后序遍历的递归算法和非递归算法,求叶子结点数目,求二叉树深度,判断二叉树是否相似,求二叉树左右子树互换,二叉树层序遍历的算法,判断二叉树是否是完全二叉树

1.实验目的 熟练掌握二叉树的二叉链表存储结构的C语言实现。掌握二叉树的基本操作-前序、中序、后序遍历二叉树的三种方法。了解非递归遍历过程中“栈”的作用和状态,而且能灵活运用遍历算法实现二叉树的其它操作。 2.实验内容 (1)二叉树的二叉链表的创建 (2)二叉树的前、中、后序遍历的递归算法和非递归算法的实现 (3)求二叉树中叶子结点数目的递归算法。 (4)编写求二叉树深度的递归算法。 ...

J_SUNV的博客 3838

【数据结构】二叉树的创建和遍历(先序、中序、后序)

二叉树的创建和遍历:先序中序后序 最近一段时间学习了数据结构中二叉树的基本操作,包括二叉树的结构、二叉树的创建、递归先序中序后序遍历、非递归遍历等,想和网友一起共同交流。

m0_63448210的博客 2万+

【数据结构】二叉树的创建和四种遍历(附带详细注释)

树是一种比起线性表更加复杂的存储结构,其是一种非常重要的非线性数据结构,树结构在客观世界中普遍存在,其中二叉树的运用最为广泛。本篇文章主要介绍了二叉树的链式存储结构(即二叉链表)的创建与遍历,这将为以后对二叉树的研究起到至关重要的作用。............

weixin_65334260的博客 4926
上一篇: 【STL】 vector 模拟实现
下一篇: 【java】简单继承练习
pointer_y
博客等级 码龄11年 157粉丝 107原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值