首页 > 其他分享 >数据结构:链式二叉树(1)

数据结构:链式二叉树(1)

时间:2024-08-12 18:51:49浏览次数:8  
标签:结点 遍历 BTNode 二叉树 链式 数据结构 root 节点

目录

前言

一、链式二叉树的遍历

1.1 前序遍历

1.2 中序遍历

 1.3 后序遍历

二、层序遍历


前言

    通过前面关于二叉树的基础知识我们知道链式二叉树分为二叉链和三叉链,本篇主要讲的是二叉链的实现,在此之前,为了方便实现链式二叉树的各个功能,我们需要先手动快速创建一个链式二叉树。

typedef int BTDataType;
typedef struct BinaryTreeNode
{
 BTDataType _data;
 struct BinaryTreeNode* _left;
 struct BinaryTreeNode* _right;
}BTNode;
 
BTNode* CreatBinaryTree()
{
 BTNode* node1 = BuyNode(1);
 BTNode* node2 = BuyNode(2);
 BTNode* node3 = BuyNode(3);
 BTNode* node4 = BuyNode(4);
 BTNode* node5 = BuyNode(5);
 BTNode* node6 = BuyNode(6);
 
 node1->_left = node2;
 node1->_right = node4;
 node2->_left = node3;
 node4->_left = node5;
 node4->_right = node6;
return node1;
}

注意:上述代码并不是创建二叉树的方式,这里只是图方便。

    这里再把创建的链式二叉树的头文件放在这里,包含了链式二叉树所需的头文件以及需要实现的函数功能

#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
typedef int BTDataType;

typedef struct BinaryTreeNode
{
	BTDataType data;
	struct BinaryTreeNode* left;
	struct BinaryTreeNode* right;
}BTNode;

// 构建一个简单的二叉树
BTNode* BinaryTreeCreate();
// 二叉树销毁
void BinaryTreeDestory(BTNode** root);
// 二叉树节点个数
int BinaryTreeSize(BTNode* root);
// 二叉树叶子节点个数
int BinaryTreeLeafSize(BTNode* root);
// 二叉树第k层节点个数
int BinaryTreeLevelKSize(BTNode* root, int k);
// 二叉树查找值为x的节点
BTNode* BinaryTreeFind(BTNode* root, BTDataType x);
// 二叉树前序遍历 
void BinaryTreePrevOrder(BTNode* root);
// 二叉树中序遍历
void BinaryTreeInOrder(BTNode* root);
// 二叉树后序遍历
void BinaryTreePostOrder(BTNode* root);
// 层序遍历
void BinaryTreeLevelOrder(BTNode* root);
// 判断二叉树是否是完全二叉树
bool BinaryTreeComplete(BTNode* root);

一、链式二叉树的遍历

    学习二叉树结构,最简单的方式就是遍历。所谓二叉树遍历是按照某种特定的规则,依次对二叉 树中的结点进行相应的操作,并且每个结点只操作一次,访问结点所做的操作依赖于具体的应用问题。 遍历是二叉树上最重要的运算之一,也是二叉树上进行其它运算的基础。

 

按照规则,二叉树的遍历有:前序/中序/后序的递归结构遍历:  

1. 前序遍历(亦称先序遍历)——访问根结点的操作发生在遍历其左右子树之前。

2. 中序遍历——访问根结点的操作发生在遍历其左右子树之中。

3. 后序遍历——访问根结点的操作发生在遍历其左右子树之后。

1.1 前序遍历

void BinaryTreePrevOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("N ");
		return;
	}
	printf("%d ", root->data);
	BinaryTreePrevOrder(root->left);
	BinaryTreePrevOrder(root->right);
}

 这里写了个打印N的代码是为了方便看到空节点,能更好的理解前序遍历。

 图解

    前序遍历的内核思想就是递归(准确来说二叉树遍历的思想都是基于递归),前序遍历的顺序是先从根节点开始遍历,找到根节点后开始向下寻找(先是找左子树的根节点再是右子树),左子树根节点找完后,接下来就是左子树中的左节点再就是右节点,找完左子树在以同样的顺序在右子树中进行一遍,总之就是 根->左子树->右子树 按照这样一个顺序来。

1.2 中序遍历

void BinaryTreeInOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("N ");
		return;
	}
	BinaryTreeInOrder(root->left);
	printf("%d ", root->data);
	BinaryTreeInOrder(root->right);
}

    前面说了几个遍历的思想其实差不多,中序遍历就是按照 左子树->根->右子树 的顺序来遍历二叉树的,跟前面的前序遍历是一个逻辑,这里就不赘述了。

 1.3 后序遍历

void BinaryTreePostOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("N ");
		return;
	}
	BinaryTreePostOrder(root->left);
	BinaryTreePostOrder(root->right);
	printf("%d ", root->data);
}

    左子树->根->右子树

同一数据,各个遍历的结果

 

二、层序遍历

    这里把层序遍历和前面三个遍历分开讲是因为,这个遍历和之前的不是同种遍历,前面三个遍历和层序遍历的底层思想是不一样的。

层序遍历:除了先序遍历、中序遍历、后序遍历外,还可以对二叉树进行层序遍历。设二叉树的根结点所在 层数为1,层序遍历就是从所在二叉树的根结点出发,首先访问第一层的树根结点,然后从左到右访问第2层 上的结点,接着是第三层的结点,以此类推,自上而下,自左至右逐层访问树的结点的过程就是层序遍历。

 

层序遍历的实现需要用到前面队列的知识,忘了的可以看下这里(队列) 

void BinaryTreeLevelOrder(BTNode* root)
{
	Queue a;
	QueueInit(&a);
	if(root)
	QueuePush(&a, root);
	while (!QueueEmpty(&a))
	{
		BTNode* f = QueueFront(&a);
        QueuePop(&a);
		printf("%d ", f->data);
		if (f->left)
			QueuePush(&a, f->left);
		if (f->right)
			QueuePush(&a, f->right);
	}
	QueueDestroy(&a);
}

    先以二叉树的最上层根节点创建一个队列, 用一个指针指向这个根节点,打印完后出队列,将这个根节点的左节点和右节点分别入队列,再先以左节点为新的根节点重复上述操作,再是右节点,这样一层遍历完了,再重复直到没有节点为止。

层序遍历的结果就是每层的数字按照顺序打印


     本篇内容就先到这里,剩下的内容会在下一篇讲解。

标签:结点,遍历,BTNode,二叉树,链式,数据结构,root,节点
From: https://blog.csdn.net/2401_86551514/article/details/141136059

相关文章

  • 每天一个知识:STL数据结构
    前言我准备这个参考大量文献,非常辛苦,渴望你能点一个赞,在点个关注,这对我来说非常重要,我会不定时完善这篇文章,望周知STL是什么?标准模板库(StandardTemplateLibrary,STL)是惠普实验室开发的一系列软件的统称。它是由AlexanderStepanov、MengLee和DavidRMusser在惠普实验......
  • 专题 (五) map 数据结构
    1、用法用法说明1、declare-Amap2、declare-AmyMap=(["my01"]="01"["my02"]="02")3、declare-Amap=()1、声明map变量2、声明map变量的同时可以赋值3、定义一个空mapmap[$_key]=$_count指定key赋值value,其中_key和_value均是shenll变量1、e......
  • 数据结构(一)-绪论
    数据结构(一)-绪论梗概:1.数据1.1数据数据是信息的载体,是描述客观事物属性的数、字符及所有能输入到计算机中并被计算机程序识别和处理的符号集合,数据是计算机程序加工的原料。1.2数据元素数据元素是数据的基本单位,通常作为一个整体进行考虑和处理。一个数据元素可有若......
  • 【Rust光年纪】Rust数据结构库全方位解析:从核心功能到API概览
    提升Rust项目效率的利器:六款优秀数据结构库详解前言随着Rust编程语言的不断发展和普及,开发者们对于高效的数据结构库需求日益增长。在本文中,我们将介绍一些优秀的Rust数据结构库,它们分别为heapless、arrayvec、smallvec、evmap、hashbrown和generic-array。这些库提供了各......
  • 数据结构 顺序队列(计数器版)
    在实现循环队列时,为了区分队列为空和队列满的情况,我们通常会浪费一个位置。也就是说,如果队列的总容量是100,那么实际上只能存储99个元素。这是因为我们需要保留一个位置来判断队列是满的还是空的。如果我们不这样做,那么在队列满和队列空时,front和rear指针都会指向同一个位置,......
  • 【Java数据结构】---泛型
    乐观学习,乐观生活,才能不断前进啊!!!我的主页:optimistic_chen我的专栏:c语言,Java欢迎大家访问~创作不易,大佬们点赞鼓励下吧~文章目录包装类装箱和拆箱泛型泛型语法擦除机制泛型的上届泛型方法静态泛型方法完结包装类在Java中,由于基本类型不是继承自Objec......
  • LinkedList模拟栈数据结构的集合,并测试
    packagecom.shujia.day13;importjava.util.LinkedList;/*LinkedList请用LinkedList模拟栈数据结构的集合,并测试栈:先进后出题目的要求是:自己创建一个类,将LinkedList作为成员变量,将来创建自己的类对象,使用自己的方法,但是底层用的是LinkedList中的方法......
  • 【经验分享】数据结构——哈希查找冲突处理方法(开放地址法-线性探测、平方探测、双散
    目录1.线性探测(LinearProbing)2.平方探测(QuadraticProbing)3.双散列探测(DoubleHashing)4.分离链接法(SeparateChaining)5.再散列(Rehashing)如何解答这些常见问题1.写出处理冲突的方法名称2.构造基于该处理冲突方法的哈希表3.求出该哈希表在等概率情况下查找成功......
  • 数据结构----二叉树
              小编会一直更新数据结构相关方面的知识,使用的语言是Java,但是其中的逻辑和思路并不影响,如果感兴趣可以关注合集。    希望大家看完之后可以自己去手敲实现一遍,同时在最后我也列出一些基本和经典的题目,可以尝试做一下。大家也可以自己去力扣或者......
  • 【数据结构】—— 内部排序算法详解
    1、前言2、常见排序算法3、排序算法实现3.1直接插入排序3.2希尔排序3.3选择排序3.4堆排序3.5冒泡排序3.6快速排序3.6.1单趟排序hoare法挖坑法双指针法3.6.2非递归实现3.6.3常见问题基准值的选取小区间优化3.7归并排序3.7.1递归实现3.7.2非递归实现3.8......