二叉树的相关接口实现

一、4.1二叉树链式结构的遍历
所谓遍历(Traversal)是指沿着某条搜索路线,依次对树中每个结点均做一次且仅做一次访问。访问结点所做
的操作依赖于具体的应用问 题。 遍历是二叉树上最重要的运算之一,是二叉树上进行其它运算之基础。
前序/中序/后序的递归结构遍历:是根据访问结点操作发生位置命名

  1. NLR:前序遍历(Preorder Traversal 亦称先序遍历)——访问根结点的操作发生在遍历其左右子树之前。
  2. LNR:中序遍历(Inorder Traversal)——访问根结点的操作发生在遍历其左右子树之中(间)。
  3. LRN:后序遍历(Postorder Traversal)——访问根结点的操作发生在遍历其左右子树之后。
    由于被访问的结点必是某子树的根,所以N(Node)、L(Left subtree)和R(Right subtree)又可解释为
    根、根的左子树和根的右子树。NLR、LNR和LRN分别又称为先根遍历、中根遍历和后根遍历。

在这里插入图片描述

层序遍历:除了先序遍历、中序遍历、后序遍历外,还可以对二叉树进行层序遍历。设二叉树的根节点所在
层数为1,层序遍历就是从所在二叉树的根节点出发,首先访问第一层的树根节点,然后从左到右访问第2层
上的节点,接着是第三层的节点,以此类推,自上而下,自左至右逐层访问树的结点的过程就是层序遍历。

在这里插入图片描述

二叉树的接口实现
1、头文件

#pragma once
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>

typedef char BTType;

typedef struct BTNode
{
	BTType _data;
	struct BTNode* _left;
	struct BTNode* _right;
}BTNode;

typedef BTNode* QUDataType;

typedef struct QueueNode
{
	QUDataType _data;
	struct QueueNode* _next;
}QueueNode;

typedef struct Queue
{
	QueueNode* _front;
	QueueNode* _rear;
}Queue;

void QueueInit(Queue* q);
void QueueDestory(Queue* q);

void QueuePush(Queue* q, QUDataType x);
void QueuePop(Queue* q);
int QueueSize(Queue* q);
int QueueEmpty(Queue* q);
QUDataType QueueFront(Queue* q);
QUDataType QueueBack(Queue* q);

typedef BTNode* STDataType;

typedef struct Stack
{
	STDataType* _a;
	int _top;
	int _capacity;
}Stack;

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



BTNode* CreatBTree(BTType* str, int* n);

int BinaryTreeSize(BTNode* root);//二叉树节点个数
int BinaryTreeLeafSize(BTNode* root);//儿叉树的叶子节点个数
int BinaryTreeLevelKSize(BTNode* root, int k);//二叉树第k层叶子节点个数
BTNode* BinaryTreeFind(BTNode* root, BTType val);

//递归遍历二叉树
void BinaryTreePrevOrder(BTNode* root);
void BinaryTreeInOrder(BTNode* root);
void BinaryTreePostOrder(BTNode* root);
//二叉树的层序遍历
void BinaryTreeLevelOrder(BTNode* root);
//非递归遍历二叉树
void BinaryTreePrevOrderNonR(BTNode* root);
void BinaryTreeInOrderNonR(BTNode* root);
void BinaryTreePostOrderNonR(BTNode* root);
void Test();

2、定义文件

#include "Tree.h"

BTNode* BuyTreeNode(BTType x)
{
	BTNode* newnode = (BTNode*)malloc(sizeof(BTNode));
	newnode->_data = x;
	newnode->_left = NULL;
	newnode->_right = NULL;
	return newnode;
}
BTNode* CreatBTree(BTType* arr, int* n)
{
	if (arr[*n] != '#')
	{
		BTNode* root = BuyTreeNode(arr[*n]);
		(*n)++;
		root->_left = CreatBTree(arr, n);
		(*n)++;
		root->_right = CreatBTree(arr, n);

		return root;
	}
	else
	{
		return NULL;
	}
}

int BinaryTreeSize(BTNode* root)
{
	if(root == NULL)
		return 0;
	return BinaryTreeSize(root->_left) + BinaryTreeSize(root->_right) + 1; 
}

int BinaryTreeLeafSize(BTNode* root)
{
	if(root == NULL)
		return 0;
	if(root->_left == NULL && root->_right == NULL)
		return 1;
	return BinaryTreeLeafSize(root->_left) + BinaryTreeLeafSize(root->_right);
}

int BinaryTreeLevelKSize(BTNode* root, int k)
{
	if(root == NULL)
		return 0;
	if(root->_left == NULL && root->_right == NULL)
		return 1;
	return BinaryTreeLevelKSize(root->_left, k-1) + BinaryTreeLevelKSize(root->_right, k-1);
}

BTNode* BinaryTreeFind(BTNode* root, BTType val)
{
	BTNode* ret = NULL;
	if(root == NULL)
		return NULL;
	if(root->_data == val)
		return root;
	ret = BinaryTreeFind(root->_left,val);
	if(ret != NULL)
		return ret;
	ret = BinaryTreeFind(root->_right, val);
	if(ret != NULL)
		return ret;
	return NULL;
}


void BinaryLevelOrder(BTNode* root)
{
	Queue s;
	QueueInit(&s);
	if(root != NULL)
	{
		QueuePush(&s, root);
	}
	while(QueueEmpty(&s) == 1)
	{
		BTNode* front = QueueFront(&s);
		QueuePop(&s);
		printf("%s ", front->_data);
		if(front->_left != NULL)
		QueuePush(&s, front->_left);
		if(front->_right != NULL)
		QueuePush(&s, front->_right);
	}
	printf("\n");
}
//非递归前序遍历二叉树的思想为:a.访问他的左路节点b.访问左路节点的右子树
//将所有左路节点入栈的同时并访问,然后拿出栈顶节点,同时出栈顶节点,此时在访问出栈节点的右孩子,
//若右孩子为空直接栈顶节点,若不为空继续入站,访问出栈节点的左路节点和左路节点的右子树,

void BinaryTreePrevOrderNonR(BTNode* root)
{
	BTNode* cur = root;
	BTNode* top = NULL;
	Stack st;
	StackInit(&st, 3);
	while(cur != NULL || StackEmpty(&st) != 0)
	{
		while(cur != NULL)
		{
			printf("%c ", cur->_data);
			StackPush(&st, cur);
			cur = cur->_left;
		}
		top = StackTop(&st);
		StackPop(&st);
		cur = top->_right;
	}
	printf("\n");
}

//中序遍历的思路和前序遍历非递归很相似,也是分为左路节点和左路节点的右子树
//首先把左路节点入栈,不访问,当左路节点没有左左孩子时,那出栈顶节点并且访问,让后出栈顶接节点
//然后把栈节点的右孩子入栈,并且继续上面的过程。
void BinaryTreeInOrderNonR(BTNode* root)
{
	BTNode* cur = root;
	BTNode* top = NULL;
	Stack st;
	StackInit(&st, 3);
	while(cur != NULL || StackEmpty(&st) != 0)
	{
		while(cur != NULL)
		{
			StackPush(&st, cur);
			cur = cur->_left;
		}
		top = StackTop(&st);
		StackPop(&st);
		printf("%c ", top->_data);
		cur = top->_right;
	}
	printf("\n");
}

//后序遍历的非递归遍历时,要判读它的右路节点是否已经被访问过,如果没有访问过就访问。
//首先把根节点入栈,如果根节点的左子树和右子树不存在,或者根节点的左子树和右子树已经
//访问过,直接拿出根节点访问,然后出栈节点,标记为上一个输出节点的prev,在把此时的站栈顶节点
//作为当前节点,若果不满足条件,就把根节点的左子树和右子树一次入栈,当前节点重置为栈顶节点,然后重复操作
void BinaryTreePostOrderNonR(BTNode* root)
{
	BTNode* top = NULL;
	BTNode* prev = NULL;
	BTNode* cur = root;
	Stack st;
	StackInit(&st,3);
	while(cur != NULL || StackEmpty(&st) != 0)
	{
		while(cur != NULL)
		{
			StackPush(&st, cur);
			cur = cur->_left;
		}
		top = StackTop(&st);
		if(top->_right == NULL || top->_right == prev)
		{
			printf("%c ",top->_data);
			StackPop(&st);
			prev = top;
		}
		else
		{
			cur = top->_right;
		}
	}
}

void BinaryTreePrevOrder(BTNode* root)
{
	if(NULL == root)
		return;
	printf("%c ", root->_data);
	BinaryTreePrevOrder(root->_left);
	BinaryTreePrevOrder(root->_right);

}
void BinaryTreeInOrder(BTNode* root);
{
	if(NULL == root)
		return;
	BinaryTreeInOrder(root->_left);
	printf("%c ",root->_data);
	BinaryTreeInOrder(root->_right);
}
void BinaryTreePostOrder(BTNode* root);
{
	if(NULL == root)
		return;
	BinaryTreePostOrder(root->_left);
	BinaryTreePostOrder(root->_right);
	printf("%c ", root->_data);
}
void Test()
{
	int i = 0;
	char* arr = "ABD##E#H##CF#G##";
	BTNode* tree = CreatBTree(arr,&i);
	printf("%d\n", BinaryTreeLeafSize(tree));
	
}

猜你喜欢

转载自blog.csdn.net/aixintianshideshouhu/article/details/83659128