二叉树的链式存储及实现(二叉树的前序遍历,中序遍历,后序遍历,非递归前序遍历,中序遍历,后序遍历,二叉树的查找,寻找叶子结点个数,以及判断一棵树是不是二叉树)

二叉树的链式存储及实现

1、树的概念及结构

1.1、树的结构

树是一种非线性结构,它由n(n>=0)个有限结点组成的一个具有层次关系的集合。把它叫做树是因为它看起来像一颗倒挂的树,也就是说它是一颗根朝上,叶朝下的。
树的特点:
每个结点有零个或多个子结点;
没有父结点的结点称为根结点;
每一个非根结点有且只有一个父结点;
每个子结点可以分为多个不相交的子树。

1.2、树的表示

树的表示方法:
双亲表示法;
孩子表示法;
孩子兄弟表示法;

typedef int DataType
struct Node
{
	struct Node *_firstChild1;	//第一个孩子结点
	struct Node *_pNextBrother;//指向下一个兄弟结点
	DataType _data;				//结点中的数据域
}

在这里插入图片描述

2、二叉树的概念及结构

2.1、二叉树的概念

一颗二叉树是结点的一个有限集合,该集合或者为空,或者是由一个根结点加上两颗别称为左子树和右子树的二叉树组成
二叉树的特点:
每个结点最多有两颗子树,即二叉树不存在度大于2的结点
二叉树的子树有左右之分,其子树的次序不能颠倒

2.2、二叉树的存储结构

2.2.1、顺序存储

顺序结构存储就是使用数组来存储,一般使用数组只适合表示完全二叉树,因为不是完全二叉树会有空间的浪费。而现实使用中只有堆才使用数组来存储,二叉树顺序存储在物理上是一个数组,在逻辑上是一颗二叉树。

2.2.2、链式存储

用链表来表示一颗二叉树,即用链来指示元素的逻辑关系。通常的方法是链表中每个结点由三个域组成,数据域和左右指针域,左右指针分别用来给出该结点左孩子和在右孩子所在的链结点的存储地址。链式结构又分为二叉链和三叉链。

// 二叉链
struct BinaryTreeNode
{
struct BinTreeNode* _pLeft; // 指向当前节点左孩子
struct BinTreeNode* _pRight; // 指向当前节点右孩子
BTDataType _data; // 当前节点值域
}
// 三叉链
struct BinaryTreeNode
{
struct BinTreeNode* _pParent; // 指向当前节点的双亲
struct BinTreeNode* _pLeft; // 指向当前节点左孩子
struct BinTreeNode* _pRight; // 指向当前节点右孩子
BTDataType _data; // 当前节点值域
};

3、二叉树遍历

二叉树的遍历指的是访问二叉树的每个结点,并且对每个结点仅做一次访问。访问结点所做的操作依赖于具体的应用问题。遍历二叉树上最重要的运算之一,是二叉树上进行其它运算的基础。

前序遍历
先访问根结点,再访问左孩子,再访问右孩子
中序遍历
先访问左孩子,再访问根结点,最后访问右孩子
后序遍历
先访问左孩子,再访问右孩子,最后访问根结点
层序遍历
逐层访问每个结点

4、二叉树的链式存储及实现

4.1、二叉树的链式结构

typedef char BinaryTreeDataType;

typedef struct BinaryTreeNode
{
	BinaryTreeDataType _data;
	struct BinaryTreeNode *_left;
	struct BinaryTreeNode *_right;
}BinaryTreeNode;

4.2、二叉树的实现

BinaryTree.h

#ifndef _BINARYTREE_H_
#define _BINARYTREE_H_

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <math.h>
#include "Queue.h"
#include "Stack.h"

typedef char BinaryTreeDataType;

typedef struct BinaryTreeNode
{
	BinaryTreeDataType _data;
	struct BinaryTreeNode *_left;
	struct BinaryTreeNode *_right;
}BinaryTreeNode;

//通过前序遍历数组"ABD##E#H##CF##G##"构建二叉树
BinaryTreeNode* BinaryTreeCreate(BinaryTreeDataType *arr);

//递归遍历
//前序遍历
void BinaryTreePreOrder(BinaryTreeNode *root);
//中序遍历
void BinaryTreeInOrder(BinaryTreeNode *root);
//后序遍历
void BinaryTreePostOrder(BinaryTreeNode *root);
//层序遍历
void BinaryTreeLevelOrder(BinaryTreeNode *root);

//非递归遍历
//前序遍历
void BinaryTreePreOrderNonR(BinaryTreeNode *root);
//中序遍历
void BinaryTreeInOrderNonR(BinaryTreeNode *root);
//后序遍历
void BinaryTreePostOrderNonR(BinaryTreeNode *root);
//返回二叉树的结点个数
int BinaryTreeSize(BinaryTreeNode *root);

//递归实现
//返回叶子结点个数
int BinaryTreeLeafSize(BinaryTreeNode *root);
//返回第K层结点个数
int BinaryTreeLevelKSize(BinaryTreeNode *root, int k);

//非递归实现
//返回叶子结点个数
int BinaryTreeLeafSizeNonR(BinaryTreeNode *root);
//返回第K层结点个数
int BinaryTreeLevelKSizeNonR(BinaryTreeNode *root, int k);

//查找节点x
BinaryTreeNode* BinaryTreeFind(BinaryTreeNode *root, BinaryTreeDataType x);
//判断是否为完全二叉树
int BinaryTreeComplete(BinaryTreeNode *root);
//销毁
void BinaryTreeDestory(BinaryTreeNode *root);

#endif //_BINARYTREE_H_

Queue.h

#ifndef _QUEUE_H_
#define _QUEUE_H_

#define _CRT_SECURE_NO_WARNINGS

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

typedef int QueueDataType;

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

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

//初始化
void QueueInit(Queue *pqueue);
//销毁
void QueueDestory(Queue *pqueue);
//为链表开辟结点
QueueNode* BuyQueueNode(QueueDataType x);
//尾插
void QueuePush(Queue *pqueue, QueueDataType x);
//头删
void QueuePop(Queue *pqueue);
//返回队首元素
QueueDataType QueueFront(Queue *pqueue);
//返回队尾元素
QueueDataType QueueRear(Queue *pqueue);
//判空
int QueueEmpty(Queue *pqueue);
//返回队列长度
int QueueSize(Queue *pqueue);
//打印
void QueuePrint(Queue *pqueue);
#endif //_QUEUE_H_

Stack.h

#ifndef _STACK_H_
#define _STACK_H_

#define _CRT_SECURE_NO_WARNINGS

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

#define CAPACITY 2

typedef int StackDataType;

typedef struct Stack
{
	StackDataType *_array;
	size_t _size;
	size_t _capacity;
}Stack;

//初始化
void StackInit(Stack *pstack, size_t capacity);
//销毁
void StackDestory(Stack *pstack);
//扩容
void CheckCapacity(Stack *pstack);
//压栈
void StackPush(Stack *pstack, StackDataType x);
//弹出
void StackPop(Stack *pstack);
//返回栈顶元素
StackDataType StackTop(Stack *pstack);
//返回栈的大小
int StackSize(Stack *pstack);
//判空
int StackEmpty(Stack *pstack);
//打印
void StackPrint(Stack *pstack);
#endif //_STACK_H_

BinaryTree.c

#include "BinaryTree.h"
#include "Queue.h"
#include "Stack.h"

//通过前序遍历数组"ABD##E#H##CF##G##"构建二叉树
BinaryTreeNode* BinaryTreeCreate(BinaryTreeDataType *arr)
{
	static int i = 0;
	if (arr[i] == '#')
	{
		i++;
		return NULL;
	}
	BinaryTreeNode *cur = (BinaryTreeNode *)malloc(sizeof(BinaryTreeNode));
	cur->_data = arr[i];
	i++;
	cur->_left = BinaryTreeCreate(arr);
	cur->_right = BinaryTreeCreate(arr);
	return cur;
}

//递归遍历
//前序遍历
void BinaryTreePreOrder(BinaryTreeNode *root)
{
	if (root)
	{
		putchar(root->_data);
		BinaryTreePreOrder(root->_left);
		BinaryTreePreOrder(root->_right);
	}
}

//中序遍历
void BinaryTreeInOrder(BinaryTreeNode *root)
{
	if (root)
	{
		BinaryTreeInOrder(root->_left);
		putchar(root->_data);
		BinaryTreeInOrder(root->_right);
	}
}

//后序遍历
void BinaryTreePostOrder(BinaryTreeNode *root)
{
	if (root)
	{
		BinaryTreePostOrder(root->_left);
		BinaryTreePostOrder(root->_right);
		putchar(root->_data);
	}
}

//层序遍历
void BinaryTreeLevelOrder(BinaryTreeNode *root)
{
	BinaryTreeNode *cur;
	Queue queue;
	QueueInit(&queue);
	QueuePush(&queue, root);
	while (!QueueEmpty(&queue))
	{
		cur = QueueFront(&queue);
		putchar(cur->_data);
		if (cur->_left)
		{
			QueuePush(&queue, cur->_left);
		}
		if (cur->_right)
		{
			QueuePush(&queue, cur->_right);
		}
		QueuePop(&queue);
	}
	QueueDestory(&queue);
}

//非递归遍历
//前序遍历
void BinaryTreePreOrderNonR(BinaryTreeNode *root)
{
	BinaryTreeNode *cur = root;
	Stack stack;
	StackInit(&stack, 100);
	while (cur || !StackEmpty(&stack))
	{
		while (cur)
		{
			putchar(cur->_data);
			StackPush(&stack, cur);
			cur = cur->_left;
		}
		if (!StackEmpty(&stack))
		{
			cur = StackTop(&stack);
			StackPop(&stack);
			cur = cur->_right;
		}
	}
	StackDestory(&stack);
}

//中序遍历
void BinaryTreeInOrderNonR(BinaryTreeNode *root)
{
	assert(root);
	BinaryTreeNode *cur = root;
	Stack stack;
	StackInit(&stack, 100);
	while (!StackEmpty(&stack) || cur)
	{
		for (; cur; cur = cur->_left)
		{
			StackPush(&stack, cur);
		}
		cur = StackTop(&stack);
		putchar(cur->_data);
		StackPop(&stack);
		cur = cur->_right;
	}
	StackDestory(&stack);
}

//后序遍历
void BinaryTreePostOrderNonR(BinaryTreeNode *root)
{
	assert(root);
	BinaryTreeNode *cur = root;
	Stack stack;
	char tag[100];
	StackInit(&stack, 100);
	do
	{
		for (; cur; cur = cur->_left)
		{
			StackPush(&stack, cur);
			tag[StackSize(&stack) - 1] = 0;
		}
		while (!StackEmpty(&stack) && tag[StackSize(&stack) - 1])
		{
			cur = StackTop(&stack);
			putchar(cur->_data);
			StackPop(&stack);
		}
		if (!StackEmpty(&stack))
		{
			cur = StackTop(&stack);
			tag[StackSize(&stack) - 1] = 1;
			cur = cur->_right;
		}
	} while (!StackEmpty(&stack));
	StackDestory(&stack);
}

//返回二叉树的结点个数
int BinaryTreeSize(BinaryTreeNode *root)
{
	int count = 0;
	BinaryTreeNode *cur = root;
	Stack stack;
	StackInit(&stack, 100);
	while (cur || !StackEmpty(&stack))
	{
		while (cur)
		{
			//putchar(cur->_data);
			count++;
			StackPush(&stack, cur);
			cur = cur->_left;
		}
		if (!StackEmpty(&stack))
		{
			cur = StackTop(&stack);
			StackPop(&stack);
			cur = cur->_right;
		}
	}
	StackDestory(&stack);
	return count;
}

//递归实现
//返回叶子结点个数
int BinaryTreeLeafSize(BinaryTreeNode *root)
{
	if (root == NULL)
	{
		return 0;
	}
	else if ((root->_left == NULL) && (root->_right == NULL))
	{
		return 1;
	}
	else
	{
		return BinaryTreeLeafSize(root->_left) + BinaryTreeLeafSize(root->_right);
	}
}

//返回第K层结点个数
int BinaryTreeLevelKSize(BinaryTreeNode *root, int k)
{
	if (root == NULL || k <= 0)
	{
		return 0;
	}
	else if (root && k == 1)
	{
		return 1;
	}
	else
	{
		return BinaryTreeLevelKSize(root->_left, k - 1) + BinaryTreeLevelKSize(root->_right, k - 1);
	}
}

//非递归实现
//返回叶子结点个数
int BinaryTreeLeafSizeNonR(BinaryTreeNode *root)
{
	int count = 0;
	BinaryTreeNode *cur = root;
	Stack stack;
	StackInit(&stack, 100);
	while (cur)
	{
		//putchar(cur->_data);
		if (cur->_left == NULL && cur->_right == NULL)
		{
			count++;
		}
		if (cur->_right)
		{
			StackPush(&stack, cur->_right);
		}
		if (cur->_left)
		{
			cur = cur->_left;
		}
		else
		{
			cur = StackTop(&stack);
			StackPop(&stack);
		}
	}
	StackDestory(&stack);
	return count;
}

//返回第K层结点个数
int BinaryTreeLevelKSizeNonR(BinaryTreeNode *root, int k)
{
	if (root == NULL || k <= 0)
	{
		return 0;
	}
	int level = 0;
	int levelsize = 0;
	Queue queue;
	QueueInit(&queue);
	QueuePush(&queue, root);
	while (!QueueEmpty(&queue))
	{
		level++;
		levelsize = QueueSize(&queue);
		if (level == k)
		{
			break;
		}
		int count = 0;
		while (count < levelsize)
		{
			count++;
			BinaryTreeNode *cur = QueueFront(&queue);
			QueuePop(&queue);
			if (cur->_left)
			{
				QueuePush(&queue, cur->_left);
			}
			if (cur->_right)
			{
				QueuePush(&queue, cur->_right);
			}
		}
	}
	QueueDestory(&queue);
	if (level == k)
	{
		return levelsize;
	}
}

//查找节点x
BinaryTreeNode* BinaryTreeFind(BinaryTreeNode *root, BinaryTreeDataType x)
{
	BinaryTreeNode *cur;
	Queue queue;
	QueueInit(&queue);
	QueuePush(&queue, root);
	while (!QueueEmpty(&queue))
	{
		cur = QueueFront(&queue);
		//putchar(cur->_data);
		if (cur->_data == x)
		{
			return cur;
		}
		if (cur->_left)
		{
			QueuePush(&queue, cur->_left);
		}
		if (cur->_right)
		{
			QueuePush(&queue, cur->_right);
		}
		QueuePop(&queue);
	}
	QueueDestory(&queue);
}

//判断是否为完全二叉树
int BinaryTreeComplete(BinaryTreeNode *root)
{
	if (root == NULL)
	{
		return 1;
	}
	BinaryTreeNode *cur;
	Queue queue;
	QueueInit(&queue);
	QueuePush(&queue, root);
	int leaf = 0;
	while (!QueueEmpty(&queue))
	{
		cur = QueueFront(&queue);
		QueuePop(&queue);
		if ((leaf && (cur->_left != NULL || cur->_right != NULL)) || (cur->_left == NULL && cur->_right))
		{
			return 0;
		}
		if (cur->_left != NULL)
		{
			QueuePush(&queue, cur->_left);
		}
		if (cur->_right != NULL)
		{
			QueuePush(&queue, cur->_right);
		}
		if (cur->_left == NULL || cur->_right == NULL)
		{
			leaf = 1;
		}
	}
	return 1;
	QueueDestory(&queue);
}

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

Queue.c

#include "Queue.h"

//初始化
void QueueInit(Queue *pqueue)
{
	assert(pqueue);
	pqueue->_front = NULL;
	pqueue->_rear = NULL;
}

//销毁
void QueueDestory(Queue *pqueue)
{
	assert(pqueue);
	QueueNode *cur = pqueue->_front;
	while (cur)
	{
		QueueNode *tmp = cur->_next;
		free(cur);
		cur = tmp;
	}
	pqueue->_front = NULL;
	pqueue->_rear = NULL;
}

//为链表开辟结点
QueueNode* BuyQueueNode(QueueDataType x)
{
	QueueNode *queuenode = (QueueNode *)malloc(sizeof(QueueNode));
	if (queuenode != NULL)
	{
		queuenode->_data = x;
		queuenode->_next = NULL;
		return queuenode;
	}
	return NULL;
}

//尾插
void QueuePush(Queue *pqueue, QueueDataType x)
{
	assert(pqueue);
	QueueNode *queuenode = BuyQueueNode(x);
	if (QueueEmpty(pqueue))
	{
		pqueue->_front = queuenode;
		pqueue->_rear = queuenode;
	}
	else
	{
		pqueue->_rear->_next = queuenode;
		pqueue->_rear = queuenode;
	}
}

//头删
void QueuePop(Queue *pqueue)
{
	assert(pqueue);
	QueueNode *tmp = pqueue->_front;
	pqueue->_front = tmp->_next;
	free(tmp);
	tmp = NULL;
}

//返回队首元素
QueueDataType QueueFront(Queue *pqueue)
{
	assert(pqueue);
	return pqueue->_front->_data;
}

//返回队尾元素
QueueDataType QueueRear(Queue *pqueue)
{
	assert(pqueue);
	return pqueue->_rear->_data;
}

//判空
int QueueEmpty(Queue *pqueue)
{
	assert(pqueue);
	return pqueue->_front == NULL;
}

//返回队列长度
int QueueSize(Queue *pqueue)
{
	assert(pqueue);
	int count = 0;
	QueueNode *cur = pqueue->_front;
	for (; cur; cur = cur->_next)
	{
		count++;
	}
	return count;
}

//打印
void QueuePrint(Queue *pqueue)
{
	assert(pqueue);
	printf("front <== ");
	QueueNode *cur = pqueue->_front;
	for (; cur; cur = cur->_next)
	{
		printf(" %d <==", cur->_data);
	}
	printf(" real\n");
}

Stack.c

#include "Stack.h"

//初始化
void StackInit(Stack *pstack, size_t capacity)
{
	assert(pstack);
	pstack->_capacity = capacity;
	pstack->_array = (StackDataType *)malloc(capacity*sizeof(StackDataType));
	assert(pstack->_array);
	pstack->_size = 0;
}

//销毁
void StackDestory(Stack *pstack)
{
	assert(pstack);
	if (pstack->_array)
	{
		free(pstack->_array);
		pstack->_array = NULL;
		pstack->_size = 0;
		pstack->_capacity = 0;
	}
}

//扩容
void CheckCapacity(Stack *pstack)
{
	assert(pstack);
	if (pstack->_size == pstack->_capacity)
	{
		pstack->_capacity *= CAPACITY;
		pstack->_array = (StackDataType *)realloc(pstack->_array, pstack->_capacity*sizeof(StackDataType));
	}
}

//压栈
void StackPush(Stack *pstack, StackDataType x)
{
	assert(pstack);
	CheckCapacity(pstack);
	pstack->_array[pstack->_size] = x;
	pstack->_size++;
}

//弹出
void StackPop(Stack *pstack)
{
	assert(pstack || pstack->_size);
	pstack->_size--;
}

//返回栈顶元素
StackDataType StackTop(Stack *pstack)
{
	assert(pstack);
	if (pstack->_array)
	{
		return pstack->_array[pstack->_size - 1];
	}
	return (StackDataType)0;
}

//返回栈的大小
int StackSize(Stack *pstack)
{
	assert(pstack);
	assert(pstack);
	if (pstack->_array)
	{
		return pstack->_size;
	}
	return -1;
}

//判空
int StackEmpty(Stack *pstack)
{
	assert(pstack);
	return pstack->_size == 0;
}

//打印
void StackPrint(Stack *pstack)
{
	assert(pstack);
	for (int i = 0; i < pstack->_size; i++)
	{
		printf("%d--", pstack->_array[i]);
	}
	printf("Top\n");
}

main.c

#include "BinaryTree.h"
#include "Queue.h"
#include "Stack.h"

int main()
{
	BinaryTreeDataType arr[] = "ABD##E#H##CF##G##";
	BinaryTreeNode *root = BinaryTreeCreate(arr);

	BinaryTreePreOrder(root);
	putchar('\n');
	BinaryTreeInOrder(root);
	putchar('\n');
	BinaryTreePostOrder(root);
	putchar('\n');
	BinaryTreeLevelOrder(root);
	putchar('\n');
	BinaryTreePreOrderNonR(root);
	putchar('\n');
	BinaryTreeInOrderNonR(root);
	putchar('\n');
	BinaryTreePostOrderNonR(root);
	putchar('\n');
	printf("BinaryTreeSize = %d\n", BinaryTreeSize(root));
	printf("BinaryTreeLeafSize = %d\n", BinaryTreeLeafSize(root));
	printf("BinaryTreeLevelKSize = %d\n", BinaryTreeLevelKSize(root, 1));
	printf("BinaryTreeLevelKSize = %d\n", BinaryTreeLevelKSize(root, 2));
	printf("BinaryTreeLevelKSize = %d\n", BinaryTreeLevelKSize(root, 3));
	printf("BinaryTreeLevelKSize = %d\n", BinaryTreeLevelKSize(root, 4));
	printf("BinaryTreeFind = %p\n", BinaryTreeFind(root, 'G'));
	printf("BinaryTreeComplete = %d\n", BinaryTreeComplete(root));
	printf("BinaryTreeLevelKSizeNonR = %d\n", BinaryTreeLevelKSizeNonR(root, 1));
	printf("BinaryTreeLevelKSizeNonR = %d\n", BinaryTreeLevelKSizeNonR(root, 2));
	printf("BinaryTreeLevelKSizeNonR = %d\n", BinaryTreeLevelKSizeNonR(root, 3));
	printf("BinaryTreeLevelKSizeNonR = %d\n", BinaryTreeLevelKSizeNonR(root, 4));

	system("pause");
	return 0;
}

发布了117 篇原创文章 · 获赞 48 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/gp1330782530/article/details/104884173