树的前、中、后序、层序遍历

这篇博客详细介绍了如何使用链式队列数据结构实现二叉树的前序、中序、后序以及层序遍历。通过C语言代码展示了从数组表示的二叉树到链式队列的转换,以及如何进行各种遍历操作。此外,还提供了顺序存储双亲表示法的树结构,并实现了层序遍历。
摘要由CSDN通过智能技术生成

层序遍历:
1、首先将二叉树的根节点push到队列中,判断队列不为NULL,就输出队头的元素,
2、判断节点如果有孩子,就将孩子push到队列中,
3、遍历过的节点出队列,
4、循环以上操作,直到Tree == NULL。
前中后、层序遍历代码:

list_queue.h
#ifndef LIST_QUEUE_H
#define LIST_QUEUE_H

#include <stdlib.h>
#include <stdbool.h>

#define TYPE int

//	设计节点
typedef struct Node
{
	TYPE data;
	struct Node* next;
}Node;

//	设计链式队列结构
typedef struct ListQueue
{
	Node* head;	//	指向队头节点的指针
	Node* tail;	//	指向队尾节点的指针
	size_t size;//	节点个数
}ListQueue;

//	创建节点
Node* create_node(TYPE val);

//	创建队列结构
ListQueue* create_list_queue(void);

//	队空
bool empty_list_queue(ListQueue* queue);

//	入队
void push_list_queue(ListQueue* queue,TYPE val);

//	出队
bool pop_list_queue(ListQueue* queue);

//	队头
TYPE head_list_queue(ListQueue* queue);

//	队尾
TYPE tail_list_queue(ListQueue* queue);

//	数量
size_t size_list_queue(ListQueue* queue);

//	销毁
void destory_list_queue(ListQueue* queue);

#endif//LIST_QUEUE_H
list_queue.c
#include "list_queue.h"

//	创建节点
Node* create_node(TYPE val)
{
	Node* node = malloc(sizeof(Node));
	node->data = val;
	node->next = NULL;
	return node;
}

//	创建队列结构
ListQueue* create_list_queue(void)
{
	ListQueue* queue = malloc(sizeof(ListQueue));
	queue->head = NULL;
	queue->tail = NULL;
	queue->size = 0;
	return queue;
}


//	队空
bool empty_list_queue(ListQueue* queue)
{
	return !queue->size;	
}

//	入队
void push_list_queue(ListQueue* queue,TYPE val)
{
	Node* node = create_node(val);	
	if(empty_list_queue(queue))
	{
		queue->head = node;
		queue->tail = node;
	}
	else
	{
		queue->tail->next = node;	
		queue->tail = node;
	}
	queue->size++;
}

//	出队
bool pop_list_queue(ListQueue* queue)
{
	if(empty_list_queue(queue)) return false;
	Node* temp = queue->head;
	queue->head = temp->next;
	queue->size--;
	free(temp);
	empty_list_queue(queue) && (queue->tail = NULL);
	return true;
}

//	队头
TYPE head_list_queue(ListQueue* queue)
{
	return queue->head->data;	
}

//	队尾
TYPE tail_list_queue(ListQueue* queue)
{
	return queue->tail->data;	
}

//	数量
size_t size_list_queue(ListQueue* queue)
{
	return queue->size;	
}

//	销毁
void destory_list_queue(ListQueue* queue)
{
	while(pop_list_queue(queue));
	free(queue);
}

bin_arry_tree.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include "list_queue.h"

#define TREE_TYPE char
#define EMPTY '#'

typedef struct BinTree
{
	TREE_TYPE* arr;
	size_t cal;
}BinTree;

//	构建
BinTree* create_tree(TREE_TYPE* arr,size_t len)
{
	BinTree* tree = malloc(sizeof(BinTree));
	tree->arr = malloc(sizeof(TREE_TYPE)*len);
	//	把arr拷贝到tree->arr
	memcpy(tree->arr,arr,sizeof(TREE_TYPE)*len);
	tree->cal = len;
	return tree;
}

//	销毁
void destory_tree(BinTree* tree)
{
	free(tree->arr);
	free(tree);
}

void _dlr_show(BinTree* tree,size_t index)
{
	if(index-1 >= tree->cal || EMPTY == tree->arr[index-1]) return;
	printf("%c ",tree->arr[index-1]);
	_dlr_show(tree,index*2);
	_dlr_show(tree,index*2+1);
}

//	前序遍历
void dlr_show(BinTree* tree)
{
	_dlr_show(tree,1);
	printf("\n");
}

void _ldr_show(BinTree* tree,size_t index)
{
	if(index-1 >= tree->cal || EMPTY == tree->arr[index-1]) return;
	
	_ldr_show(tree,index*2);
	printf("%c ",tree->arr[index-1]);
	_ldr_show(tree,index*2+1);
}

//	中序遍历
void ldr_show(BinTree* tree)
{
	_ldr_show(tree,1);	
	printf("\n");
}

void _lrd_show(BinTree* tree,size_t index)
{
	if(index-1 >= tree->cal || EMPTY == tree->arr[index-1]) return;
	
	_lrd_show(tree,index*2);
	_lrd_show(tree,index*2+1);
	printf("%c ",tree->arr[index-1]);
}

//	后序遍历
void lrd_show(BinTree* tree)
{
	_lrd_show(tree,1);	
	printf("\n");
}

//	层序遍历
void level_show(BinTree* tree)
{
	//	创建队列
	ListQueue* queue = create_list_queue();
	//	根入队
	push_list_queue(queue,1);
	
	while(!empty_list_queue(queue))
	{
	//	获取队头
		int index = head_list_queue(queue);
	//	计算左右子树编号
		int left = index*2;
	//	子树入队
		if(left-1 < tree->cal && EMPTY != tree->arr[left-1])
		{
			push_list_queue(queue,left);
		}
		int right = index*2+1;
		if(right-1 < tree->cal && EMPTY != tree->arr[right-1])
		{
			push_list_queue(queue,right);	
		}
	//	打印队头
		printf("%c ",tree->arr[index-1]);
	//	队头出队
		pop_list_queue(queue);
	}
	destory_list_queue(queue);
}

int main(int argc,const char* argv[])
{
	BinTree* tree = create_tree("ABCD#EFG###HI",13);
	dlr_show(tree);
	ldr_show(tree);
	lrd_show(tree);
	level_show(tree);
}
arr_tree.c
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include "list_queue.h"

//	顺序存储 双亲表示法

//	设计节点
typedef struct TreeNode
{
	char data;	//	数据
	int parent;	//	双亲节点下标
}TreeNode;

//	设计树的顺序结构
typedef struct Tree
{
	TreeNode* arr;	//	存储节点内存的首地址
	size_t cal;		//	容量
	size_t cnt;		//	节点个数
}Tree;

//	创建
Tree* create_tree(size_t cal)
{
	Tree* tree = malloc(sizeof(Tree));
	tree->arr = malloc(sizeof(TreeNode)*cal);
	tree->cal = cal;
	tree->cnt = 0;
	return tree;
}

//	parent是双亲的data
bool add_tree(Tree* tree,char data,char parent)
{
	//	树不存在满的情况,可以扩容
	if(tree->cnt >= tree->cal)
	{
		tree->cal *= 2;
		tree->arr = realloc(tree->arr,sizeof(TreeNode)*tree->cal);
	}

	//	默认根节点的双亲是'\0'
	if('\0' == parent)
	{
		tree->arr[0].data = data;
		tree->arr[0].parent = -1;
		tree->cnt = 1;
		return true;
	}

	for(int i=0; i<tree->cnt; i++)
	{
		if(tree->arr[i].data == parent)
		{
			tree->arr[tree->cnt].data = data;
			tree->arr[tree->cnt++].parent = i;
			return true;
		}
	}
	return false;
}

void show_tree(Tree* tree)
{
	for(int i=0; i<tree->cnt; i++)
	{
		printf("index: %d  data: %c parent: %d\n",
			i,tree->arr[i].data,tree->arr[i].parent);
	}
}

//	计算节点的度
int node_count(Tree* tree,char data)
{
	int count = 0,index = -1;
	for(int i=0; i<tree->cnt; i++)
	{
		if(data == tree->arr[i].data)
		{
			index = i;
			break;
		}	
	}
	if(-1 == index) return -1;
	for(int i=0; i<tree->cnt; i++)
	{
		if(index == tree->arr[i].parent)
		{
			count++;	
		}
	}
	return count;
}

//	层序遍历 
void level_show_tree(Tree* tree)
{
	//	创建一个队列
	ListQueue* queue = create_list_queue();

	//	根节点入队
	push_list_queue(queue,tree->arr[0].data);

	while(!empty_list_queue(queue))
	{
		//	出队队头并显示
		char data = head_list_queue(queue);
		printf("%c ",data);
		pop_list_queue(queue);

		//	找出该节点的子节点并入队
		int index = -1;
		for(int i=0; i<tree->cnt; i++)
		{
			if(data == tree->arr[i].data)
			{
				index = i;
				break;
			}
		}
		for(int i=0; i<tree->cnt; i++)
		{
			if(index == tree->arr[i].parent)
			{
				push_list_queue(queue,tree->arr[i].data);	
			}
		}
	}
	//	销毁队列
	destory_list_queue(queue);
}

int main(int argc,const char* argv[])
{
	Tree* tree = create_tree(10);
	add_tree(tree,'A','\0');
	add_tree(tree,'B','A');
	add_tree(tree,'C','A');
	add_tree(tree,'D','B');
	add_tree(tree,'E','C');
	add_tree(tree,'F','C');
	add_tree(tree,'G','D');
	add_tree(tree,'H','E');
	add_tree(tree,'I','E');
	add_tree(tree,'X','B');
	add_tree(tree,'Y','B');
	show_tree(tree);
	printf("count:%d\n",node_count(tree,'C'));
	level_show_tree(tree);
}
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值