数据结构-二叉树的代码实现(详解)

这篇具有很好参考价值的文章主要介绍了数据结构-二叉树的代码实现(详解)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

内容:二叉树的前、中,后序遍历,层序遍历,二叉树节点个数,叶子节点个数,二叉树高度,第k层节点的个数,查找某个节点,二叉树销毁,判断是否为完全二叉树

目录

 前序遍历:

中序遍历:

后序遍历:

层次遍历:需要借助队列

 二叉树节点个数:

 二叉树叶子节点的个数:

二叉树的高度:

二叉树第k层的节点个数:

查找某个节点并返回其地址:

二叉树销毁:

判断是否为完全二叉树:借助队列


事前准备:

typedef int BTDataType;
typedef struct BinaryTreeNode//二叉树节点
{
	BTDataType data;
	struct BinaryTreeNode* left;
	struct BinaryTreeNode*right;
}BTNode;

BTNode* BuyNode(BTDataType x)//创建一个节点
{
	BTNode* node = (BTNode*)malloc(sizeof(BTNode));
	if (node == NULL)
	{
		perror("malloc fail");
		return NULL;
	}
	node->data = x;
	node->left = NULL;
	node->right = NULL;
	return node;
}

手动构造一个二叉树,用以验证:图示如下

BTNode* CreatBinaryTree()
{
	BTNode* node1 = BuyNode(1);
	BTNode* node2 = BuyNode(2);
	BTNode* node3 = BuyNode(3);
	BTNode* node4 = BuyNode(4);

	node1->left = node2;
	node1->right = node3;
	node2->left = node4;

	return node1;
}

二叉树代码实现,数据结构,数据结构

 前序遍历:

void PrevOrder(BTNode* root)
{
	if (root == NULL)//进入一个空树
	{
		printf("N ");
		return;
	}

	printf("%d ", root->data);//访问根节点的值
	PrevOrder(root->left);//访问左子树
	PrevOrder(root->right);//访问右子树
}

二叉树代码实现,数据结构,数据结构  

中序遍历:

void InOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("N ");
		return;
	}

	InOrder(root->left);//访问左子树
	printf("%d ", root->data);//访问根节点
	InOrder(root->right);//访问右子树
}

二叉树代码实现,数据结构,数据结构 

后序遍历:

void PostOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("N ");
		return;
	}

	PostOrder(root->left);//访问左子树
	PostOrder(root->right);//访问右子树
	printf("%d ", root->data);//访问根节点
}

二叉树代码实现,数据结构,数据结构

层次遍历:需要借助队列

借助队列先进先出的性质,一个节点出队,带入它不为空的左右孩子入队

相关队列功能的所需函数及队列结构的定义:

typedef struct BinaryTreeNode* QDataType;
typedef struct QueueNode//队列中的节点
{
	QDataType data;
	struct QueueNode* next;
}QNode;

typedef struct Queue//队列
{
	QNode* phead;//指向队头的指针
	QNode* ptail;//指向队尾的指针
	int size;
}Queue;

void QueueInit(Queue* pq);//初始化
void QueueDestroy(Queue* pq);//销毁
void QueuePush(Queue* pq, QDataType x);//插入
void QueuePop(Queue* pq);//删除
QDataType QueueFront(Queue* pq);//获取队头元素
bool QueueEmpty(Queue* pq);//判空

 

void QueueInit(Queue* pq)
{
	assert(pq);//断言,pq一定不为空
	pq->phead = NULL;
	pq->ptail = NULL;
	pq->size = 0;
}

void QueueDestroy(Queue* pq)
{
	assert(pq);
	QNode* cur = pq->phead;
	while (cur)
	{
		QNode* next = cur->next;
		free(cur);
		cur = next;
	}

	pq->phead = pq->ptail = NULL;
	pq->size = 0;
}

void QueuePush(Queue* pq, QDataType x)
{
	assert(pq);
	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	if (newnode == NULL)
	{
		perror("malloc fail");
		return;
	}
	newnode->data = x;
	newnode->next = NULL;

	if (pq->ptail == NULL)//第一次插入,链表中没有节点
	{
		assert(pq->phead == NULL);
		pq->phead = pq->ptail = newnode;
	}
	else//尾插
	{
		pq->ptail->next = newnode;
		pq->ptail = newnode;
	}
	pq->size++;
}

void QueuePop(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));
	if (pq->phead->next == NULL)//链表中仅有一个节点
	{
		free(pq->phead);
		pq->phead = pq->ptail = NULL;
	}
	else//多个节点,头删
	{
		QNode* next = pq->phead->next;
		free(pq->phead);
		pq->phead = next;
	}
	pq->size--;
}

QDataType QueueFront(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));
	return pq->phead->data;
}


bool QueueEmpty(Queue* pq)
{
	assert(pq);
	return pq->size == 0;
}

层序遍历:

void LeverOrder(BTNode* root)
{
	Queue q;
	QueueInit(&q);

	if (root)//将根节点入队
	{
		QueuePush(&q, root);
	}

	while (!QueueEmpty(&q))//一个节点出队,带入它的左右孩子
	{
		BTNode* front = QueueFront(&q);
		QueuePop(&q);
		printf("%d ", front->data);

		if (front->left)//左孩子不为空,入队
		{
			QueuePush(&q, front->left);
		}

		if (front->right)//右孩子不为空,入队
		{
			QueuePush(&q, front->right);
		}
	}

	printf("\n");
	QueueDestroy(&q);
}

二叉树代码实现,数据结构,数据结构

 二叉树节点个数:

空树返回0 

非空树返回:左子树节点的个数+右子树节点的个数+1

int BTreeSize(BTNode* root)
{
	return root == NULL ? 0 : BTreeSize(root->left)
		                    + BTreeSize(root->right) + 1;
}

二叉树代码实现,数据结构,数据结构

 二叉树叶子节点的个数:

进入一个空树返回0

非空树:若本身是叶子,返回1,否则返回左子树叶子的个数+右子树叶子的个数

int BTreeLeafSize(BTNode* root)
{
	if (root == NULL)
	{
		return 0;
	}

	if (root->left == NULL && root->right == NULL)//本身是叶子
	{
		return 1;
	}

	return BTreeLeafSize(root->left) + BTreeLeafSize(root->right);//非叶子
}

二叉树代码实现,数据结构,数据结构

二叉树的高度:

 进入一个空树,返回0

非空树:找出左右子树高度更高的一个,返回其+1

int BTreeHeight(BTNode* root)
{
	if (root == NULL)
	{
		return 0;
	}

	int leftHeight = BTreeHeight(root->left);
	int rightHeight = BTreeHeight(root->right);

	return leftHeight > rightHeight ? leftHeight + 1 : rightHeight + 1;
}

二叉树代码实现,数据结构,数据结构

二叉树第k层的节点个数:

 进入空树,返回0

非空树:若它的k==1,则求的就是它这一层,返回1

              否则,返回它左子树第k-1层的节点个数+右子树第k-1层的节点个数

int BTreeLevelKSize(BTNode* root,int k)
{
	assert(k > 0);
	if (root == NULL)
	{
		return 0;
	}

	if (k == 1)
	{
		return 1;
	}

	return BTreeLevelKSize(root->left, k - 1)
		+ BTreeLevelKSize(root->right, k - 1);
}

如求其第2层的节点个数:

二叉树代码实现,数据结构,数据结构

查找某个节点并返回其地址:

BTNode* BTreeFind(BTNode* root, BTDataType x)
{
	if (root == NULL)
	{
		return NULL;
	}

	if (root->data == x)//根节点就是,直接返回
	{
		return root;
	}

	BTNode* ret1 = BTreeFind(root->left, x);//去左子树找
	if (ret1)//找到了,返回
	{
		return ret1;
	}

	BTNode* ret2 = BTreeFind(root->right, x);//去右子树找
	if (ret2)//找到了,返回
	{
		return ret2;
	}

	return NULL;//根,左子树,右子树全都找不到,返回NULL
}

二叉树销毁:

void BTreeDestroy(BTNode* root)
{
	if (root == NULL)//进入空树,返回
	{
		return;
	}

	BTreeDestroy(root->left);//销毁左子树
	BTreeDestroy(root->right);//销毁右子树
	free(root);//销毁根节点
}

判断是否为完全二叉树:借助队列

一个节点出队,让它的左右孩子进队,不管左右孩子是否为空

若是完全·二叉树,则出到第一个NULL时,这个NULL后面的所有队列元素都是NULL

若不是完全二叉树,则出到第一个NULL时,这个NULL后面的所有队列元素中有元素不是NULL

bool BTreeComplete(BTNode* root)
{
	Queue q;
	QueueInit(&q);

	if (root)//根节点入队
	{
		QueuePush(&q, root);
	}

	while (!QueueEmpty(&q))//出队列元素
	{
		BTNode* front = QueueFront(&q);
		QueuePop(&q);
		if (front == NULL)//出到第一个NULL,结束循环,进行判断它后面的所有处在队列中的元素是否都为NULL
		{
			break;
		}

		QueuePush(&q, front->left);//不管是否为空,左右孩子都进队
		QueuePush(&q, front->right);
	}

	while (!QueueEmpty(&q))//判断第一个NULL出队后,队中所有元素的情况
	{
		BTNode* front = QueueFront(&q);
		QueuePop(&q);

		if (front)//如果队中有非空节点,则不是完全二叉树
		{
			QueueDestroy(&q);
			return false;
		}
	}
	QueueDestroy(&q);
	return true;//第一个NULL出队后,队中所有元素均为NULL
}

二叉树代码实现,数据结构,数据结构

完结撒花~ 文章来源地址https://www.toymoban.com/news/detail-771866.html

到了这里,关于数据结构-二叉树的代码实现(详解)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【数据结构】树、二叉树的概念和二叉树的顺序结构及实现

    之前我们学习了顺序表、链表以及栈和队列这些数据结构,但这些数据结构都是线性的(一对一)。接下来要学习 非线性的数据结构——树(二叉树) ,相比前面的,树的结构更加复杂,话不多说,直接进入正题吧。 树是一种 非线性的数据结构 ,它是 一对多(也有可能是

    2024年02月07日
    浏览(40)
  • 【数据结构 —— 二叉树的链式结构实现】

    树是一种非线性的数据结构,它是由n(n=0)个有限结点组成一个具有层次关系的集合。 把它叫做树是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。 1.有一个 特殊的结点,称为根结点 ,根节点没有前驱结点 2.除根节点外, 其余结点被分成M(M0)个互不相交

    2024年02月05日
    浏览(54)
  • 【数据结构—二叉树的链式结构实现】

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一、二叉树的存储结构 二、二叉树链式结构的实现 2.1手动构建一课树 2.2二叉树的遍历 三、二叉树链式结构的实现 3.1前序遍历(递归) 3.2中序遍历(递归) 3.3后序遍历(递归) 3.4层序遍历(非递

    2024年02月03日
    浏览(56)
  • 【数据结构】二叉树的实现

    一棵二叉树是结点的一个有限集合,该集合分为两点: 一是为空和二是由一个根节点加上两棵别称为左子树和右子树的二叉树组成从图上看出有2个性质: 二叉树不存在度大于2的结点 二叉树的子树有左右之分,次序不能颠倒,因此二叉树是有序树 对于任意的二叉树都是由以下

    2024年02月02日
    浏览(38)
  • 【数据结构】二叉树的链式结构及实现

    目录 1. 前置说明 2. 二叉树的遍历 2.1 前序、中序以及后序遍历 2.2 层序遍历 3. 节点个数及高度等 4. 二叉树的创建和销毁 在学习二叉树的基本操作前,需先要创建一棵二叉树,然后才能学习其相关的基本操作。由于现在大家对二叉树结构掌握还不够深入,为了降低大家学习成

    2024年02月08日
    浏览(41)
  • 数据结构:二叉树的链式结构的实现

      目录  1.通过前序遍历构建二叉树 2. 二叉树的销毁  3.二叉树的遍历 4. 二叉树的节点个位和二叉树的叶子节点个位数 5. 二叉树的的k层节点数和查找值为x的节点 6. 判断二叉树是否为完全二叉树和求二叉树的高度h 二叉树的前序遍历 二叉树的中序遍历 二叉树的后序遍历

    2024年02月12日
    浏览(44)
  • 【数据结构】二叉树的顺序结构及实现

    目录 1. 二叉树的顺序结构 2. 堆的概念及结构 3. 堆的实现 3.1 堆向下调整算法 3.2 堆的创建 3.3 建堆时间复杂度 3.4 堆的插入 3.5 堆的删除 3.6 堆的代码实现 4. 堆的应用 4.1 堆排序 4.2 TOP-K问题 普通的二叉树是不适合用数组来存储的,因为可能会存在大量的空间浪费。而完全二叉

    2024年02月08日
    浏览(40)
  • 【数据结构】二叉树的模拟实现

    前言:前面我们学习了堆的模拟实现,今天我们来进一步学习二叉树,当然了内容肯定是越来越难的,各位我们一起努力! 💖 博主CSDN主页:卫卫卫的个人主页 💞 👉 专栏分类:数据结构 👈 💯代码仓库:卫卫周大胖的学习日记💫 💪关注博主和博主一起学习!一起努力! 树是一

    2024年02月03日
    浏览(35)
  • 【数据结构】二叉树的链式结构的实现 -- 详解

    在学习二叉树的基本操作前,需先要创建一棵二叉树,然后才能学习其相关的基本操作。为了降低大家学习成本,此处手动快速创建一棵简单的二叉树,快速进入二叉树操作学习。 注意 :上述代码并不是创建二叉树的方式。 学习二叉树结构,最简单的方式就是遍历。所谓

    2024年02月12日
    浏览(40)
  • 【数据结构】二叉树---红黑树的实现

    目录 一.  红黑树的概念及性质 二.  红黑树结点结构的定义 三.  红黑树的插入操作      1. 情况一      2. 情况二        3. 情况三 四.  红黑树的验证 五.  红黑树与AVL树的比较 红黑树是一种自平衡的二叉搜索树,它在每个节点上增加了一个存储位来表示节点的颜色,

    2024年03月21日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包