二叉树排序讲解(一)

༺ 个人主页 · 纪念229 ༻

🏠我的博客主页🏠

༒专栏目录:《数据结构》༒

༒专栏目录:《算法》༒

༒专栏目录:《MySQL数据库》༒

༒专栏目录:《前端开发》༒

༒其它有趣的计算机知识༒

༺世上本没有路,走的人多了自然就有了༻


文章目录

  • 1.Tree.h
  • 2.Tree.c
  • 3.实现函数
  • [3.1void preOrder(BTNode* root)](#3.1void preOrder(BTNode* root))
  • [3.2void inOrder(BTNode* root)](#3.2void inOrder(BTNode* root))
  • [3.3void postOrder(BTNode* root)](#3.3void postOrder(BTNode* root))
  • [3.4int BinaryTreeSize(BTNode* root)](#3.4int BinaryTreeSize(BTNode* root))
  • [3.5BinaryTreeLeafSize(BTNode* root)](#3.5BinaryTreeLeafSize(BTNode* root))
  • [3.6BinaryTreeLevelKSize(BTNode* root, int k)](#3.6BinaryTreeLevelKSize(BTNode* root, int k))
  • [3.7BinaryTreeDepth(BTNode* root)](#3.7BinaryTreeDepth(BTNode* root))

本篇文章主要讲述的是二叉树的前、中、后序排序。

主要讲解代码构成以及排序方法,其中大部分我们要用递归来实现

1.Tree.h

代码展示

c 复制代码
#pragma once
#include<stdio.h>
#include<stdlib.h>
//定义链式结构的二叉树(内容是char类型的)单链表
typedef char BTTypeData;
typedef struct BinaryTreeNode
{
	BTTypeData data;
	struct BinaryTreeNode* left;
	struct BinaryTreeNode* right;
}BTNode;

//前序遍历-根左右
void preOrder(BTNode* root);
//中序遍历
void inOrder(BTNode* root);
//后序遍历
void postOrder(BTNode* root);

//二叉树节点个数
int BinaryTreeSize(BTNode* root);
//int BinaryTreeSize(BTNode* root, int* psize)
//二叉树叶子节点个数
int BinaryTreeLeafSize(BTNode* root);
//第k层节点的个数
int BinaryTreeLevelKSize(BTNode* root, int k);
//二叉树的深度/高度
int BinaryTreeDepth(BTNode* root);
//查找二叉树中值为x的节点
BTNode* BinaryTreeFind(BTNode* root, BTTypeData x);

2.Tree.c

代码展示

c 复制代码
#define _CRT_SECURE_NO_WARNINGS 1
#include"Tree.h"
//前序遍历-根左右
void preOrder(BTNode* root)
{
	//判断根节点是否为空
	if (root == NULL)
	{
		printf("NULL ");
		return;
	}
	//根据情况递归
	printf("%c ", root->data);
	preOrder(root->left);
	preOrder(root->right);
}
//中序遍历-左中右
void inOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("NULL ");
		return;
	}
	inOrder(root->left);
	printf("%c ", root->data);
	inOrder(root->right);
}
//后序遍历-左右根
void postOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("NULL");
		return;
	}
	postOrder(root->left);
	postOrder(root->right);
	printf("%c ", root->data);
}
//二叉树节点个数
//int size = 0;
//int BinaryTreeSize(BTNode* root)
//{
// if(root == NULL)
// {
// return 0;
// }
// size++;
// BinaryTreeSize(root->left);
// BinaryTreeSize(root->right);
// return size;
//}
//int BinaryTreeSize(BTNode* root, int* psize)
//{
//	if (root == NULL)
//	{
//	return 0; 
//}
//(*psize)++;
//BinaryTreeSize(root->left, psize);
//BinaryTreeSize(root->right, psize);
//}
//二叉树节点个数等于1加上左子树节点个数加上右子树节点个数
int BinaryTreeSize(BTNode* root)
{
	//节点为NULL返回0
	if (root == NULL)
	{
		return 0;
	}
	return 1 + BinaryTreeSize(root->left) + BinaryTreeSize(root->right);
}
//二叉树叶子节点个数
int BinaryTreeLeafSize(BTNode* root)
{

	if (root == NULL)
	{
		return 0;
	}
	//如果节点的左节点和右节点都为NULL则该节点为叶子节点
	if (root->left == NULL && root->right == NULL)
	{
		return 1;
	}
	//以上两点都不符合就递归
	return BinaryTreeLeafSize(root->left) + BinaryTreeLeafSize(root->right);
}
//第k层节点的个数
int BinaryTreeLevelKSize(BTNode* root, int k)
{
	if (root == NULL)
	{
		return 0;
	}
	//第一层只有一个节点
	if (k == 1)
	{
		return 1;
	}
	//用递归从k到1最后相加
	//指向左右节点层数比原来减一
	return BinaryTreeLevelKSize(root->left, k - 1) + BinaryTreeLevelKSize(root->right, k - 1);
}
//二叉树深度/高度
int BinaryTreeDepth(BTNode* root)
{
	if (root == NULL)
	{
		return 0;
	}
	//根据左右子树的深度带判断树的深度
	int leftDep = BinaryTreeDepth(root->left);
	int rightDep = BinaryTreeDepth(root->right);
	//根据root遍历进行深入访问
	return 1 + (leftDep > rightDep ? leftDep : rightDep);
}
#define _CRT_SECURE_NO_WARNINGS 1
#include"Tree.h"
BTNode* buyNode(char x)
{
	BTNode* tmp = (BTNode*)malloc(sizeof(BTNode));
	if (tmp == NULL)
	{
		perror("malloc fail");
		exit(1);
	}
	BTNode* node = tmp;
	node->data = x;
	node->left = node->right = NULL;
	return node;
}
BTNode* creatBinaryTree()
{
	BTNode* nodeA = buyNode('A');
	BTNode* nodeB = buyNode('B');
	BTNode* nodeC = buyNode('C');
	BTNode* nodeD = buyNode('D');
	BTNode* nodeE = buyNode('E');
	BTNode* nodeF = buyNode('F');

	nodeA->left = nodeB;
	nodeA->right = nodeC;
	nodeB->left = nodeD;
	nodeC->left = nodeE;
	nodeC->right = nodeF;
	return nodeA;
}

void test01()
{
	BTNode* root = creatBinaryTree();
	preOrder(root);
	inOrder(root);
	postOrder(root);
	printf("size:%d\n", BinaryTreeSize(root));
	printf("Leaf size:%d\n", BinaryTreeLeafSize(root));
}
int main()
{
	test01();
	return 0;
}

以下是具体讲解

讲一些比较重要的

本文是链式结构的二叉树(内容是char类型的)单链表(其实就是结构体里多加了个指针)

3.实现函数

3.1void preOrder(BTNode* root)

前序遍历

代码展示

c 复制代码
  //前序遍历-根左右
void preOrder(BTNode* root)
{
	//判断根节点是否为空
	if (root == NULL)
	{
		printf("NULL ");
		return;
	}
	//根据情况递归
	printf("%c ", root->data);
	preOrder(root->left);
	preOrder(root->right);
}

具体讲解:

遍历时首先要看传入的指针是否为NULL

为NULL

root->XXXX会报错(空指针遍历内容会报错)

前序遍历的顺序是E(center)L(left)R(right)

我们由代码可知结构体由一个字符,两个字符指针构成

我们前序遍历到的字符都要打印出来然后继续直到遍历完为止(到center就打印其它就遍历)

这里我们遍历用到递归(函数反复调用自己,直到遇到特殊规则停止)

前序遍历我们可以在纸上画出来在实际上的编译器上我们一般看到的是一排一排打印出来的数据

3.2void inOrder(BTNode* root)

中序遍历

代码展示

c 复制代码
//中序遍历-左中右
void inOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("NULL ");
		return;
	}
	inOrder(root->left);
	printf("%c ", root->data);
	inOrder(root->right);
}

具体讲解

中序遍历LER

和前序遍历差不多就遍历循序变成了左右中

这里讲一下这个E可以随便放但是L一定在R的右边

3.3void postOrder(BTNode* root)

后序遍历LRE

代码展示

c 复制代码
//后序遍历-左右根
void postOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("NULL");
		return;
	}
	postOrder(root->left);
	postOrder(root->right);
	printf("%c ", root->data);
}

3.4int BinaryTreeSize(BTNode* root)

二叉树节点个数

讲三个版本推荐最后一个

代码展示

c 复制代码
int size = 0;
int BinaryTreeSize(BTNode* root)
{
 if(root == NULL)
 {
 return 0;
 }
 size++;
 BinaryTreeSize(root->left);
 BinaryTreeSize(root->right);
 return size;
}
c 复制代码
//int BinaryTreeSize(BTNode* root, int* psize)
//{
//	if (root == NULL)
//	{
//	return 0; 
//}
//(*psize)++;
//BinaryTreeSize(root->left, psize);
//BinaryTreeSize(root->right, psize);
//}
//二叉树节点个数等于1加上左子树节点个数加上右子树节点个数
c 复制代码
int BinaryTreeSize(BTNode* root)
{
	//节点为NULL返回0
	if (root == NULL)
	{
		return 0;
	}
	return 1 + BinaryTreeSize(root->left) + BinaryTreeSize(root->right);
}

具体讲解:

实际上就是每一个节点进行一次加加(利用递归)

第二个涉及指针返回值可以是void因为传入的形参为int * psize(psize发生改变全局psize跟着改变)

3.5BinaryTreeLeafSize(BTNode* root)

二叉树叶子节点个数

代码展示

c 复制代码
//二叉树叶子节点个数
int BinaryTreeLeafSize(BTNode* root)
{

	if (root == NULL)
	{
		return 0;
	}
	//如果节点的左节点和右节点都为NULL则该节点为叶子节点
	if (root->left == NULL && root->right == NULL)
	{
		return 1;
	}
	//以上两点都不符合就递归
	return BinaryTreeLeafSize(root->left) + BinaryTreeLeafSize(root->right);
}

具体讲解:

有两种情况

1.头节点为NULL

直接返回

2.头节点的左右指针为NULL(说明就是叶子节点)

返回1

若两点都不符合就返回

c 复制代码
BinaryTreeLeafSize(root->left) + BinaryTreeLeafSize(root->right);

递归遇到节点左右节点为NULL

即为叶子节点

3.6BinaryTreeLevelKSize(BTNode* root, int k)

第k层节点的个数

代码展示

c 复制代码
int BinaryTreeLevelKSize(BTNode* root, int k)
{
	if (root == NULL)
	{
		return 0;
	}
	//第一层只有一个节点
	if (k == 1)
	{
		return 1;
	}
	//用递归从k到1最后相加
	//指向左右节点层数比原来减一
	return BinaryTreeLevelKSize(root->left, k - 1) + BinaryTreeLevelKSize(root->right, k - 1);
}

  

具体讲解

节点为NULL返回0

若刚开始是k为1说明只有一个节点

若不为k就用左右节点递归每个形参的k进行减减

最后递归到只剩k为1是此时出现的数字加加就是该层的节点个数

3.7BinaryTreeDepth(BTNode* root)

二叉树的深度/高度

代码展示

c 复制代码
//二叉树深度/高度
int BinaryTreeDepth(BTNode* root)
{
	if (root == NULL)
	{
		return 0;
	}
	//根据左右子树的深度带判断树的深度
	int leftDep = BinaryTreeDepth(root->left);
	int rightDep = BinaryTreeDepth(root->right);
	//根据root遍历进行深入访问
	return 1 + (leftDep > rightDep ? leftDep : rightDep);
}

具体讲解

c 复制代码
int leftDep = BinaryTreeDepth(root->left);
int rightDep = BinaryTreeDepth(root->right);
c 复制代码
	return 1 + (leftDep > rightDep ? leftDep : rightDep);
}

函数如果头指针为NULL就返回0

若不为0

根据leftDep和rightDep的递归所得到的具体值判断大小即可得到具体的最深高度

加一是如何得到的?

函数每进行一次递归每个函数最终都要加上1

最终得到左右支的深度,最后那个大就取那个加一得到的值就是该二叉树的高度
还有一个自定义函数我就不加以赘述了,有兴趣可以了解一下


文章到这里就告一段落,希望对你有所帮助,感谢观看!

相关推荐
tudousisi2221 小时前
01背包8.21
数据结构·算法
石头猫灯11 小时前
WordPress wp2shell 漏洞链完整拆解流程
网络·数据结构·安全·web安全
小欣加油15 小时前
leetcode3069 将元素分配到两个数组中I
数据结构·c++·算法·leetcode·职场和发展
_Narcissus_18 小时前
排序算法总结表格
c语言·数据结构·c++·笔记·算法·排序算法·总结
一只小小的芙厨19 小时前
前缀和与差分
数据结构·算法
一只小小的芙厨20 小时前
最短路总结
数据结构·算法
来一碗刘肉面1 天前
有向无环图 DAG(描述表达式)
数据结构
郝学胜_神的一滴1 天前
干货版《算法导论》18:遍历增删原理、时间复杂度与集合序列实现全解
数据结构·算法
BK贝壳1 天前
Python底层:1亿个布尔值缓存失效标记,list爆内存numpy爆拷贝,bool-hybrid-array混合存储实测
数据结构·python·缓存·性能优化·list·numpy