二叉树的链式存储

数据结构-二叉树的链式存储 文章目录二叉树的链式结构链式结构的遍历二叉树链式存储的实现二叉树节点的创建前序遍历中序遍历后序遍历二叉树元素个数叶节点的个数第k层节点的个数查找元素二叉树销毁二叉树的层序遍历判断是否为完全二叉树 二叉树的链式结构 二叉树的存储结构有顺序结构和链式结构两种,顺序结构我已经在上篇进行了详细的讲解,地址:数据结构-二叉树的顺序存储与堆(堆排序),本篇我们就主要讲解二叉树的链式存储。 二叉树的链式存储结构是指,用链表来表示一棵二叉树,即用链来指示元素的逻辑关系。 通常的方法是链表中每个结点由三个域组成,数据域和左右 阅读详情

顺序存储

有n个节点的完全二叉树可以用有n+1个元素的数组进行顺序存储,节点号和数组下标 一一对应。
不完全二叉树通过添加虚节点构成 完全二叉树,然后用数组存储,这要浪费一些存储空间。
在这里插入图片描述

最坏的情况下,一个深度为k且只有k个结点的单支树却需要长度为2k-1的一维数组。
总结: 顺序存储浪费空间。

链式存储

数据的描述

描述: 数据域+左右指针域

typedef char datatype;

typedef struct node {
	datatype data;
	struct node *lchild;//左孩子
	struct node *rchild;//右孩子
}btree, *btree_t;

二叉树的创建

树的结构定义是一个递归的定义,即在树的定义中又用到了树的概念。所以创建也采用递归的方式创建。

btree_t createBtree()
{
	//1.获取数据
	datatype x;
	btree_t T = NULL;

	scanf("%c", &x);

	//2.数据有效,创建根结点存放
	if('#' == x)
		return NULL;

	T = (btree_t)malloc(sizeof(btree));
	if(NULL == T)
	{
		perror("malloc");
		return NULL;
	}

	T->data = x;

	//3.还有数据,递归创建左结点存放
	T->lchild = createBtree();

	//4.还有数据,递归创建右结点存放
	T->rchild = createBtree();

	return T;
}

二叉树的遍历

由于二叉树的递归性质,遍历算法也是递归的。
三种遍历方式: 先序遍历、中序遍历、后序遍历。
在这里插入图片描述

先序遍历

void pre_order(btree_t T)//前序
{
	//空则不遍历
	if(NULL == T)
	{
		return ;
	}

	//非空才遍历
	printf("%c", T->data);//根
	pre_order(T->lchild);//左子树
	pre_order(T->rchild);//右子树

}

在这里插入图片描述

中序遍历

void in_order(btree_t T)//中序
{
	//空则不遍历
	if(NULL == T)
	{
		return ;
	}

	//非空才遍历
	in_order(T->lchild);//左子树
	printf("%c", T->data);//根
	in_order(T->rchild);//右子树

	return ;
	
}

后序遍历

void post_order(btree_t T)//后序
{
	//空则不遍历
	if(NULL == T)
	{
		return ;
	}

	//非空才遍历
	post_order(T->lchild);//左子树
	post_order(T->rchild);//右子树
	printf("%c", T->data);//根

	return ;

}

层序遍历

在这里插入图片描述
该图来自mooc浙江大学数据结构课程

void Levelorder ( btree_t T )
{
	if ( !T ) return; /* 若是空树则直接返回 */
	
    btree_t Temp;
    sequeue *Q = createSeQueue(); /* 创建空队列Q */
    
    inSeQueue( Q, T );
    while ( !isEmptySeQueue(Q) ) 
	{
        OutSeQueue( Q, &Temp );
        printf("%c ", Temp->data); /* 访问取出队列的结点 */
        if ( Temp->lchild )   
			inSeQueue( Q, Temp->lchild );
        if ( Temp->rchild )  
			inSeQueue( Q, Temp->rchild );
    }
}

测试

在这里插入图片描述
在这里插入图片描述

	btree_t T = createBtree();
	if(NULL == T)
	{
		printf("创建二叉树失败");
		return -1;
	}

	printf("pre: ");
	pre_order(T);
	printf("\n");

	printf("in: ");
	in_order(T);
	printf("\n");

	printf("post: ");
	post_order(T);
	printf("\n");

    return 0;

先序 中序 后序的非递归遍历算法

利用堆栈
在这里插入图片描述
沿着如图所示路径遍历。
先序遍历就是在第一次遇到结点的时候输出,中序在第二次遇到的时候输出,后序是在第三次遇到的时候输出。

void preOder(btree_t T)
{
	seqstack * s = (seqstack *)malloc(sizeof(seqstack));//创建空栈
	
	while(T || !isEmpty(s)) 
	{
		while(T)
		{
			push(s, T);	//第一次碰到,将该结点指针入栈,并输出其数据
			printf("%c", T->data);
			T = T->lchild;//T指向T的左孩子 
		}
		
		if(!isEmpty(s))	//出栈,直到栈为空 
		{
			T = pop(s);	//第二次碰到,出栈该结点 
			
			T = T->rchild;			
		}
	}
}

void inOder(btree_t T)
{
	seqstack * s = (seqstack *)malloc(sizeof(seqstack));//创建空栈
	
	while(T || !isEmpty(s)) 
	{
		while(T)
		{
			push(s, T);	//第一次碰到,将该结点指针入栈
			T = T->lchild;//T指向T的左孩子 
		}
		
		if(!isEmpty(s))	//出栈,直到栈为空 
		{
			T = pop(s);	//第二次碰到,出栈该结点,并输出其数据 
			printf("%c", T->data);
			T = T->rchild;			
		}
	}
}

后序

void PostOrderTraversal(Bintree BT)
{
    Bintree T=BT;
    Bintree flag=NULL;//flag记录结点是否已被访问过
    Bintree top;
    Stack S=CreateStack(MaxSize);
    while(T || !IsEmpty(S))
    {
        while(T)
        {
            push(S,T);
            T=T->Left;
        }             //一路向左,将沿途结点压栈
        top=GetTop(S);        //获取栈顶元素,此时不出栈
        if(top->Right==NULL || top->Right==flag)  //此时top的左子树在上一个while循环中已访问过。当top的右子树为空或已访问过时打印top结点
        {
            printf("%5d",top->Data);
            flag=pop(s);    //用flag记录这个元素,表示已访问
        }
        else
            T=top->Right;       //若top的右子树没有被访问过,则将其当做一颗新二叉树访问
    }
}

网上看到一个很有意思的程序,也分享一下:

void PostOrderTraversal( BinTree BT )
 {   
     BinTree T =BT;   
     Stack S = CreatStack( MaxSize ); 
     Stack Q = CreatStack( MaxSize );
     while( T || !IsEmpty(S) )
    {  
       while(T)
       { 
         Push(S,T);  
           Push(Q,T);
         T = T->Right;
        }          //向右将沿途结点一路压栈
       if(!IsEmpty(S))
       {  
         T = Pop(S);
         T = T->Left; //转向左子树
        }   
   }  
   while( !IsEmpty(Q) )
    { 
      T = Pop(Q);
      printf(“%5d”, T->Data); 
    }  
}
二叉树链式存储的实现 //filename:bitree.h #include #include #include #define OK 1 #define ERROR 0 #define TRUE 1 #define FALSE 0 #define NIL '#' //定义'#'为空节点 typedef struct queue_node qnode; typedef struct bitree_nod 阅读详情

相关推荐

二叉树的顺序存储和链式存储

作为一个机械屌丝男,最近一直在恶补

bbewx的专栏 1万+

二叉树的存储表示

二叉树的数组存储表示 在数据处理过程中二叉树的大小、形态不发生剧烈的动态变化的场合,适宜采用数组方式来表示二叉树的抽象数据类型 1、完全二叉树的数组存储表示 设有一棵完全二叉树,将其所有结点按照层次自顶向下、同一层自左向右进行按序编号1 - n,得到一个结点的顺序(线性)序列。在数组下标为 i 的位置,存放编号为 i 的完全二叉树的结点。这种存储表示是存储完全二叉树最简单、最省存储的方式,因为可以从一个结点的编号推算出它的父结点、子女、兄弟等结点的编号 数组存储的缺陷:对待一般二叉树来说,有可能导致浪费大量

q793145253的博客 2437

二叉树链式存储结构代码实现

上一篇博客已经介绍过实际内容了,这一篇直接上干货代码了。 结构体 前面写的是用c语言写的,用的也是递归的方法 typedef char BTDataType; typedef struct BTNode { struct BTNode* left; struct BTNode* right; BTDataType data; }BTNode; 1、创建二叉树 typedef struct ...

qq_42430426的博客 5465

LeetCode 0919. 完全二叉树插入器:完全二叉树的数组表示

LeetCode 919. 完全二叉树插入器:完全二叉树的数组表示 完全二叉树 是每一层(除最后一层外)都是完全填充(即,节点数达到最大)的,并且所有的节点都尽可能地集中在左侧。

<font color="Pink">Tisfy的博客</font> 946

二叉树链式存储操作

前言二叉树的存储结构    1.二叉树的顺序存储结构 利用性质5,对于完全二叉树可以利用一维数组存储,如果不是完全二叉树,则可以补空节点,使成为完全二叉树在进行存储,    但是对于非完全二叉树,可能要浪费很多的空间。2.二叉树的链式存储结构  二叉树的链式存储结构就是用指针建立二叉树中节点之间的关系,二叉树最常用的链式存储结构是二叉链。二叉树的二叉链存储结构是一种常用的  二叉树存储结构。二叉链...

qq_41582941的博客 1079

二叉树的链式存储结构

对于二叉树,顺序存储结构一般只用于完全二叉树。 #include using namespace std; typedef char ElemType; typedef struct BiNode { ElemType data; BiNode *lchild,*rchild; }BiNode,*BiTree; int index = 0; char node[10]="AB#

HAN Kai 4438

数据结构:二叉树的链式结构

链式二叉树创建非常详细的过程:包含如何前序遍历创建二叉树、对二叉树的前、中、后序遍历、二叉树节点个数、二叉树叶子节点个数、二叉树的高度、第k层节点个数、查找节点、层序遍历、判断二叉树是否为完全二叉树、二叉树的销毁.....附带完整代码以及图解

Yikefore的博客 6704

用VINS-Fusion跑通EuRoC数据集:Ubuntu22.04+ROS2环境下的保姆级评测指南

本文详细介绍了在Ubuntu22.04和ROS2 Humble环境下使用VINS-Fusion处理EuRoC数据集的完整流程。从环境配置、数据集转换到参数调优和性能评估,提供了一套全面的多传感器融合分析方案,帮助开发者在无人机精准定位场景中实现高效部署与优化。

weixin_29212867的博客 518

二叉树链式存储详解

二叉树是数据结构中一个非常重要的概念,它广泛应用于各种算法和程序设计中。在C语言中,我们可以使用链式存储的方式来实现二叉树。

猪肉炖粉条的博客 2570

若依RuoYi文件上传漏洞实战:如何安全配置/profile/upload路径(附避坑指南)

本文深入解析若依RuoYi框架中/profile/upload路径的文件上传漏洞,提供详细的安全配置方案和实战指南。通过权限修正、输入验证强化和存储隔离等多层防御策略,有效防范未授权访问和恶意文件上传风险,保障系统安全。

pink的博客 781

双目立体成像(一)双目图片生成点云

利用左右目图片生成点云

qq_62964142的博客 4554

二叉树——链式存储

上期讲了二叉树的顺序存储,今天来讲一下二叉树的链式存储。

qq_63943454的博客 2056

别急着让AI画板!聊聊Cadence Allegro X AI和OrCAD X在实际PCB项目中的真实体验

本文分享了Cadence Allegro X AI与OrCAD X在PCB设计中的实际应用体验,探讨了AI辅助Layout的效率提升与潜在陷阱。通过高速ADC采集板案例,详细对比了AI与传统方法在电源平面分割、低速信号布线等任务中的表现,并总结了人机协作的最佳实践,为工程师提供实用参考。

weixin_30836759的博客 2225

二叉树的链式存储、层次遍历以及顺序存储转换为链式存储

1.二叉树链式存储的定义 首先自己写了个队列类(其实也可以不用); 树节点模板类的定义:data-数据,left-左孩子指针,right-右孩子指针,含参构造函数; 创建结点的函数-GetBTNode()函数 创建一个树节点并分配内存,同时利用构造函数存储内容. 2.层次遍历函数 层次遍历:从上到下,从左到右. 因为层次遍历是一层一层进行的,从当前访问的结点结构中不能直接得到下一个要访问的结点,为此引用队列做为存储二叉链表的结点指针的寄存器. 建队列,根节点入队-----若队列不为空,则从队列中删除

weixin_53551797的博客 6210

【论文学习】《Fully-Convolutional Siamese Networks for Object Tracking》2016年SiamFC 全卷积孪生网络用于目标跟踪

在这项工作中,我们脱离了跟踪中采用的传统在线学习方法,并展示了一种专注于在离线阶段学习强嵌入的替代方法。与在分类设置中的使用不同,我们证明,对于跟踪应用,孪生全卷积深度网络能够更有效地使用可用数据。这不仅反映在测试时,通过执行有效的空间搜索,也反映在训练时,其中每个子窗口都有效地代表一个有用的样本,而几乎没有额外的成本。实验表明,深度嵌入为在线跟踪器提供了自然丰富的特征来源,并使简单的测试时策略表现良好。我们相信这种方法是对更复杂的在线跟踪方法的补充,并期望未来的工作能够更彻底地探索这种关系。

SkyLeopard的博客 2421

Python爬虫实战 | 拼多多商品评论采集与深度分析

本文从 API 调用、网页渲染到情感分析与关键词提取,全流程剖析了“拼多多商品评论采集与分析”项目。Scrapy + API 可快速抓取评论;Playwright 可突破 API 限制,抓取完整页面内容;数据清洗 + 分析揭示用户真实反馈;可持续部署、扩展至更多商品 & 时间段;

2201_76125261的博客 1696

二叉树链式存储

二叉树是一种树形结构,其中每个节点最多有两个子节点,分别称为左子节点和右子节点。二叉树广泛应用于各种算法和数据结构中,如二叉搜索树、堆和哈夫曼编码等。int data;// 数据域// 左子节点指针// 右子节点指针} TreeNode;二叉树的链式存储是一种灵活且高效的实现方式,适用于各种需要动态插入和删除节点的场景。通过本文的介绍,相信大家对二叉树的链式存储有了更深入的了解。在实际应用中,可以根据具体需求选择合适的存储方式。希望这篇博客对你有所帮助,欢迎在评论区留下你的问题和见解!

Chinese_chen_的博客 412

PoE 的三大国际标准:PoE、PoE+、PoE++

很多人知道 PoE 能“一根网线,既供电又传数据”,但鲜少有人能说清楚:PoE 供电到底分几种标准?差别有多大?哪些设备要用 PoE,哪些必须上 PoE+ 或 PoE++?今天,我们就来一次彻底的“拆解”,把 PoE 的三大国际标准——讲得明明白白,顺便也帮你厘清网络工程中的常见“供电疑惑”。

网络技术联盟站 1551

二叉树(链式存储)—— C++实现

作者:花 梦 时间:2019.12.21 二叉树(链式存储) 非线性 物理上不连在一起 树型结构 直接开撸,首先需要我们的头文件与命名空间: #include <iostream> #include <deque> // 下面的层级遍历的算法需要用到队列 using namespace std; 链式存储需要结点来连接左子树与右子树: template &...

浪子花梦 3575

【GEOS-Chem模拟教程第二期下】全球生物质燃烧 GFAS 数据配置

本博客详细介绍全球生物质燃烧 GFAS 数据下载及在 GEOS-CHEM 模型中的配置

WW、forever的博客 1396

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

DS:二叉树的链式存储及遍历

本篇博客主要是详细介绍二叉树的链式结构的实现及其二叉树相关的常见计算!

白乐天_ξ( ✿>◡❛)的博客 1378

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

二叉树--链式存储

1我们之前学了二叉树的顺序存储(这种顺序存储的二叉树被称为堆),我们今天来学习一下二叉树的链式存储:我们使用链表来表示一颗二叉树:⽤链表来表⽰⼀棵⼆叉树,即⽤链来指⽰元素的逻辑关系。通常的⽅法是链表中每个结点由三个域组成,数据域和左右指针域,左右指针分别⽤来给出该结点左孩⼦和右孩⼦所在的链结点的存储地址。比如这就是我们的二叉树的链式存储,跟链表是不是比较像,就是使用链表来进行存储我们的二叉树;但是我想你也一定发现了我们使用链式存储的二叉树不一定是完全的二叉树;

daiwoliyunshang的博客 1185

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

上一篇: 线性表8:队列的链式存储——链队
下一篇: Dev-c++ 4:创建项目,编译多个源文件
hellohelloe
博客等级 码龄8年 18粉丝 15原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值