【数据结构】二叉树的实现&递归遍历(完整代码)

本次模拟二叉树实现的功能

1.按要求创建一棵树
2.计算树节点,树叶子节点的个数
3.输出树中第n层的节点个数
4.关于树前序,中序,后序的递归遍历
5.树的层序遍历
6.判断树是否为完全二叉树
7.树的前序,中序,后序的非递归遍历

其中二叉树非递归遍历具体实现的讲解,可参考下篇博客: 二叉树的非递归遍历

注意:
二叉树的递归遍历实现:直接按遍历顺序递归调用
二叉树的层序遍历实现:可以借用队列结构来实现
二叉树的非递归遍历实现:可以借用栈结构来实现

前序遍历: 根 – 左 – 右
中序遍历: 左 – 根 – 右
后序遍历: 左 – 右 – 根

代码示例如下:

小编提示:作者用的编译器是VS,若编译器不同,可以将代码中的#define _CRT_SECURE_NO_WARNINGS 1system("pause"); 注释掉,不然直接运行代码的话可能会报错哦~

Tree.h – 头文件
// #define _CRT_SECURE_NO_WARNINGS 1
#ifndef __TREE_H__   //宏的使用,主要防止头文件的重复包含和编译
#define __TREE_H__ 

#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <string.h>

typedef char BTDataType;
typedef struct BinaryTreeNode  //树节点定义
{
	BTDataType _data;
	struct BinaryTreeNode* _left;
	struct BinaryTreeNode* _right;
}BTNode;

//创建树
BTNode *BinaryTreeCreate(BTDataType*a, int*pi);
//销毁树
void BinaryTreeDestory(BTNode* root);
//树的结点
int BinaryTreeSize(BTNode* root);
//树的叶子结点
int BinaryTreeLeafSize(BTNode* root);
//树某一层的结点
int BinaryTreeLevelkSize(BTNode* root, int k);
//找到某个元素
BTNode *BinaryTreeFind(BTNode* root, BTDataType x);
//遍历
void BinaryTreePrevOrder(BTNode* root);  //前序
void BinaryTreeInOrder(BTNode* root);  //中序
void BinaryTreePostOrder(BTNode* root);  //后序
//层序遍历
void BinaryTreeLevelOrder(BTNode* root);
//判断是否完全二叉树
int BinaryTreeComplete(BTNode* root);
//非递归遍历
void BinaryPrevOrder(BTNode* root);  //前序
void BinaryInOrder(BTNode* root);  //中序
void BinaryPostOrder(BTNode* root);  //后序
//测试类
void Test();


 //队列定义以及操作声明
typedef BTNode* QDataType;
typedef struct QueueNode  
{
	QDataType _data;
	struct QueueNode* _next;
}QNode;   //定义队列节点结构

typedef struct Queue
{
	QNode* _head;
	QNode* _tail;
}Qu;   //定义队列指针结构

void QueueInit(Qu* pq);
void QueueDestory(Qu* pq);
void QueuePrint(Qu* pq);
QNode* BuyQueueNode(QDataType x);
void QueuePush(Qu* pq, QDataType x);
void QueuePop(Qu* pq);
QDataType QueueFront(Qu* pq);
QDataType QueueBack(Qu* pq);
int QueueEmpty(Qu* pq);
int QueueSize(Qu* pq);
void TestQueue();

 //栈定义以及操作声明
typedef BTNode* STDataType;
typedef struct Stack 
{
	STDataType* _a;
	int _top;
	int _capacity;
}Stack;  //定义栈结构

void StackInit(Stack* ps);
void StackDestory(Stack* ps);
void StackPush(Stack *ps, STDataType x);
void StackPop(Stack* ps);
STDataType  StackTop(Stack* ps);
int StackEmpty(Stack* ps);
int StackSize(Stack* ps);
void StackPrint(Stack* ps);
void TestStack();

#endif //__TREE_H__


Tree.c – 树的操作
// #define _CRT_SECURE_NO_WARNINGS 1
#include "Tree.h"

BTNode *BinaryTreeCreate(BTDataType*a, int* pi)  //创建树
{
		if (a[*pi] == '#')
		{
			(*pi)++;
			return NULL;
		}
			BTNode* root = (BTNode*)malloc(sizeof(BTNode));
			root->_left = root->_right = NULL;
			root->_data = a[*pi];
			(*pi)++;
			root->_left = BinaryTreeCreate(a, pi);
			root->_right = BinaryTreeCreate(a, pi);
			return root;		
}

void BinaryTreeDestory(BTNode* root)  //销毁树
{
	if (root)
	{
		BinaryTreeDestory(root->_left);
		BinaryTreeDestory(root->_right);
		free(root);
		root = NULL;
	}	
}

int BinaryTreeSize(BTNode* root)  //统计树节点个数
{
	if (root == NULL) 
		return 0;
	return 1 + BinaryTreeSize(root->_left) + BinaryTreeSize(root->_right);
}

int BinaryTreeLeafSize(BTNode* root)   //统计树的叶子节点个数
{
	if (root == NULL)
		return 0;
	else
	{
		if ((root->_left == NULL) && (root->_right == NULL))
			return 1;
		else
		return BinaryTreeLeafSize(root->_left) + BinaryTreeLeafSize(root->_right);
	}
}

int BinaryTreeLevelkSize(BTNode* root, int k)  //递归--统计树中第k层的节点个数
{
	if (root == NULL)		return 0;
	if (k==1)
		return 1;
	return BinaryTreeLevelkSize(root->_left,k-1) + BinaryTreeLevelkSize(root->_right,k-1);
}

BTNode *BinaryTreeFind(BTNode* root, BTDataType x)  //找到某个树节点
{
	BTNode* ret;
	if (root == NULL)	
		return NULL;
	if (root->_data == x)   
		return root;
	 ret = BinaryTreeFind(root->_left, x);
	{
		if (ret)
			return ret;
		ret = BinaryTreeFind(root->_right, x);
		if (ret)
			return ret;
	}	
	return NULL;
}

void BinaryTreePrevOrder(BTNode* root)   //递归--前序遍历
{
	if (root == NULL)
		return;
	printf("%c ", root->_data);
	BinaryTreePrevOrder(root->_left);
	BinaryTreePrevOrder(root->_right);
}

void BinaryTreeInOrder(BTNode* root)   //递归--中序遍历
{
	if (root == NULL)
		return;
	BinaryTreeInOrder(root->_left);
	printf("%c ", root->_data);
	BinaryTreeInOrder(root->_right);
}

void BinaryTreePostOrder(BTNode* root)   //递归--后序遍历
{
	if (root == NULL)
		return;
	BinaryTreePostOrder(root->_left);
	BinaryTreePostOrder(root->_right);
	printf("%c ", root->_data);
}

void BinaryTreeLevelOrder(BTNode* root)  //层序遍历
{
	Qu q;
	QueueInit(&q);
	if (root != NULL)
	{
		QueuePush(&q, root);
		while (QueueEmpty(&q) != 0)
		{
			BTNode* front = QueueFront(&q);
			printf("%c ", front->_data);
			QueuePop(&q);

			if (front->_left)
			    QueuePush(&q, front->_left);
			if (front->_right)
			    QueuePush(&q, front->_right);
		}
	}
}

int BinaryTreeComplete(BTNode* root)   //判断树是否是完全二叉树
{
	Qu q;
	QueueInit(&q);
	if (root != NULL)
	{
		QueuePush(&q, root);
		while (QueueEmpty(&q))
		{
			BTNode* front = QueueFront(&q);
			QueuePop(&q);
			if (front == NULL)
				break;
			QueuePush(&q, front->_left);
			QueuePush(&q, front->_right);
		}
		while (QueueEmpty(&q) )
		{
			BTNode* front = QueueFront(&q);
			if (front != NULL)
			{
				QueueDestory(&q);
				return 0;
			}	
			QueuePop(&q);
		}
		return 1;
	}	
	return 0;
}

void BinaryPrevOrder(BTNode* root)   //非递归--前序遍历
{
	Stack st;
	StackInit(&st);
	BTNode* cur = root;
	while (StackEmpty(&st) != 0 || cur != NULL)
	{
		while (cur != NULL)
		{
			printf("%c ", cur->_data);
			StackPush(&st, cur);
			cur = cur->_left;
		}
		BTNode* top = StackTop(&st);
		StackPop(&st);
		cur=top->_right;
	}
}

void BinaryInOrder(BTNode* root)    //非递归--中序遍历
{
	Stack st;
	StackInit(&st);
	BTNode* cur = root;
	while (StackEmpty(&st) != 0 || cur != NULL)
	{
		while (cur != NULL)
		{
			StackPush(&st, cur);
			cur = cur->_left;
		}
		BTNode* top = StackTop(&st);
		printf("%c ", top->_data);
		StackPop(&st);
		cur = top->_right;
	}
}

void BinaryPostOrder(BTNode* root)    //非递归--后序遍历
{
	BTNode* cur = root;
	BTNode* prev = NULL;
	Stack st;
	StackInit(&st);
	while (cur || StackEmpty(&st) != 0)
	{
		while (cur != NULL)
		{
			StackPush(&st, cur);
			cur = cur->_left;
		}
		BTNode* top = StackTop(&st); 
		if (top->_right == NULL || top->_right == prev)
		{
			StackPop(&st);
			printf("%c ", top->_data);
			prev = top;
		}
		else cur=top->_right;
	} 
}

void Test()  
{
   char a[20] = "ABD##E#H##CF##G##";
   //int sz = (sizeof(a) / sizeof(a[0]));
   int pi = 0;
   int i = 0;
   BTNode* root = BinaryTreeCreate(a, &pi);
   printf("树创建成功!\n");
   printf("树点的个数是: ");
   printf("%d\n", BinaryTreeSize(root));
   printf("树叶子结点的个数是: ");
   printf("%d\n", BinaryTreeLeafSize(root));
   printf("第3层结点的个数是: ");
   printf("%d\n", BinaryTreeLevelkSize(root, 3));
   printf("树前序遍历的结果是: ");
   BinaryTreePrevOrder(root);
   printf("\n");
   printf("树中序遍历的结果是: ");
   BinaryTreeInOrder(root);
   printf("\n");
   printf("树后序遍历的结果是: ");
   BinaryTreePostOrder(root);
   printf("\n");
   printf("树层序遍历的结果是: ");
   BinaryTreeLevelOrder(root);
   printf("\n");
   i=BinaryTreeComplete(root);
   if (i == 1) printf("此树是完全二叉树。\n ");
   else  printf("此树非完全二叉树。\n ");
   printf("\n\n\n 下面是树的非递归遍历!\n");
   printf("树前序遍历的结果是: ");
   BinaryPrevOrder(root);
   printf("\n");
   printf("树中序遍历的结果是: ");
   BinaryInOrder(root);
   printf("\n");
   printf("树后序遍历的结果是: ");
   BinaryPostOrder(root);
   printf("\n");
  BinaryTreeDestory(root);
  printf("销毁成功!\n");
}

Queue.c – 队列的操作(辅助层序遍历)
// #define _CRT_SECURE_NO_WARNINGS 1
#include "Tree.h"

void QueueInit(Qu* pq)  //队列初始化
{
	QDataType x = 0; 
	assert(pq);
	pq->_head = BuyQueueNode(x); 
	pq->_tail = pq->_head;   
}

void QueueDestory(Qu* pq)  //队列销毁
{
	QNode* cur = pq->_head->_next; //节点指针指向队列头节点
	while (cur != NULL)
	{
		QNode* next = cur->_next; //记录下一个节点
		free(cur);  //释放当前节点
		cur = next; //指针指向下一个节点
	}
} 

QNode* BuyQueueNode(QDataType x)  //新增队列节点
{
	QNode* newNode = (QNode*)malloc(sizeof(QNode));  //新增一个节点
	newNode->_data = x;  //为节点赋值
	newNode->_next = NULL;  //节点指针初始化
	return newNode;  //返回当前新增的节点
}

void QueuePush(Qu* pq, QDataType x)  //指定值进入队列
{	
	QNode* newnode = BuyQueueNode(x); //新增指定值的节点
	pq->_tail->_next = newnode;  //连接新节点
	pq->_tail = newnode;  //队列尾指针后移
}

void QueuePop(Qu* pq)  //出队列
{
	assert(pq);
	QNode* 	cur = pq->_head->_next; //结点指针
	if (cur == NULL)  //无节点直接返回
	{
		return;
	}
	if (cur == pq->_tail)  //只有一个节点,尾节点前移
	{
		pq->_tail = pq->_head;
	}
	pq->_head->_next = cur->_next;  //将头节点后移
	free(cur);    //节点释放
}

QDataType QueueFront(Qu* pq)  //返回队列头部的值
{
	QNode* 	cur = pq->_head->_next;
	assert(pq);
	return cur->_data;
}

QDataType QueueBack(Qu*pq)  //队列尾部的值
{
	assert(pq);
	return pq->_tail->_data;
}

int QueueEmpty(Qu* pq)  //队列判空
{
	QNode* 	cur = pq->_head->_next;
	if (cur == NULL)
		return 0;
	else return 1;
}

int QueueSize(Qu* pq)  //队列节点总数
{
	int count = 0;
	QNode* 	cur = pq->_head->_next;
	if (cur == NULL)
		return 0;
	while (cur)
	{
		count++;
		cur = cur->_next;
	}
	return count;
}

void QueuePrint(Qu* pq)  //队列打印
{
	QNode* 	cur = pq->_head->_next;
	assert(pq);
	while (cur != NULL)
	{
		printf("%d  ", cur->_data);
		cur = cur->_next;
	}
	printf("\n");
}
Stack.c – 栈的操作(辅助非递归遍历)
#define _CRT_SECURE_NO_WARNINGS 1
#include "Tree.h"

void StackInit(Stack* ps)
{
	assert(ps);
	ps->_a = NULL;
	ps->_capacity = 0;
	ps->_top = 0;
}

void StackDestory(Stack* ps)
{
	assert(ps);
	ps->_capacity = 0;
	ps->_top = 0;
	free(ps->_a);
	ps->_a = NULL;
}

void StackPush(Stack *ps, STDataType x)
{
	assert(ps);
	if (ps->_top == ps->_capacity)
	{
		size_t newcapacity = (ps->_capacity == 0 ? 4 : ps->_capacity * 2);
		ps->_a = (STDataType*)realloc(ps->_a, sizeof(STDataType)*newcapacity);
		ps->_capacity = newcapacity;
	}
	ps->_a[ps->_top]= x;
	ps->_top++;
}

void StackPop(Stack* ps)
{
	assert(ps&&ps->_top>0);
	ps->_top--;
}

STDataType  StackTop(Stack* ps)
{
	assert(ps&&ps->_top>0);
	return ps->_a[ps->_top - 1];
}

int StackEmpty(Stack* ps)
{
	assert(ps);
	if (ps->_top == 0)
		return 0;
	else return 1;
}

int StackSize(Stack* ps)
{
	assert(ps);
	STDataType size = ps->_top;
	return size;
}

void StackPrint(Stack* ps)
{
	assert(ps);
	while (StackEmpty(ps) != 0)
	{
		printf("%d ", StackTop(ps));
		StackPop(ps);
	}
	printf("\n");
}
test.c – 主文件
#define _CRT_SECURE_NO_WARNINGS 1
#include "Tree.h"


int main()
{
	printf("      *******二叉树的实现******\n");
	Test();
	printf("\n");
	printf("\n");
	printf("\n");
	
//	system("pause");
	return 0;
}
运行结果如下:

在这里插入图片描述

  • 22
    点赞
  • 148
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值