数据结构——树

二叉树

存储结构

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

typedef struct TreeNode *BinTree;
typedef BinTree Postion;
struct TreeNode{
	ElementType Data;
	BinTree Left;
	BinTree Right;
}

二叉树的遍历

先序遍历

遍历过程:
①访问根结点
②先序遍历其左子树
③先序遍历其右子树

void PreOrderTraversal(BinTree BT)
{
	if(BT){
		printf("%d", BT->Data);
		PreOrderTraversal(BT->Left);
		PreOrderTraversal(BT->Right);
	}
}

A (B D F E) (C G H I)
先序遍历 => A B D F E C G H I
在这里插入图片描述

中序遍历

遍历过程:
①中序遍历其左子树
②访问根结点
③中序遍历其右子树

void InOrderTraversal(BinTree BT)
{
	if(BT){
		InOrderTraversal(BT->Left);
		printf("%d", BT->Data);
		InOrderTraversal(BT->Right);
	}
}

(D B E F) A (G H C I)
中序遍历 => D B E F A G H C I
在这里插入图片描述

后序遍历

遍历过程为:
①后序遍历其左子树
②后序遍历其右子树
③访问根结点

void PostOrderTraversal(BinTree BT)
{
	if(BT){
		PostOrderTraversal(BT->Left);
		PostOrderTraversal(BT->Right);
		printf("%d", BT->Data);
	}
}

(D E F B) (H G I C) A
后序遍历 => D E F B H G I C A
在这里插入图片描述

层序遍历

二叉树遍历的核心问题:二维结构的线性化

从结点 访问其左、右子节点,访问左儿子后,右儿子节点怎么办?

需要一个存储结构保存暂时不访问的结点。
存储结构:堆栈、队列

队列实现

遍历从根结点开始,首先将根节点入队,然后开始执行循环:节点出队、访问该节点、其左右儿子入队。
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述在这里插入图片描述
层序的基本过程:先根节点入队,然后:
①从队列中取出一个元素
②访问该元素所指节点
③若该元素所指的左、右孩子节点非空,则将其左、右孩子的指针顺序入队

void LevelOrderTraversal(BinTree BT)
{
	Queue Q;
	BinTree T;
	if(!BT) return;	// 若是空树则直接返回
	Q = CreateQueue(MaxSize); // 创建并初始化队列Q
	AddQ(Q, BT);
	while(!IsEmpty(Q)){
		T = DeleteQ(Q);
		printf("%d\n", T->Data); // 访问取出队列的节点
		if(T->Left) AddQ(Q, T->Left);
		if(T->Right) AddQ(Q, T->Right);
	}
}

遍历应用的例子

例:遍历二叉树的应用:输出二叉树中的叶子结点
· 在二叉树的遍历算法中增加检测结点的“左右子树是否都为空”。

void ProOrderPrintLeaves(BinTree BT)
{
	if(BT){
		if(!BT->Left && !BT->Right)
			printf("%d ", BT->Data);
		ProOrderPrintLeaves(BT->Left);
		ProOrderPrintLeaves(BT->Right);		
	}
}

例:求二叉树的高度
在这里插入图片描述

int PostOrderGetHeight(BinTree BT)
{
	int HL, HR, MaxH=0;
	if(BT){
		HL = PostOrderGetHeight(BT->Left);
		HR = PostOrderGetHeight(BT->Right);
		return (MaxH+1);
	}
	else return 0;
}

例:二元运算表达式树及其遍历
在这里插入图片描述
三种遍历可以得到三种不同的访问结果:
先序遍历:++abc+defg
中序遍历:a+b
c+de+fg
后序遍历:abc*+def+g+

先序和中序遍历序列来确定一颗二叉树

分析: 根据先序遍历序列第一个结点确定根结点 根据根结点在中序遍历序列中分割出左右两个子序列 对左子树和右子树分别递归使用相同的方法继续分解
在这里插入图片描述
例:先序序列:a b c d e f g h i j
中序序列:c b e d a h g i j f

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
在Keil MDK中使用可以通过定义节点结构体和使用指针来实现。下面是一个简单的示例代码: ```c #include <stdio.h> #include <stdlib.h> // 定义节点结构体 typedef struct node { int data; struct node *left; struct node *right; } TreeNode; // 创建节点 TreeNode* create_node(int data) { TreeNode* node = (TreeNode*)malloc(sizeof(TreeNode)); node->data = data; node->left = NULL; node->right = NULL; return node; } // 插入节点 TreeNode* insert_node(TreeNode* root, int data) { if (root == NULL) { return create_node(data); } if (data < root->data) { root->left = insert_node(root->left, data); } else { root->right = insert_node(root->right, data); } return root; } // 计算的深度 int tree_depth(TreeNode* root) { if (root == NULL) { return 0; } int left_depth = tree_depth(root->left); int right_depth = tree_depth(root->right); return (left_depth > right_depth ? left_depth : right_depth) + 1; } int main() { // 创建根节点 TreeNode* root = create_node(5); // 插入节点 root = insert_node(root, 3); root = insert_node(root, 7); root = insert_node(root, 1); root = insert_node(root, 4); root = insert_node(root, 6); root = insert_node(root, 8); // 计算的深度并输出 int depth = tree_depth(root); printf("Tree Depth: %d\n", depth); return 0; } ``` 在这个示例代码中,我们首先定义了一个节点结构体,包含了节点数据和左右子节点指针。然后我们定义了创建节点和插入节点的函数,使用递归的方式实现。最后我们定义了计算深度的函数,并在main函数中使用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值