二叉树的相关代码

 

创建二叉树的结构体:首先创建叶子节点结构体,然后创建树的结构体。

typedef struct BNode 
{
	TDataType data;
	struct BNode* left;
	struct BNode* right;
}BNode;

typedef struct  
{
	BNode* root;
	int used;
} RESULT;

其中used是已经被使用过的节点。

  • 创建树节点

static BNode* create_BNode(TDataType data)
{
	BNode* node = (BNode*)malloc(sizeof(BNode));
	node->data = data;
	node->left = node->right = NULL;
	return node;
}
  • 创建二叉树 
// 利用含空结点的前序创建二叉树
// 返回结果是二叉树的根结点
// preorder: 带空结点的前序
// size: preorder的长度
// 1. 递归
// 2. 创建树的过程中会返回使用过的结点个数
RESULT create_tree(TDataType preorder[], int size)
{
	if (size==0)
	{
		RESULT result = { NULL, 0 };
		return result;
	}

	//根 左子树 右子树
	TDataType root_value = preorder[0];

	if (-1 == root_value)
	{
		RESULT result = { NULL, 1 };
		return result;
	}

	BNode* root = create_BNode(root_value);

	RESULT lr = create_tree(&preorder[1], size - 1);
	root->left = lr.root;
	RESULT rr = create_tree(&preorder[1 + lr.used], size - 1 - lr.used);
	root->right = rr.root;

	RESULT result = { root, 1 + lr.used + rr.used };
	return result;
}

我把所有的代码都写在一个头文件里,使用时比较方便,测试代码也在其中,如下:

binary_tree.h

#pragma once

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

typedef int TDataType;

typedef struct BNode 
{
	TDataType data;
	struct BNode* left;
	struct BNode* right;
}BNode;

static BNode* create_BNode(TDataType data)
{
	BNode* node = (BNode*)malloc(sizeof(BNode));
	node->data = data;
	node->left = node->right = NULL;
	return node;
}

typedef struct  
{
	BNode* root;
	int used;
} RESULT;


// 利用含空结点的前序创建二叉树
// 返回结果是二叉树的根结点
// preorder: 带空结点的前序
// size: preorder的长度
// 1. 递归
// 2. 创建树的过程中会返回使用过的结点个数
RESULT create_tree(TDataType preorder[], int size)
{
	if (size==0)
	{
		RESULT result = { NULL, 0 };
		return result;
	}

	//根 左子树 右子树
	TDataType root_value = preorder[0];

	if (-1 == root_value)
	{
		RESULT result = { NULL, 1 };
		return result;
	}

	BNode* root = create_BNode(root_value);

	RESULT lr = create_tree(&preorder[1], size - 1);
	root->left = lr.root;
	RESULT rr = create_tree(&preorder[1 + lr.used], size - 1 - lr.used);
	root->right = rr.root;

	RESULT result = { root, 1 + lr.used + rr.used };
	return result;
}


//二叉树的前序
void Preorder(BNode* root)
{
	//终止条件
	if (NULL == root)
	{
		return;
	}

	//根
	printf("%d ", root->data);
	//左子树,子问题用递归处理
	Preorder(root->left);
	//右子树,子问题用递归处理
	Preorder(root->right);
}


//中序
void Inorder(BNode* root)
{
	//终止条件
	if (NULL == root)
	{
		return;
	}

	//左子树,子问题用递归处理
	Inorder(root->left);
	//根
	printf("%d ", root->data);
	//右子树,子问题用递归处理
	Inorder(root->right);
}


//后序
void Postorder(BNode* root)
{
	//终止条件
	if (NULL == root)
	{
		return;
	}

	//左子树,子问题用递归处理
	Postorder(root->left);
	//右子树,子问题用递归处理
	Postorder(root->right);
	//根
	printf("%d ", root->data);
}


//求树的节点个数
int get_size(BNode* root)
{
	//终止条件
	if (NULL == root)
	{
		//空树
		return 0;
	}

	return get_size(root->left) + get_size(root->right) + 1;
}


//求叶子节点的个数
int get_leaf_size(BNode* root)
{
	//终止条件
	if (NULL == root)
	{
		//空树
		return 0;
	}

	else if (NULL == root->left && NULL == root->right)
	{
		//只有一个节点的树
		return 1;
	}

	else
		return get_leaf_size(root->left) 
		+ get_leaf_size(root->right);
}

//求 第k层 的节点个数
int get_k_level_size(BNode* root,int k)
{
	assert(k > 0);
	if (NULL == root)
	{
		return 0;
	}

	if (1 == k)
	{
		return 1;
	}

	return get_k_level_size(root->left, k - 1) 
		+ get_k_level_size(root->right, k - 1);
}


//求二叉树的高度
#define MAX(a,b) ((a) > (b) ? (a) : (b))
int get_height(BNode* root)
{
	if (NULL == root)
	{
		return 0;
	}

	int left_height = get_height(root->left);
	int right_height = get_height(root->right);

	return MAX(left_height, right_height) + 1;
}


//查找结点:
//如果找到,返回节点地址
//如果没找到,反会NULL
//查找策略:
//如果是空树,返回NULL
//如果根命中,直接返回根的地址
//先去左子树找,左子树没找到,再去右子树找

BNode* Search(BNode* root,TDataType data)
{
	if (NULL == root)
	{
		return NULL;
	}

	if (data == root->data)
	{
		return root;
	}

	BNode* l_node = Search(root->left,data);
	if (NULL != l_node)
	{
		return l_node;
	}

	BNode* r_node = Search(root->right, data);
	if (NULL != r_node)
	{
		return r_node;
	}

	else
	{
		return NULL;
	}
}



//层序----队列
void level_order(BNode* root)
{
	Queue queue;
	InitQueue(&queue);

	if (NULL == root)
	{
		return;
	}
	PushQueue(&queue, root);

	while (!QueueEmpty(&queue))
	{
		BNode* front = QueueFront(&queue);
		PopQueue(&queue);
		printf("%d ", front->data);
		if (NULL != front->left)
		{
			PushQueue(&queue, front->left);
		}
		if (NULL != front->right)
		{
			PushQueue(&queue, front->right);
		}
	}
	DestroyQueue(&queue);
}


//判断二叉树是否是完全二叉树
int is_not_complete_binary_tree(BNode* root)
{
	Queue queue;
	InitQueue(&queue);
	if (NULL == root)
	{
		return 1;
	}
	PushQueue(&queue,root);
	while (!QueueEmpty(&queue))
	{
		BNode* front = QueueFront(&queue);
		PopQueue(&queue);
		if (front == NULL)
		{
			break;
		}
		PushQueue(&queue, front->left);
		PushQueue(&queue, front->right);
	}
	while (!QueueEmpty(&queue))
	{
		BNode* node = QueueFront(&queue);
		PopQueue(&queue);
		if (node != NULL)
			return 0;
	}
	return 1;
	DestroyQueue(&queue);
	return 1;
}




void pre_order_loop(BNode* root)
{
	Stack stack;
	StackInit(&stack);

	BNode* node = root;
	BNode* top;
	while (node != NULL || !StackEmpty(&stack))
	{
		while (NULL != node)
		{
			printf("%d ", node->data);
			StackPush(&stack, node);   // 压栈,压的是结点地址
			node = node->left;
		}

		top = StackTop(&stack);
		StackPop(&stack);
		node = top->right;
	}
}

void in_order_loop(BNode* root)
{
	Stack stack;
	StackInit(&stack);

	BNode* node = root;
	BNode* top;
	while (node != NULL || !StackEmpty(&stack))
	{
		while (NULL != node)
		{
			StackPush(&stack, node);   // 压栈,压的是结点地址
			node = node->left;
		}

		top = StackTop(&stack);
		StackPop(&stack);
		printf("%d ",top->data);
		node = top->right;
	}
}


void post_order_loop(BNode* root)
{
	Stack stack;
	StackInit(&stack);

	BNode* node = root;
	BNode* top;
	BNode* last = NULL;
	while (node != NULL || !StackEmpty(&stack))
	{
		while (NULL != node)
		{
			StackPush(&stack, node);   // 压栈,压的是结点地址
			node = node->left;
		}

		top = StackTop(&stack);
		if (top->right == NULL || top->right == last)
		{
			printf("%d ", top->data);
			last = top;
			StackPop(&stack);
		}
		else
			node = top->right;
	}
}


//二叉树的镜像
void Mirror(BNode* root)
{
	if (root == NULL) 
	{ 
		return; 
	}
	BNode *t = root->left;
	root->left = root->right;
	root->right = t;
	Mirror(root->left);
	Mirror(root->right);
}

void MirrorLoop(BNode* root)
{
	Stack stack;
	StackInit(&stack);

	BNode* node = root;
	BNode* top;
	BNode* last = NULL;

	while (node != NULL || !StackEmpty(&stack))
	{
		while (node != NULL)
		{
			StackPush(&stack, node);
			node = node->left;
		}
		top = StackTop(&stack);
		if (top->right == NULL || top->right == last)
		{
			BNode* t = top->left;
			top->left = top->right;
			top->right = t;
			last = top;
			StackPop(&stack);
		}
		else
			node = top->right;
	
	}
}



//获取一个节点的双亲节点
BNode* get_parent(BNode*root, BNode* child)
{
	if (root==NULL || root == child)
	{
		return NULL;
	}
	if (root->left == child || root->right == child)
	{
		return root;
	}
	BNode* l_node =get_parent(root->left, child);
	if (l_node != NULL)
	{
		return l_node;
	}
   return get_parent(root->right, child);
	
}




//获取一个节点的左孩子节点
BNode* get_left_child(BNode* root, BNode* parent)
{
	if (root == NULL || (root->left == NULL && root == NULL))
	{
		return NULL;
	}
	if (parent->left == NULL)
	{
		return NULL;
	}
	return parent->left;
}



//获取一个节点的右孩子节点

BNode* get_right_child(BNode* root, BNode* parent)
{
	if (root == NULL || (root->left == NULL && root == NULL))
	{
		return NULL;
	}
	if (parent->right == NULL)
	{
		return NULL;
	}
	return parent->right;
}

//求二叉树中两个节点的最近公共祖先
BNode * get_nearest_ancestor(BNode *root, int n1, int n2)
{
	BNode *n1InLeft = Search(root->left, n1);
	BNode *n2InLeft = Search(root->left, n2);

	if (n1InLeft && !n2InLeft) {
		return root;
	}

	if (!n1InLeft && n2InLeft) {
		return root;
	}

	if (n1InLeft) {
		return get_nearest_ancestor(root->left, n1, n2);
	}
	else {
		return get_nearest_ancestor(root->right, n1, n2);
	}
}

//判断是否是平衡二叉树
int IsBalance(BNode* root)
{
	if (root == NULL)
	{
		return 1;
	}
	int isBalance = IsBalance(root->left);
	if (isBalance == 0) 
	{
		return 0;
	}

	isBalance = IsBalance(root->right);
	if (isBalance == 0) 
	{
		return 0;
	}

	int leftHeight = get_height(root->left);
	int rightHeight = get_height(root->right);
	int diff = leftHeight - rightHeight;
	if (diff < -1 || diff > 1) 
	{
		return 0;
	}
	else 
	{
		return 1;
	}
}

int IsBalance2(BNode *root, int *pHeight)
{
	if (root == NULL) {
		// return 高度值
		*pHeight = 0;
		return 1;
	}

	int leftHeight;
	int rightHeight;
	int leftBalance = IsBalance2(root->left, &leftHeight);
	int rightBalance = IsBalance2(root->right, &rightHeight);
	// return 高度值
	*pHeight = MAX(leftHeight, rightHeight) + 1;

	if (leftBalance == 0 || rightBalance == 0) {
		return 0;
	}

	int diff = leftHeight - rightHeight;
	if (diff < -1 || diff > 1) {
		return 0;
	}
	else {
		return 1;
	}
}


int MAX3(int a, int b, int c)
{
	if (a >= b && a >= c) {
		return a;
	}

	if (b >= a && b >= c) {
		return b;
	}

	return c;
}

int GetFarrestDistance(BNode *root)
{
	if (root == NULL) {
		return 0;
	}

	int leftDistance = GetFarrestDistance(root->left);
	int rightDistance = GetFarrestDistance(root->right);

	int leftHeight = get_height(root->left);
	int rightHeight = get_height(root->right);
	int rootDistance = leftHeight + rightHeight;

	return MAX3(leftDistance, rightDistance, rootDistance);
}




void test()
{
	RESULT result;
	TDataType preorder[] = { 1, 2, 4, -1, 6, -1, -1, -1, 3, -1, 5, -1, -1 };
	int size = sizeof(preorder) / sizeof(preorder[0]);
	result = create_tree(preorder, size);
	BNode* root = result.root;

	printf("节点个数:%d\n", get_size(root));
	printf("高度:%d\n", get_height(root));
	printf("叶子个数:%d\n", get_leaf_size(root));
	printf("第k层节点个数:%d\n", get_k_level_size(root, 3));
	printf("查找F:%d\n", Search(root, 6)->data);
	

	Preorder(root);printf("\n");
	pre_order_loop(root); printf("\n");
	Inorder(root);printf("\n");
	in_order_loop(root); printf("\n");
	Postorder(root);printf("\n");
	post_order_loop(root); printf("\n");
	level_order(root);printf("\n");

	printf("%d\n", is_not_complete_binary_tree(root));

	Mirror(root);
	MirrorLoop(root);
	//找父母节点
	BNode* child = Search(root,5);
	BNode* parent = get_parent(root, child);
	printf("%d\n", parent->data);
	//左孩子
	parent = Search(root, 1);
	BNode* leftchild = get_left_child(root, parent);
	printf("%d\n", leftchild->data);
	//右孩子
	parent = Search(root,4);
	BNode* rightchild = get_right_child(root, parent);
	printf("%d\n", rightchild->data);

	//祖先
	BNode* pre_order[] = { 1, 2, 4, 8, -1, -1, 9, -1, -1, 5, 10, -1, -1, 11, -1, -1, 3, 6, 12, -1, -1, 7 ,-1,-1};
	int sz = sizeof(pre_order) / sizeof(int);
	RESULT tree = create_tree(pre_order,sz);
	BNode* ancestor = get_nearest_ancestor(tree.root, 9, 10);
	printf("%d\n", ancestor->data);

	//平衡
	int height;
	printf("是否为平衡二叉树:%d\n", IsBalance(root));
	printf("是否为平衡二叉树:%d\n", IsBalance2(tree.root,&height));
	//
	printf("最远的距离:%d\n", GetFarrestDistance(root));
}


BNode * CreateTree2(TDataType preorder[], TDataType inorder[], int size)
{
	if (size <= 0) {
		return NULL;
	}

	TDataType rootValue = preorder[0];
	int i;
	int r = 0;
	for (i = 0; i < size; i++) {
		if (inorder[i] == rootValue) {
			r = i; break;
		}
	}
	BNode *root = create_BNode(rootValue);
	root->left = CreateTree2(preorder + 1, inorder, r);
	root->right = CreateTree2(preorder + 1 + r, inorder + r + 1, size - 1 - r);

	return root;
}

BNode * CreateTree3(TDataType postorder[], TDataType inorder[], int size)
{
	if (size <= 0) {
		return NULL;
	}

	TDataType rootValue = postorder[size-1];
	int i;
	int r = 0;
	for (i = 0; i < size; i++) {
		if (inorder[i] == rootValue) {
			r = i; break;
		}
	}
	
	BNode *root = create_BNode(rootValue);
	root->left = CreateTree2(postorder, inorder, r);
	root->right = CreateTree2(postorder+ r, inorder + r + 1, size - 1 - r);

	return root;
}


void test2()
{
	int preoder[] = { 1, 2, 3, 4, 5, 6, 7 };
	int inorder[] = { 3, 2, 4, 1, 6, 7, 5 };
	int posorder[] = { 3, 4, 2, 7, 6, 5, 1 };
	int size = sizeof(preoder) / sizeof(int);
	BNode*tree2 = CreateTree2(preoder, inorder, size);
	BNode*tree3 = CreateTree3(posorder, inorder, size);
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值