数据结构--二叉树基本操作(二叉树面试题)

二叉树的基本概念就不多说了 代码如下

BinaryTree.c

#pragma once
#include 
#include 
#include 
#include 

typedef char BTDataType;

typedef struct BinaryTreeNode
{
	BTDataType _data;
	struct BinaryTreeNode* _left;
	struct BinaryTreeNode* _right;
}BTNode;

// a是一个前序遍历的数组
//二叉树的创建
BTNode* BinaryTreeCreate(BTDataType* a, int n, int* pi);
//二叉式销毁
void BinaryTreeDestory(BTNode* root);
//二叉树节点个数
int BinaryTreeSize(BTNode* root);
//二叉树叶子节点个数
int BinaryTreeLeafSize(BTNode* root);
//二叉树第k个节点个数
int BinaryTreeLevelKSize(BTNode* root, int k);
//查找节点
BTNode* BinaryTreeFind(BTNode* root, BTDataType x);
//完全二叉树的判断
int BinaryTreeComplete(BTNode* root);
//二叉树高度
int BinaryTreeHeight(BTNode* root);
// 遍历  递归&非递归
//先序
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 TestBinaryTree();

BinaryTree .c

#include "BinaryTree.h"
#include "Queue.h"
#include "Stack.h"
//申请节点
BTNode* BuyBTNode(BTDataType x)
{
	BTNode* node = (BTNode*)malloc(sizeof(BTNode));
	node->_left = NULL;
	node->_right = NULL;
	node->_data = x;
	return node;
}
//二叉树的创建
BTNode* BinaryTreeCreate(BTDataType* a, int n, int* pi)
{
	if (a[*pi] != '#')
	{
		BTNode* root = BuyBTNode(a[*pi]);

		++(*pi);
		root->_left = BinaryTreeCreate(a, n, pi);

		++(*pi);
		root->_right = BinaryTreeCreate(a, n, pi);

		return root;
	}
	else
	{
		return NULL;
	}
}
//数的销毁
//采用递归,先销毁根左子树节点,在销毁根右子树节点,最后销毁根节点
void BinaryTreeDestory(BTNode* root)
{
	if (root == NULL)
		return;
	BinaryTreeDestory(root->_left);
	BinaryTreeDestory(root->_right);
	free(root);
	root = 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;
	//利用叶子节点的概念,只有当节点的左右都为空时才为叶子节点,返回1
	if (root->_left == NULL
		&& root->_right == NULL)
		return 1;
	return BinaryTreeLeafSize(root->_left)
		+ BinaryTreeLeafSize(root->_right);
}
//数的第k层节点数
int BinaryTreeLevelKSize(BTNode* root, int k)
{
	//排除特殊情况
	if (root == NULL)
		return 0;
	//递归终止条件,有当k为1时才能返回1
	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);
	//找到最后时,直接返回即可
	return ret;
}
//判断完全二叉树
//我们可以采用层次遍历的思想,当它的left或right为空时,将'#',入队
//如果为完全二叉树则当队头元素为'#',那么不断出队判断对头元素为'#'即可,如果出现
//不是'#'的元素则为非完全二叉树
int BinaryTreeComplete(BTNode* root)
{
	Queue q;
	BTNode * cur = NULL;
	int flag = 0;
	if (root == NULL)
		return -1;
	QueueInit(&q);
	QueuePush(&q, root);
	while (QueueEmpty(&q))
	{
		if (QueueFront(&q)->_left)
			QueuePush(&q, QueueFront(&q)->_left);
		else 
		{
			cur = BuyBTNode('#');
			QueuePush(&q, cur);
		}
		if (QueueFront(&q)->_right)
			QueuePush(&q, QueueFront(&q)->_right);
		else
		{
			cur = BuyBTNode('#');
			QueuePush(&q, cur);
		}
		if (QueueFront(&q)->_data != '#')
			QueuePop(&q);
		if (QueueFront(&q)->_data == '#')
		{
			QueuePop(&q);
			while (QueueEmpty(&q)&&QueueFront(&q)->_data == '#')
			{
				QueuePop(&q);
			}
			if (QueueEmpty(&q))
				return -1;
			else
				return 1;
		}
	}
	QueueDestory(&q);
	return 1;
}
//数的高度
//我们可以将题目分解为求节点左边的高度和求节点右边的高度,最后只需要将
//求出的结果进行比较,返回最大值就好
int BinaryTreeHeight(BTNode* root)
{
	int Lh = 0, Rh = 0;
	if (root == NULL)
		return 0;
	if (BinaryTreeSize(root) == 1)
		return 1;
	Lh = 1 + BinaryTreeHeight(root->_left);
	Rh = 1 + BinaryTreeHeight(root->_right);
	return Lh > Rh ? Lh : Rh;
}
// 遍历  递归&非递归
//先序遍历
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)
{	
	Queue q;
	if (root == NULL)
		return;
	QueueInit(&q);
	QueuePush(&q, root);
	while (QueueEmpty(&q))
	{
		printf("%c ", QueueFront(&q)->_data);
		if (QueueFront(&q)->_left)
			QueuePush(&q, QueueFront(&q)->_left);
		if (QueueFront(&q)->_right)
			QueuePush(&q, QueueFront(&q)->_right);
		QueuePop(&q);
	}
	QueueDestory(&q);
}
void TestBinaryTree()
{
//	char array[] = { 'A', 'B', '#', '#', 'C', '#', '#'};
	char array[] = { 'A', 'B', 'D', '#', '#', '#', 'C', 'E', '#', '#', 'F', '#', '#' };
//	char array[] = { 'A', 'B', 'D','p','#', '#', '#', '#', 'C', 'E', '#', '#', 'F', '#', '#' };
	size_t i = 0;
	int j = 0;
	BTNode* tree = BinaryTreeCreate(array, sizeof(array) / sizeof(BTDataType), &i);
	printf("先序遍历顺序为: ");
	BinaryTreePrevOrder(tree);
	printf("\n中序遍历顺序为: ");
	BinaryTreeInOrder(tree);
	printf("\n后序遍历顺序为: ");
	BinaryTreePostOrder(tree);
	printf("\n层序遍历顺序为: ");
	BinaryTreeLevelOrder(tree);
	printf("\n");
	printf("树的节点个数为: %d\n",BinaryTreeSize(tree));
	printf("树的高度为: %d\n", BinaryTreeHeight(tree));
	if (BinaryTreeFind(tree, 'd') != NULL)
		printf("%c \n", BinaryTreeFind(tree, 'd')->_data);
	else
		printf("没有找到!\n");
	j = BinaryTreeComplete(tree);
	if (j > 0)
		printf("完全二叉树\n");
	else
		printf("非完全二叉树\n");
	BinaryTreeDestory(tree);
}

Test.c

#include "BinaryTree.h"
int main()
{
	TestBinaryTree();
	system("pause");
	return 0;
}

 

你可能感兴趣的:(数据结构)