数据结构——第5章 树和二叉树

news2024/11/18 4:16:48

1 二叉树

二叉树和树都属于树形结构,但两者互不包含。即二叉树不是特殊的树。

1.1 二叉树的基本概念

1.2 二叉树的顺序存储

仅适用于完全二叉树

#define MaxSize 100
typedef int ElemType; 
typedef struct TreeNode{
	ElemType value;//结点中的数据元素
	bool isEmpty;//结点是否为空 
}TreeNode;

构造结点数为MaxSize的完全二叉树t。 

TreeNode t[MaxSize];

1.3 二叉树的链式存储

1.3.1 二叉链表

typedef struct BiNode{
	ElemType data;//数据域 
	struct BiNode *lchild,*rchild;//左右孩子指针  
}BiNode,*BiTree; 

二叉链表具体实现:

#include<iostream>
#include<stack> 
#include<queue>
using namespace std;
typedef char ElemType; 
//二叉树的结点(链式存储)
typedef struct BiNode{
	ElemType data;//数据域 
	struct BiNode *lchild,*rchild;//左右孩子指针 
//	struct BiTNode *parent;//父节点指针  三叉链表 
}BiNode,*BiTree; 
//先序遍历的顺序建立二叉链表
void CreateBiTree(BiTree &T){
	char ch;
	cin>>ch;
	if(ch=='#') T=NULL;
	else{
		T=new BiNode;
		T->data=ch; 
		CreateBiTree(T->lchild);
		CreateBiTree(T->rchild);
	}
} 
//先序遍历
void PreOrder(BiTree T){
	if(T!=NULL){
		cout<<T->data<<" ";
		PreOrder(T->lchild);
		PreOrder(T->rchild);
	}
} 
//中序遍历
void InOrder(BiTree T){
	if(T!=NULL){
		PreOrder(T->lchild);
		cout<<T->data<<" ";
		PreOrder(T->rchild);
	}
}
//后序遍历
void AfterOrder(BiTree T){
	if(T!=NULL){
		PreOrder(T->lchild);
		PreOrder(T->rchild);
		cout<<T->data<<" ";
	}
}
//非递归调用的先序遍历
void  PreOrderTree(BiTree T){
	stack<BiNode *> s;
	while(T||!s.empty()){
		while(T){
			cout<<T->data;
			s.push(T);
			T=T->lchild;
		}
		if(!s.empty()){
			T=s.top();
			s.pop();
			T=T->rchild;
		}
	}
	cout<<endl;
}
//非递归调用的中序遍历
void  InOrderTree(BiTree T){
	stack<BiNode *> s;
	while(T||!s.empty()){
		while(T){
			s.push(T);
			T=T->lchild;
		}
		if(!s.empty()){
			T=s.top();
			s.pop();
			cout<<T->data;
			T=T->rchild;
		}
	}
	cout<<endl;
}

//非递归调用的后序遍历
void AfterOrderTree(BiTree T){
	stack<BiNode*> s;
	BiNode* lastVisited = NULL; // 记录上一个访问过的结点
	while (T || !s.empty()) {
		while (T) {
			s.push(T);
			T = T->lchild;
		}
		if (!s.empty()) {
			BiNode* topNode = s.top();
			if (topNode->rchild && topNode->rchild != lastVisited) {
				T = topNode->rchild;
			} else {
				cout << topNode->data;
				lastVisited = topNode;	
				s.pop();
			}
		}
	}
	cout << endl;
}
//层次遍历
void LevelOrder(BiTree T){
	queue<BiNode *> q;
	q.push(T);
	while(q.size()){
		BiNode *f=q.front();
		q.pop();
		cout<<f->data;
		if(f->lchild!=NULL){
			q.push(f->lchild);
		}
		if(f->rchild!=NULL){
			q.push(f->rchild);
		}
	}
	cout<<endl; 
} 
//复制二叉树
void Copy(BiTree T,BiTree &NewT){
	if(T==NULL){
		NewT=NULL;
		return;
	}else{
		NewT=new BiNode;
		NewT->data=T->data;
		Copy(T->lchild,NewT->lchild);
		Copy(T->rchild,NewT->rchild);
	}
} 
//计算二叉树的深度
int Depth(BiTree T){
	if(T==NULL){
		return 0;
	}
	int m=Depth(T->lchild);
	int n=Depth(T->rchild);
	if(m>n){
		return m+1;
	}else{
		return n+1;
	}
} 
//统计二叉树中结点的个数
int NodeCount(BiTree T){
	if(T==NULL) return 0;
	else return NodeCount(T->lchild)+NodeCount(T->rchild)+1;
} 
int main(){
	BiTree T;
	cout<<"------------------创建二叉链表(先序遍历的顺序)------------------"<<endl;
	CreateBiTree(T);
	cout<<"创建完成:";
	PreOrder(T);//先序遍历的顺序输出二叉树
	cout<<endl;
	cout<<"------------------先序遍历输出二叉树------------------"<<endl;
	PreOrderTree(T);
	cout<<"------------------中序遍历输出二叉树------------------"<<endl;
	InOrderTree(T);
	cout<<"------------------后序遍历输出二叉树------------------"<<endl;
	AfterOrderTree(T);
	cout<<"------------------层次遍历输出二叉树------------------"<<endl;
	LevelOrder(T);
	cout<<"------------------求深度------------------"<<endl;
	cout<<"深度为:"<<Depth(T)<<endl; 
	cout<<"------------------求结点个数------------------"<<endl;
	cout<<"结点个数为:"<<NodeCount(T)<<endl;
	return 0; 
} 

求中序遍历的前驱和后继:

//找前驱
BiNode *p;//目标结点 
BiNode *pre;
BiNode *final;
void visit(BiNode *q){
	if(q==p){
		final=pre;
	}else{
		pre=q;
	}
//	//找后继
//	if(pre==p){
//		final=q;
//	}else{
//		pre=q;
//	}
}
void findPre(BiTree T){
	if(T!=NULL){
		T=T->lchild;
		visit(T);
		T=T->rchild;
	}
} 

1.3.2 线索链表

定义

typedef char ElemType;
typedef struct BiThrNode{
	ElemType data;
	struct BiThrNode *lchild,*rchild;
	int LTag,RTag;//左右标志,0:指向左右孩子 1:指向前驱或后继 
}BiThrNode,* BiThrTree; 

先序线索化

//先序线索化(防止转圈问题)
void PreThreadTree(BiThrNode *p,BiThrNode *pre){
	if(p!=NULL){
		//根 
		if(p->lchild==NULL){
			p->LTag=1;
			p->lchild=pre;
		}else{
			p->LTag=0;
		}
		if(pre!=NULL&&pre->rchild==NULL){
			pre->RTag=0;
			pre->rchild=p;
		}else{
			p->RTag=0;
		}
		pre=p;
		//左
		if(p->LTag==0) PreThreadTree(p->lchild,pre);
		//右 
		PreThreadTree(p->rchild,pre);
	}
} 
void CreatePreThreadTree(BiThrTree T){
	BiThrNode *pre=NULL;
	if(T!=NULL){
		InThreadTree(T,pre);
		if(pre->rchild==NULL){
			pre->RTag=1;
		}
	}
}

中序线索化

//中序线索化
void InThreadTree(BiThrNode *p,BiThrNode *pre){
	if(p!=NULL){
		InThreadTree(p->lchild,pre);
		if(p->lchild==NULL){
			p->LTag=1;
			p->lchild=pre;
		}else{
			p->LTag=0;
		}
		if(pre!=NULL&&pre->rchild==NULL){
			pre->RTag=0;
			pre->rchild=p;
		}else{
			p->RTag=0;
		}
		pre=p;
		InThreadTree(p->rchild,pre);
	}
} 
void CreateInThreadTree(BiThrTree T){
	BiThrNode *pre=NULL;
	if(T!=NULL){
		InThreadTree(T,pre);
		if(pre->rchild==NULL){
			pre->RTag=1;
		}
	}
}

 后序线索化

//后序线索化
void PostThreadTree(BiThrTree p,BiThrNode *pre){
	if(p!=NULL){
		//左
		PostThreadTree(p->lchild,pre);
		//右 
		PostThreadTree(p->rchild,pre);
		//根 
		if(p->lchild==NULL){
			p->LTag=1;
			p->lchild=pre;
		}else{
			p->LTag=0;
		}
		if(pre!=NULL&&pre->rchild==NULL){
			pre->RTag=0;
			pre->rchild=p;
		}else{
			p->RTag=0;
		}
		pre=p;
	}
} 
void CreatePostThreadTree(BiThrTree T){
	BiThrNode *pre=NULL;
	if(T!=NULL){
		InThreadTree(T,pre);
		if(pre->rchild==NULL){
			pre->RTag=1;
		}
	}
} 

1.3.3 三叉链表

typedef struct BiNode{
	ElemType data;//数据域 
	struct BiNode *lchild,*rchild;//左右孩子指针 
	struct BiTNode *parent;//父节点指针
}BiNode,*BiTree;

2 树

1.1 树的基本概念

树(Tree)是n(n>=0)个结点的有限集,它或为空树(n=0);或为非空树。

基本术语

结点:树中的一个独立单元

1.2 树的

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1550266.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【面试】Elasticsearch 在部署时,对 Linux 的设置有哪些优化方法?

Elasticsearch 在部署时&#xff0c;对 Linux 的设置有哪些优化方法&#xff1f; Elasticsearch是一个分布式搜索和分析引擎&#xff0c;它在Linux环境下的性能和稳定性可以通过一些优化方法进行提升。以下是一些针对Linux环境下Elasticsearch部署的优化方法&#xff1a; 1. 内…

OSG编程指南<二十一>:OSG视图与相机视点更新设置及OSG宽屏变形

1、概述 什么是视图?在《OpenGL 编程指南》中有下面的比喻,从笔者开始学习图形学就影响深刻,相信对读者学习场景管理也会非常有帮助。 产生目标场景视图的变换过程类似于用相机进行拍照,主要有如下的步骤: (1)把照相机固定在三脚架上,让它对准场景(视图变换)。 (2)…

spring安全框架之Shiro

Shiro 一、现存问题 1.1 现存问题 认证&#xff08;登录&#xff09;&#xff1a;认证操作流程都差不多&#xff0c;但是每次都需要手动的基于业务代码去实现&#xff0c;很麻烦&#xff01; 授权&#xff1a;如果权限控制粒度比较粗&#xff0c;可以自身去实现&#xff0c…

算法打卡day19

今日任务&#xff1a; 1&#xff09;235. 二叉搜索树的最近公共祖先 2&#xff09;701.二叉搜索树中的插入操作 3&#xff09;450.删除二叉搜索树中的节点 235. 二叉搜索树的最近公共祖先 题目链接&#xff1a;235. 二叉搜索树的最近公共祖先 - 力扣&#xff08;LeetCode&…

Mysql数据库——高级SQL语句补充

目录 一、子查询——Subquery 1.环境准备 2.In——查询已知的值的数据记录 2.1子查询——Insert 2.2子查询——Update 2.3子查询——Delete 3.Not In——表示否定&#xff0c;不在子查询的结果集里 3.Exists——判断查询结果集是否为空 4.子查询——别名 二、视图—…

政安晨:【Keras机器学习实践要点】(六)—— 使用内置方法进行训练和评估

政安晨的个人主页&#xff1a;政安晨 欢迎 &#x1f44d;点赞✍评论⭐收藏 收录专栏: TensorFlow与Keras实战演绎机器学习 希望政安晨的博客能够对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff01; 本文涵盖使用内置 API 进行训练和验证&#…

pytorch+tensorboard

安装依赖 pip install teorboard pip install torch_tb_profiler了解teorboard 记录并可视化标量[组]、图片[组]。 如何使用 第一步&#xff1a;构建模型&#xff0c;记录中间值&#xff0c;写入summarywriter 每次写入一个标量add_scalar 比如&#xff1a; from torch.u…

深度学习:基于PyTorch的模型解释工具Captum

深度学习&#xff1a;基于PyTorch的模型解释工具Captum 引言简介示例安装解释模型的预测解释文本模型情绪分析问答 解释视觉模型特征分析特征消融鲁棒性 解释多模态模型 引言 当我们训练神经网络模型时&#xff0c;我们通常只关注模型的整体性能&#xff0c;例如准确率或损失函…

上位机图像处理和嵌入式模块部署(qmacvisual区域提取)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 在图像处理中&#xff0c;有两部分比较重要&#xff0c;一个是区域分割&#xff0c;一个是区域提取。区域分割&#xff0c;比较好理解&#xff0c;…

Chrome 插件 storage API 解析

Chrome.storage API 解析 使用 chrome.storage API 存储、检索和跟踪用户数据的更改 一、各模块中的 chrome.storage 内容 1. Service worker 中 runtime 内容 2. Action 中 runtime 内容 3. Content 中 runtime 内容 二、权限&#xff08;Permissions&#xff09; 如果需使…

SPU赋能PSI:探秘隐私集合求交核心技术与高级调度架构实践

1.SPU实现的PSI介绍 1.PSI的定义和种类 隐私集合求交&#xff08;Private Set Intersection, PSI&#xff09;是一种在密码学和安全多方计算&#xff08;MPC&#xff09;领域中的关键技术&#xff0c;允许两个或多个参与者在不泄露各自输入集合中非交集部分的前提下&#xff…

【python分析实战】成本:揭示电商平台月度开支与成本结构占比 - 过于详细 【收藏】

重点关注本文思路&#xff0c;用python分析&#xff0c;方便大家实验复现&#xff0c;代码每次都用全量的&#xff0c;其他工具自行选择。 全文3000字&#xff0c;阅读10min&#xff0c;操作1小时 企业案例实战欢迎关注专栏 每日更新&#xff1a;https://blog.csdn.net/cciehl/…

深入理解element-plus table二次封装:从理论到实践的全面指南

前言 在许多中后台管理系统中&#xff0c;表格占据着半壁江山&#xff0c;如果使用element plus组件库&#xff0c;那么少不了要用到table组件&#xff0c;可是table组件的功能过于基础&#xff0c;因此&#xff0c;我在table组件的实现基础之上进一步封装&#xff0c;从而实现…

2024-03-24 需求分析-智能问答系统-调研

一. 需求列表 基于本地知识库的问答系统对接外围系统 数字人语音识别二. 待调研的公司 2.1 音视贝 AI智能外呼_大模型智能客服系统_大模型知识库系统_杭州音视贝 (yinshibei.com) 2.2 得助智能 智能AI客服机器人-智能电话机器人客服-电话电销机器人-得助智能 (51ima.com) 2…

【LVGL-使用SquareLine Studio设计器 】

LVGL-使用SquareLine Studio设计器 ■ 简介■ 安装■ SquareLine Studio移植到工程 ■ 简介 SquareLine Studio 设计器是一个付费软件。 ■ 安装 SquareLine Studio 设计器的下载地址 我们点击“WINDOWS”下载 SquareLine Studio 设计器&#xff0c;下载完成之后我们就会得到…

ActiveMQ Artemis 系列| High Availability 主备模式(消息复制) 版本2.19.1

一、ActiveMQ Artemis 介绍 Apache ActiveMQ Artemis 是一个高性能的开源消息代理&#xff0c;它完全符合 Java Message Service (JMS) 2.0 规范&#xff0c;并支持多种通信协议&#xff0c;包括 AMQP、MQTT、STOMP 和 OpenWire 等。ActiveMQ Artemis 由 Apache Software Foun…

Android 性能优化实例分享-内存优化 兼顾效率与性能

背景 项目上线一段时间后,回顾重要页面 保证更好用户体验及生产效率&#xff0c;做了内存优化和下载导出优化&#xff0c;具体效果如最后的一节的表格所示。 下面针对拍摄流程的两个页面 预览页 导出页优化实例进行介绍&#xff1a; 一.拍摄前预览页面优化 预览效果问题 存在…

快速上手Spring Cloud 十一:微服务架构下的安全与权限管理

快速上手Spring Cloud 一&#xff1a;Spring Cloud 简介 快速上手Spring Cloud 二&#xff1a;核心组件解析 快速上手Spring Cloud 三&#xff1a;API网关深入探索与实战应用 快速上手Spring Cloud 四&#xff1a;微服务治理与安全 快速上手Spring Cloud 五&#xff1a;Spring …

vuees6新语法

vue的学习网站&#xff1a; https://www.runoob.com/vue2/vue-tutorial.html1.Vue的介绍 学习目标 说出什么是Vue能够说出Vue的好处能够说出Vue的特点 内容讲解 【1】Vue介绍 1.vue属于一个前端框架&#xff0c;底层使用原生js编写的。主要用来进行前端和后台服务器之间的…

搜索插入位置-java

题目描述 : 给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。请必须使用时间复杂度为 O(log n) 的算法。 思路分析: 这段代码的解题思想是利用二分查找的方法在…