二叉树

#pragma once

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


typedef char BTDataType;

树
//typedef struct TreeNode
//{
//	BTDataType _data;
//	struct TreeNode* _fristChild;
//	struct TreeNode* _nextBrother;
//}TreeNode;

//二叉树
typedef struct BTNode
{
	BTDataType _data;
	struct BTNode* _left;  //左孩子
	struct BTNode* _right;  //右孩子
}BTNode;

//创建二叉树
BTNode* CreateBTree(BTNode **ppRoot,BTDataType* arr, size_t *pIndex, BTDataType invalid, size_t len);
//创建一个节点
BTNode* BuyBTNode(BTDataType data);
//前序遍历递归
void BTreePrevOrderRV(BTNode *pRoot);
//中序遍历递归
void BTreeInOrderRV(BTNode *pRoot);
//后序遍历递归
void BTreePostOrderRV(BTNode *pRoot);
//层序遍历
void BTreeLevelOrder(BTNode *pRoot);
//拷贝二叉树
BTNode* CopyBinaryTree(BTNode *pRoot);
//求二叉树节点个数
size_t BinaryTreeSize(BTNode *pRoot);
//销毁二叉树
void BinaryTreeDestory(BTNode **pRoot);
//求叶子节点
size_t BinaryTreeLeafSize(BTNode *pRoot, size_t *count);
//二叉树的镜像(递归)
void BinaryTreeMirrorRV(BTNode *pRoot);
//二叉树的镜像(非递归)
void BinaryTreeMirror(BTNode *pRoot);
//求第k层的节点个数
size_t BinaryTreeKNode(BTNode *pRoot, int k);
//求二叉树的高度
size_t BinaryTreeHeight(BTNode *pRoot);
//判断是否是完全二叉树
int IsCompleteBinaryTree(BTNode *pRoot);
//找当前树中是否有data这个数
BTNode* FindDataBinaryTree(BTNode *pRoot, BTDataType data);
//找当前树中是否有这个节点
int FindNodeBinaryTree(BTNode *pRoot, BTNode *node);
//非递归前序遍历(方法一)
void BinaryTreePrevOrder1(BTNode *pRoot);
//非递归前序遍历(方法二)
void BinaryTreePrevOrder2(BTNode *pRoot);
//非递归的中序遍历
void BinaryTreeInOrder(BTNode *pRoot);
//后序非递归遍历
void BinaryTreePostOrder(BTNode *pRoot);

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



BTNode* BuyBTNode(BTDataType data)
{
	BTNode *newnode = (BTNode*)malloc(sizeof(BTNode));
	if (NULL == newnode)
	{
		assert(0);
		return NULL;
	}

	newnode->_data = data;
	newnode->_left = NULL;
	newnode->_right = NULL;

	return newnode;
}

//创建二叉树
BTNode* CreateBTree(BTNode **ppRoot, BTDataType* arr, size_t *pIndex, BTDataType invalid, size_t len)
{
	assert(ppRoot);
	if ((*pIndex < len) && (invalid != arr[*pIndex]))
	{
		//创建根节点
		*ppRoot = BuyBTNode(arr[*pIndex]);
		//创建左子树
		++(*pIndex);
		(*ppRoot)->_left = CreateBTree(&((*ppRoot)->_left), arr, &(*pIndex), invalid, len);
		//创建右子树
		++(*pIndex);
		(*ppRoot)->_right = CreateBTree(&((*ppRoot)->_right), arr, &(*pIndex), invalid, len);
	}

	return *ppRoot;
}

//前序遍历
void BTreePrevOrderRV(BTNode *pRoot)
{
	if (NULL == pRoot)
		return;

	printf("%c ", pRoot->_data);

	BTreePrevOrderRV(pRoot->_left);
	BTreePrevOrderRV(pRoot->_right);

}

//中序遍历
void BTreeInOrderRV(BTNode *pRoot)
{
	if (NULL == pRoot)
		return;

	BTreeInOrderRV(pRoot->_left);

	printf("%c ", pRoot->_data);

	BTreeInOrderRV(pRoot->_right);
}


//后序遍历
void BTreePostOrderRV(BTNode *pRoot)
{
	if (NULL == pRoot)
		return;

	BTreePostOrderRV(pRoot->_left);
	BTreePostOrderRV(pRoot->_right);

	printf("%c ", pRoot->_data);
}

//层序遍历
void BTreeLevelOrder(BTNode *pRoot)
{
	BTNode *cur = NULL;
	Queue q;
	QueueInit(&q);

	if (NULL == pRoot)
		return;

	//根节点入队列
	QueuePush(&q, pRoot);
	while (EmptyQueue(&q))
	{
		//先遍历根节点
		cur = QueueFront(&q);
		printf("%c ", cur->_data);
		//遍历完出队列
		QueuePop(&q);

		//左子树存在则遍历
		if (cur->_left)
			QueuePush(&q, cur->_left);

		//右子树存在则遍历
		if (cur->_right)
			QueuePush(&q, cur->_right);
	}

}


//拷贝二叉树
BTNode* CopyBinaryTree(BTNode *pRoot)
{
	BTNode *newtree = NULL;

	if (NULL == pRoot)
		return NULL;

	newtree = pRoot;
	newtree->_left = CopyBinaryTree(pRoot->_left);
	newtree->_right = CopyBinaryTree(pRoot->_right);

	return newtree;
}

size_t BinaryTreeSize(BTNode *pRoot)
{
	size_t left = 0;
	size_t right = 0;
	if (NULL == pRoot)
		return 0;

	//left = left + BinaryTreeSize(pRoot->_left);
	//right = right + BinaryTreeSize(pRoot->_right);

	//return left + right + 1;

	return BinaryTreeSize(pRoot->_left) + right + BinaryTreeSize(pRoot->_right) + 1;
}

//销毁二叉树
void BinaryTreeDestory(BTNode **pRoot) 
{
	assert(pRoot);

	if (*pRoot)  //如果树不为空
	{
		//销毁左子树
		BinaryTreeDestory(&(*pRoot)->_left);
		//销毁右子树
		BinaryTreeDestory(&(*pRoot)->_right);
		//销毁根
		free(*pRoot);
		*pRoot = NULL;
	}

}

//求叶子节点
size_t BinaryTreeLeafSize(BTNode *pRoot, size_t *count)
{
	if (NULL == pRoot)
		return 0;

	if (NULL == pRoot->_left && NULL == pRoot->_right)
		++(*count);
	else
	{
		BinaryTreeLeafSize(pRoot->_left, &(*count));
		BinaryTreeLeafSize(pRoot->_right, &(*count));
	}

	return *count;
}

//交换函数
void Swap(BTNode **left, BTNode **right)
{
	BTNode *tmp = NULL;
	tmp = *left;
	*left = *right;
	*right = tmp;
}

//二叉树的镜像(前序递归) 
void BinaryTreeMirrorRV(BTNode *pRoot)
{
	if (NULL == pRoot)
		return;
	
	//先遍历根节点
	printf("%c ", pRoot->_data);

	//交换左右子树
	Swap(&(pRoot->_left), &(pRoot->_right));

	BinaryTreeMirrorRV(pRoot->_left);
	BinaryTreeMirrorRV(pRoot->_right);
}

//二叉树的镜像(层序非递归) 在层序遍历的时候交换左右节点
void BinaryTreeMirror(BTNode *pRoot)
{
	if (NULL == pRoot)
		return;

	Queue q;
	QueueInit(&q);

	//根入队
	QueuePush(&q, pRoot);

	while (EmptyQueue(&q))
	{
		//取队头元素
		BTNode *cur = QueueFront(&q);

		//遍历根节点
		printf("%c ", cur->_data);
		QueuePop(&q);

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

		//交换左右节点(无论是否存在)
		Swap(&(cur->_left), &(cur->_right));
	}
}

//求第k层的节点个数
size_t BinaryTreeKNode(BTNode *pRoot, int k)
{
	if (NULL == pRoot || k <= 0)
		return 0;

	if (1 == k)
		return 1;

	else
		return BinaryTreeKNode(pRoot->_left, k - 1) 
			 + BinaryTreeKNode(pRoot->_right, k - 1);
}

//求二叉树的高度
size_t BinaryTreeHeight(BTNode *pRoot)
{
	if (NULL == pRoot)
		return 0;

	//优化,可以少递归将近一半
	if (NULL == pRoot->_left && NULL == pRoot->_right)
		return 1;

	return BinaryTreeHeight(pRoot->_left) > BinaryTreeHeight(pRoot->_right) ?
		   BinaryTreeHeight(pRoot->_left) + 1 : BinaryTreeHeight(pRoot->_right) + 1;
}

//判断是否是完全二叉树
int IsCompleteBinaryTree(BTNode *pRoot)
{
	if (NULL == pRoot)
		return 0;

	Queue q;
	QueueInit(&q);
	BTNode *cur = NULL;

	int flag = 0;

	//根节点入队
	QueuePush(&q, pRoot);
	while (EmptyQueue(&q))
	{
		//取队头并出队
		cur = QueueFront(&q);
		QueuePop(&q);

		//临界点后面的节点一定没有孩子
		if (flag)
		{
			if (cur->_left || cur->_right)
				return 0;
		}
		else
		{
			if (cur->_left && cur->_right)
			{
				QueuePush(&q, cur->_left);
				QueuePush(&q, cur->_right);
			}
			else if (cur->_right)
				return 0;   //不是完全二叉树
			else if (cur->_left)
			{
				flag = 1;
				QueuePush(&q, cur->_left);
			}
			else
				flag = 1;
		}
	}

	return 1;
}

//找当前树中是否有data
BTNode* FindDataBinaryTree(BTNode *pRoot, BTDataType data)
{
	if (NULL == pRoot)
		return NULL;
	
	if (data == pRoot->_data)
		return pRoot;

	FindDataBinaryTree(pRoot->_left, data);
	FindDataBinaryTree(pRoot->_right, data);	
}

//找当前树中是否有这个节点
int FindNodeBinaryTree(BTNode *pRoot, BTNode *node)
{
	if (NULL == pRoot)
		return 0;

	if (node == pRoot)
		return 1;

	FindNodeBinaryTree(pRoot->_left, node);
	FindNodeBinaryTree(pRoot->_right, node);
}


//非递归的前序遍历(方法一)  和层次遍历的步骤一样
void BinaryTreePrevOrder1(BTNode *pRoot)
{
	if (NULL == pRoot)
		return;

	Stack s;
	StackInit(&s);
	//根入栈
	StackPush(&s, pRoot);

	while (EmptyStack(&s))
	{
		//遍历
		BTNode *cur = StackTop(&s);
		printf("%c ", cur->_data);
		//出栈
		StackPop(&s);

		//先让右孩子入栈
		if (cur->_right)
			StackPush(&s, cur->_right);
		//再让左孩子入栈
		if (cur->_left)
			StackPush(&s, cur->_left);
	}

}

//非递归前序遍历(方法二)
void BinaryTreePrevOrder2(BTNode *pRoot)
{
	if (NULL == pRoot)
		return;

	Stack s;
	StackInit(&s);
	//把根节点入栈
	StackPush(&s, pRoot);
	
	while (EmptyStack(&s))
	{
		//取栈顶元素并出栈
		BTNode *cur = StackTop(&s);
		StackPop(&s);

		while (cur)
		{
			//遍历栈顶节点
			printf("%c ", cur->_data);

			//如果该节点有右孩子就入栈
			if (cur->_right)
				StackPush(&s, cur->_right);
			//然后往左边走
			cur = cur->_left;
		}
	}
}

//非递归的中序遍历
void BinaryTreeInOrder(BTNode *pRoot)
{
	if (NULL == pRoot)
		return;

	Stack s;
	StackInit(&s);

	BTNode *cur = pRoot;
	//先找这棵树的最左边的节点,并保存这条路径上的所有节点
	while (cur || EmptyStack(&s))
	{
		while (cur)
		{
			StackPush(&s, cur);
			cur = cur->_left;
		}
		//去栈顶节点并遍历
		cur = StackTop(&s);
		printf("%c ", cur->_data);
		//出栈
		StackPop(&s);
		//再遍历右子树
		cur = cur->_right;
	}
}

//后序非递归遍历
void BinaryTreePostOrder(BTNode *pRoot)
{
	if (NULL == pRoot)
		return;

	Stack s;
	StackInit(&s);
	BTNode *cur = pRoot;
	BTNode *top = NULL;
	//用来标记前一个被遍历的节点
	BTNode *sign = NULL;  

	
	//找最左节点并保存路径中的所有节点
	while (cur || EmptyStack(&s))
	{
		while (cur)
		{
			StackPush(&s, cur);
			cur = cur->_left;
		}

		//取栈顶元素
		top = StackTop(&s);

		//如果该节点右子树为空或者右子树已经遍历过了则遍历这个节点,遍历完出栈
		if (NULL == top->_right || top->_right == sign)
		{
			printf("%c ", top->_data);
			//该节点已遍历则标记
			sign = top;
			StackPop(&s);

		}
		else
			cur = top->_right;
	}
}
#include"BinaryTree.h"
#include"Queue.h"
#include"Stack.h"



test1()
{
	BTNode *root;
	//BTNode *newTree;
	//BTDataType arr[] = "ABD##G##CE##F";
	BTDataType arr[] = "ABD###CE##F";

	size_t pIndex = 0;
	size_t len = strlen(arr);
	CreateBTree(&root, arr, &pIndex, '#', len);

	printf("递归前序遍历为: ");
	BTreePrevOrderRV(root);
	printf("\n");

	printf("非递归前序遍历为: ");
	BinaryTreePrevOrder1(root);
	printf("\n");

	printf("非递归前序遍历为: ");
	BinaryTreePrevOrder2(root);
	printf("\n");

	printf("递归中序遍历为: ");
	BTreeInOrderRV(root);
	printf("\n");

	printf("非递归中序遍历为: ");
	BinaryTreeInOrder(root);
	printf("\n");

	printf("递归后序遍历为: ");
	BTreePostOrderRV(root);
	printf("\n");

	printf("非递归后序遍历为: ");
	BinaryTreePostOrder(root);
	printf("\n");

	//newTree = CopyBinrayTree(root);
	//printf("前序遍历为: ");
	//BTreePrevOrderRV(newTree);
	//printf("\n");

	//printf("层序遍历为: ");
	//BTreeLevelOrder(root);
	//printf("\n");

	//printf("该树的节点个数为:%u\n", BinaryTreeSize(root));

	//size_t count = 0;
	//printf("该树的叶子个数为:%u\n", BinaryTreeLeafSize(root, &count));


	二叉树的镜像
	//printf("该二叉树的镜像二叉树为(前序递归):");
	//BinaryTreeMirrorRV(root);
	//printf("\n");

	//printf("该二叉树的镜像二叉树为(层序非递归):");
	//BinaryTreeMirror(root);
	//printf("\n");

	//printf("第K层的节点个数为:%u\n", BinaryTreeKNode(root, 3))

	//printf("该二叉树的高度为:%u\n", BinaryTreeHeight(root));

	//BinaryTreeDestory(&root);
	//printf("该树的节点个数为:%u\n", BinaryTreeSize(root));

	//printf("该树中是否有data: %p0x\n", FindDataBinaryTree(root, 'C'));

	//BTNode *node = FindDataBinaryTree(root, 'a');
	//printf("该树中是否有node: %d\n", FindNodeBinaryTree(root, node));

	//printf("判断该树是否是完全二叉树:%d\n", IsCompleteBinaryTree(root));

}


int main()
{
	test1();

	system("pause");
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值