二叉树及二叉树的基本操作(递归与非递归)



树是由一个或多个结点组成的有限集合,其中:

⒈必有一个特定的称为根(ROOT)的结点;

⒉剩下的结点被分成n>=0个互不相交的集合T1、T2、......Tn,而且, 这些集合的每一个又都是树。树T1、T2、......Tn被称作根的子树(Subtree)。

树的递归定义如下:(1)至少有一个结点(称为根)(2)其它是互不相交的子树

1.树的度——也即是宽度,简单地说,就是结点的分支数。以组成该树各结点中最大的度作为该树的度,如上图的树,其度为2;树中度为零的结点称为叶结点或终端结点。树中度不为零的结点称为分枝结点或非终端结点。除根结点外的分枝结点统称为内部结点。

2.树的深度——组成该树各结点的最大层次。

3.森林——指若干棵互不相交的树的集合,如上图,去掉根结点A,其原来的二棵子树T1、T2、T3的集合{T1,T2,T3}就为森林;

4.有序树——指树中同层结点从左到右有次序排列,它们之间的次序不能互换,这样的树称为有序树,否则称为无序树。





Bintree.h

#pragma once

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<malloc.h>
#include<string.h>
#include"queue.h"
#include"stack.h"

typedef char BTDataType;
typedef struct BinTreeNode
{
	BTDataType _data;
	struct BinTreeNode* _pLeft;
	struct BinTreeNode* _pRight;
}BTNode, *PBTNode;

void _CreateBintree(PBTNode* pRoot,const BTDataType* arr, int size, int* index,BTDataType invalid);
void CreateBinTree(PBTNode* pRoot,const BTDataType* arr, int size, BTDataType invalid);
PBTNode BuyBinTreeNode(BTDataType data);
void PreOrder(PBTNode pRoot);
PBTNode Copy(PBTNode pRoot);
void DestroyBinTree(PBTNode* pRoot);
void PreOrderNor(PBTNode pRoot);//前序遍历非递归
void PreOrderNor2(PBTNode pRoot);//前序遍历非递归2
void InOrder(PBTNode pRoot);//中序遍历
void PostOrder(PBTNode pRoot);//后序遍历
void LevelOrder(PBTNode pRoot);//层序遍历
int BintreeNodeSize(PBTNode pRoot);//结点个数
int BintreeLeafSize(PBTNode pRoot);//叶结点个数
int BintreeLevelNodesize(PBTNode pRoot,int k);//k层结点个数
int BintreeHigh(PBTNode pRoot);//二叉树高度
void swap(PBTNode *left, PBTNode *right);
void MirrorBinTree(PBTNode pRoot);// 二叉树的镜像递归 
void MirrorBinTreeNor(PBTNode pRoot);// 二叉树的镜像非递归 


Bintree.c

#include"Bintree.h"

PBTNode BuyBinTreeNode(BTDataType data)
{
	PBTNode pNewNode = (PBTNode)malloc(sizeof(BTNode));
	if (NULL == pNewNode)
	{
		assert(0);//0为假,打印一条错误信息,然后停止程序运行
		return NULL;
	}
	pNewNode->_pLeft = NULL;
	pNewNode->_pRight = NULL;
	pNewNode->_data = data;
	return pNewNode;
}

void _CreateBintree(PBTNode* pRoot, const BTDataType* arr, int size, int* index ,BTDataType invalid)
{
	assert(pRoot);
	assert(index);
	if (*index < size && invalid != arr[*index])
	{
		//创建根节点
		*pRoot = BuyBinTreeNode(arr[*index]);
		//创建左子树
		++(*index);//防止递归时索引回退,应优先向后走
		_CreateBintree(&(*pRoot)->_pLeft, arr, size, index,invalid);

		++(*index);//防止递归时索引回退,应优先向后走
		_CreateBintree(&(*pRoot)->_pRight, arr, size, index,invalid);
		//创建右子树
	}
	
}

void CreateBinTree(PBTNode* pRoot,const BTDataType* arr, int size, BTDataType invalid)
{
	int index = 0;
	_CreateBintree(pRoot, arr, size, &index, invalid);

}

PBTNode Copy(PBTNode pRoot)
{
	PBTNode pNewNode = NULL;
	if (pRoot)
	{
		//拷贝根节点
		pNewNode = BuyBinTreeNode(pRoot->_data);
		//拷贝左子数
		if(pRoot->_pLeft)//判读是否有左子树,避免无效递归
		pNewNode->_pLeft = Copy(pRoot->_pLeft);
		//拷贝右子树
		if(pRoot->_pRight)//判读是否有右子树,避免无效递归
		pNewNode->_pRight = Copy(pRoot->_pRight);
	}
	return pNewNode;
}

void DestroyBinTree(PBTNode* pRoot)
{
	//不能按照前序遍历销毁,销毁根之后左右子树找不到
	//应使用后续遍历销毁
	assert(pRoot);
	if (*pRoot)
	{
		DestroyBinTree(&(*pRoot)->_pLeft);
		DestroyBinTree(&(*pRoot)->_pRight);
		free(*pRoot);
		*pRoot = NULL;
	}
}

void PreOrderNor(PBTNode pRoot)//前序遍历非递归
{
	Stack q;
	if (NULL == pRoot)
	{
		return;
	}
	StackInit(&q);
	StackPush(&q, pRoot);
	while (!StackEmpty(&q))
	{
		PBTNode pCur = StackTop(&q);
		printf("%c", pCur->_data);
		StackPop(&q);
		if (pCur->_pRight)
		{
			StackPush(&q, pCur->_pRight);
		}
		if (pCur->_pLeft)
		{
			StackPush(&q, pCur->_pLeft);
		}
	}
}

void PreOrderNor2(PBTNode pRoot)//前序遍历非递归2
{
	Stack s;
	if (NULL == pRoot)
	{
		return;
	}
	StackInit(&s);
	StackPush(&s, pRoot);
	while(!StackEmpty(&s))
	{
		PBTNode pCur = StackTop(&s);
		StackPop(&s);
		while (pCur)
		{
			printf("%c",pCur->_data);
			if (pCur->_pRight)
				StackPush(&s,pCur->_pRight);
			pCur = pCur->_pLeft;
		}
	
	}
}
void PreOrder(PBTNode pRoot)//前序
{
	if (pRoot)
	{
		printf("%c", pRoot->_data);
		PreOrder(pRoot->_pLeft);
		PreOrder(pRoot->_pRight);
	}
}

void InOrder(PBTNode pRoot)//中序遍历
{
	PreOrder(pRoot->_pLeft);
	printf("%c", pRoot->_data);
	PreOrder(pRoot->_pRight);
}

void PostOrder(PBTNode pRoot)//后序遍历
{
	if (pRoot)
	{
		PreOrder(pRoot->_pLeft);
		PreOrder(pRoot->_pRight);
		printf("%c", pRoot->_data);
	}
}

void LevelOrder(PBTNode pRoot)
{
	//1取队头元素
	//2访问
	//3找到对头元素的左右子树入队列
	//4队头出队列------循环,队列为空时终止
	LQueue q;
	if (NULL == pRoot)
	{
		return;
	}
	InitQueue(&q);
	PushQueue(&q,pRoot);
	while(!QueueEmpyt(&q))
	{
		PBTNode pCur = QueueFront(&q);
		printf("%c", pCur->_data);
		if (pCur->_pLeft)
		{
			PushQueue(&q,pCur->_pLeft);
		}
		if (pCur->_pRight)
		{
			PushQueue(&q, pCur->_pRight);
		}
		PopQueue(&q);
	}
}

int BintreeNodeSize(PBTNode pRoot)
{
	if (NULL == pRoot)
		return 0;
	return BintreeNodeSize(pRoot->_pLeft) + BintreeNodeSize(pRoot->_pRight) + 1;
}

int BintreeLeafSize(PBTNode pRoot)
{
	if (NULL == pRoot)
		return 0;
	if (NULL == pRoot->_pLeft && NULL == pRoot->_pRight)
		return 1;
	return BintreeLeafSize(pRoot->_pLeft) + BintreeLeafSize(pRoot->_pRight) ;
}

int BintreeLevelNodesize(PBTNode pRoot,int k)
{
	if (NULL == pRoot || k <= 0)
		return 0;
	if (k == 1)
		return 1;
	return BintreeLevelNodesize(pRoot->_pLeft, k - 1) + BintreeLevelNodesize(pRoot->_pRight,k - 1);
}

int BintreeHigh(PBTNode pRoot)
{
	if (NULL == pRoot)
		return 0;
	int left = BintreeHigh(pRoot->_pLeft) + 1;
	int right = BintreeHigh(pRoot->_pRight) + 1;
	return left > right ? left : right;

}
void swap(PBTNode *left, PBTNode *right)
{
	PBTNode tmp = *left;
	*left = *right;
	*right = tmp;
}
void MirrorBinTree(PBTNode pRoot)// 二叉树的镜像递归 
{
	if (pRoot)
	{
		swap(&pRoot->_pLeft,&pRoot->_pRight);
		MirrorBinTree(pRoot->_pLeft);
		MirrorBinTree(pRoot->_pRight);
	}
 }

void MirrorBinTreeNor(PBTNode pRoot)// 二叉树的镜像非递归 
{
	LQueue q;
	if (NULL == pRoot)
	{
		return;
	}
	InitQueue(&q);
	PushQueue(&q, pRoot);
	while (!QueueEmpyt(&q))
	{
		PBTNode pCur = QueueFront(&q);
		PopQueue(&q);
		
		if (pCur->_pLeft)
		{
			PushQueue(&q, pCur->_pLeft);
		}
		if (pCur->_pRight)
		{
			PushQueue(&q, pCur->_pRight);
		}
		swap(&pCur->_pLeft,&pCur->_pRight);
	}
}

void test()
{
	const char* str = "ABD###CE##F";
	PBTNode pRoot = NULL;
	PBTNode pNewNode = NULL;
	CreateBinTree(&pRoot,str, strlen(str),'#');

	printf("PreOrder: ");
	PreOrder(pRoot);
	printf("\n");
	printf("InOrder: ");
	InOrder(pRoot);
	printf("\n");
	printf("PosteOrder: ");
	PostOrder(pRoot);
	printf("\n");

	pNewNode = Copy(pRoot);
	printf("PreOrder pNewNode: ");
	PreOrder(pRoot);
	printf("\n");

	printf("PreOrderNor: ");
	PreOrderNor(pRoot);
	printf("\n");

	printf("PreOrderNor2: ");
	PreOrderNor2(pRoot);
	printf("\n");

	printf("LevelOrder: ");
	LevelOrder(pRoot);
	printf("\n");

	printf("结点个数为:%d\n", BintreeNodeSize(pRoot));
	printf("叶子结点个数为: %d\n",BintreeLeafSize(pRoot));
	printf("第3层结点个数为:  %d\n", BintreeLevelNodesize(pRoot,3));
	printf("二叉树高度: %d\n", BintreeHigh(pRoot));

	printf("Mirror tree:");
	MirrorBinTree(pRoot);
	PreOrder(pRoot);
	printf("\n");

	printf("MirrorNor tree:");
	MirrorBinTreeNor(pRoot);
	PreOrder(pRoot);
	printf("\n");

	DestroyBinTree(&pRoot);
	DestroyBinTree(&pNewNode);
}

int main()
{
	test();
	system("pause");
	return 0;
}

stack.h

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

#define MAX_SIZE 100  

extern struct BinTreeNode;
typedef struct BinTreeNode* DataType;

typedef struct Stack
{
	DataType _arr[MAX_SIZE];//栈的元素最大个数  
	int _top;//栈顶  
	int _bottom;//栈低  
	int len;//栈大小  
}Stack, *Pstack;

// 栈的初始化   
void StackInit(Stack* s);

// 入栈   
void StackPush(Stack* s, DataType data);

// 出栈   
void StackPop(Stack* s);

// 获取栈顶元素   
DataType StackTop(Stack* s);

// 获取栈中元素个数   
int StackSize(Stack* s);

// 检测栈是否为空   
int StackEmpty(Stack* s);

stack.c

#include"stack.h"  
void StackInit(Stack* S)
{
	S->_bottom = S->_top = 0;
	S->len = 0;
}

void StackPush(Stack* S, DataType data)
{
	if (S->len == MAX_SIZE)
	{
		printf("栈满溢出,添加失败!\n");
		return;
	}
	S->_top++;
	S->_arr[S->_top] = data;
	S->len++;
}

void StackPop(Stack* S)
{
	if (S->len == 0)
	{
		printf("栈为空!\n");
		return;
	}
	S->_top--;
	S->len--;
}

DataType StackTop(Stack* S)
{
	if (S->len == 0)
	{
		printf("栈为空!\n");
		return;
	}
	return S->_arr[S->_top];
}

int StackSize(Stack* S)
{
	int ret = 0;
	ret = printf("栈中元素个数为:%d\n", S->len);
	return ret;
}

int StackEmpty(Stack* S)
{
	if (S->len == 0)
	{
		return 1;
	}
	else
	{
		return 0;
	}
}

queue.h

#pragma once
extern struct BinTreeNode;
typedef struct BinTreeNode* pData;
#define DataType pData
typedef struct Node {
	DataType data;
	struct Node * next;
}qNode;

//基于带头结点的单链表队列
typedef struct Queue {
	qNode * front;
	qNode * tail;
}LQueue;

void InitQueue(LQueue *queue);
void PushQueue(LQueue *queue, DataType data);
void PopQueue(LQueue * queue);
DataType QueueFront(LQueue* queue);
int QueueSize(LQueue* queue);
int QueueEmpyt(LQueue* queue);
void DestoryQueue(LQueue** queue);

queue.c

#include "queue.h"
#include <assert.h>
#include <malloc.h>
#include <stdio.h>
qNode * BuyNode(DataType data)
{
	qNode * new = (qNode*)malloc(sizeof(qNode));
	if (NULL == new) {
		printf("分配失败");
		return NULL;
	}
	new->data = data;
	new->next = NULL;
	return new;
}
void InitQueue(LQueue *queue)
{
	assert(queue);
	//创建头结点
	qNode * head = BuyNode(0);
	queue->front = head;
	queue->tail = head;
}
void PushQueue(LQueue *queue, DataType data)
{
	qNode *new = BuyNode(data);
	queue->tail->next = new;
	queue->tail = new;
}
void PopQueue(LQueue * queue)
{
	qNode *pDel = queue->front->next;
	//不是空队列
	if (pDel) {
		//除头结点只有一个结点
		if (NULL == pDel->next) {
			queue->tail = queue->front;
		}
		queue->front->next = pDel->next;
	}
}
DataType QueueFront(LQueue* queue)
{
	if (queue->front->next) {
		return queue->front->next->data;
	}
	return queue->front->data;
}
int QueueSize(LQueue* queue)
{
	int count = 0;
	qNode * pcur = queue->front->next;
	while (pcur) {
		count++;
		pcur = pcur->next;
	}
	return count;
}
int QueueEmpyt(LQueue* queue)
{
	if (queue->front == queue->tail) {
		return 1;
	}
	return 0;
}
void DestoryQueue(LQueue** queue)
{
	if (*queue != NULL) {
		while ((*queue)->front) {
			PopQueue(*queue);
		}
		free(*queue);
		*queue = NULL;
	}

}

树是由一个或多个结点组成的有限集合,其中:


猜你喜欢

转载自blog.csdn.net/w_j_f_/article/details/80408846