二叉树C语言构建及功能实现

        关于二叉树,出现的印象一般就是一个“丫”字,这看似没有毛病,但其实也真没有什么毛病,逻辑上的二叉树差不多就是这个样子。可是当我们已经在逻辑上构建好了二叉树之后,真的不想去动手实现实现二叉树嘛?

        下面,献上我的二叉树,仅供参考使用。

一、二叉树的构建

        头文件.h

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<string.h>
#include<math.h>


typedef int HPDateType;
typedef struct Bintry
{
	HPDateType date;
	struct Bintry* left;
	struct Bintry* right;
}BTNode;


// 通过前序遍历的数组"ABD##E#H##CF##G##"构建二叉树
//n,pi都保存着字符串的长度
BTNode* BinaryTreeCreate(char* a, int n, int* pi);

//创建一个结点
BTNode* BuyNode(HPDateType data);

// 二叉树销毁
void BinaryTreeDestory(BTNode** root);
//前序遍历
void PrevOrder(BTNode* root);

//中序遍历
void InOrder(BTNode* root);

//后序遍历
void PostOrder(BTNode* root);

// 层序遍历
void BinaryTreeLevelOrder(BTNode* root);

     函数库文件.c

#define _CRT_SECURE_NO_WARNINGS
#include"Order.h"


// 通过前序遍历的数组,如"ABD##E#H##CF##G##"构建二叉树
BTNode* BinaryTreeCreate(char* a, int n, int* pi)
{
	assert(a);
	if (a[n-*pi] == '#')
	{
		return NULL;
	}
	else
	{
		BTNode* root = (BTNode*)malloc(sizeof(BTNode));
		root->date = a[n-*pi];
		(*pi)--;
		root->left = BinaryTreeCreate(a, n, pi);
		(*pi)--;
		root->right= BinaryTreeCreate(a, n, pi);
		return root;
	}
}

//创建一个结点
BTNode* BuyNode(HPDateType data)
{
	BTNode* root = (BTNode*)malloc(sizeof(BTNode));
	if (root == NULL)
	{
		perror("malloc fail");
		exit(-1);
	}
	root->date = data;
	root->left = NULL;
	root->right = NULL;
	return root;
}

// 二叉树销毁
//后序遍历销毁
void BinaryTreeDestory(BTNode** root)
{
	if((*root)->left != NULL)
	{
		BinaryTreeDestory(&((*root)->left));
		
	}
	if ((*root)->right != NULL)
	{
		BinaryTreeDestory(&((*root)->right));
	}
	if ((*root)->left == NULL && (*root)->right == NULL)
	{
		free(*root);
		*root = NULL;
		return;
	}
}

//前序遍历
void PrevOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("NULL ");
		return;
	}
	printf("%c ", root->date);//打印根结点
	PrevOrder(root->left);
	PrevOrder(root->right);
}

//中序遍历
void InOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("NULL ");
		return;
	}
	InOrder(root->left);
	printf("%d ", root->date);//打印根结点
	InOrder(root->right);
}

//后序遍历
void PostOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("NULL ");
		return;
	}
	PostOrder(root->left);
	PostOrder(root->right);
	printf("%d ", root->date);//打印根结点
}

// 层序遍历
//层序遍历时若拥有栈,队列等数据结构,建议使用于sr1,sr2
void BinaryTreeLevelOrder(BTNode* root)
{
	int h = TreeHight(root);
	BTNode** sr1 = (BTNode**)malloc(sizeof(BTNode*) *(pow(2,h-1)) );
	BTNode** sr2 = (BTNode**)malloc(sizeof(BTNode*) *(pow(2,h-1)) );
	sr1[0] = root;
	for (int j = 0; j < h; j++)
	{
		for (int i = 0; i < pow(2,j); i++)
		{
			if ((sr1[i]) == NULL)
			{
				printf("NULL ");
			}
			else
			{
				printf("%d ", sr1[i]->date);
			}
			if (j < h - 1)
			{
				sr2[i * 2] = (sr1[i]) != NULL ? sr1[i]->left : NULL;
				sr2[i * 2 + 1] = (sr1[i]) != NULL ? sr1[i]->right : NULL;
			}
		}
		BTNode** temp = sr1;
		sr1 = sr2;
		sr2 = temp;
		
	}
	printf("\n");
	free(sr1);
	free(sr2);
}

以上是二叉树的基本构建,原理大部分是递归,除了层序遍历。

二、二叉树的功能函数

        这里就是二叉树这个数据结构的一些基本功能函数,毕竟不能光有数据,不能使用吧

        注意,此部分只是为了方便讲解,如果要使用,需要与上部分代码进行合并。

        头文件.h


typedef int HPDateType;
typedef struct Bintry
{
	HPDateType date;
	struct Bintry* left;
	struct Bintry* right;
}BTNode;


//计算二叉树结点的数量
int TreeSize(BTNode* root);



//计算叶子结点个数
int TreeLeafSize(BTNode* root);

//计算二叉树的高度
int TreeHight(BTNode* root);

//计算第k层的结点个数
int TreeKSize(BTNode* root, int k);

// 判断二叉树是否是完全二叉树
bool BinaryTreeComplete(BTNode* root);

// 二叉树查找值为x的节点
BTNode* BinaryTreeFind(BTNode* root, HPDateType x);

          函数库文件.c


//计算二叉树结点的数量
int TreeSize(BTNode* root)
{
	return root!=NULL?TreeSize(root->left) + TreeSize(root->right)+1:0;
}

//计算叶子结点个数
int TreeLeafSize(BTNode* root)
{
	if(root==NULL)
	{
		return 0;
	}
	if (root->left == NULL && root->right == NULL)
	{
		return 1;
	}

	return TreeLeafSize(root->left) + TreeLeafSize(root->right);
}

//计算二叉树的高度
int TreeHight(BTNode* root)
{
	if (root == NULL)
	{
		return 0;
	}

	int TreeHightLeft = TreeHight(root->left);
	int TreeHightRight = TreeHight(root->right);
	return TreeHightLeft > TreeHightRight ? TreeHightLeft+1: TreeHightRight +1;
}

//计算第k层的结点个数
int TreeKSize(BTNode* root, int k)
{
	if (root == NULL)
	{
		return 0;
	}
	if (k == 1)
	{
		return 1;
	}
	return TreeKSize(root->left, k - 1) + TreeKSize(root->right, k - 1);
}

// 判断二叉树是否是完全二叉树
bool BinaryTreeComplete(BTNode* root)
{
    int h = TreeHight(root);
	BTNode** sr1 = (BTNode**)malloc(sizeof(BTNode*) *(pow(2,h-1)) );
	BTNode** sr2 = (BTNode**)malloc(sizeof(BTNode*) *(pow(2,h-1)) );
	sr1[0] = root;
	for (int j = 0; j < h; j++)
	{
		int _or = 0;
		for (int i = 0; i < pow(2,j); i++)
		{
			if ((sr1[i]) == NULL)
			{
				_or=1;
			}
			if(_or && (sr1[i]!=NULL))
			{
				return false;
				break;
			}
			if (j < h - 1)
			{
				sr2[i * 2] = (sr1[i]) != NULL ? sr1[i]->left : NULL;
				sr2[i * 2 + 1] = (sr1[i]) != NULL ? sr1[i]->right : NULL;
			}
		}
		BTNode** temp = sr1;
		sr1 = sr2;
		sr2 = temp;
		
	}
	free(sr1);
	free(sr2);
	return true;
}

// 二叉树查找值为x的节点
BTNode* BinaryTreeFind(BTNode* root, HPDateType x)
{
	if (root == NULL)
	{
		return NULL;
	}
	if (root->date == x)
	{
		return root;
	}
	BTNode*  a=BinaryTreeFind(root->left, x);
	if (a)
	{
		return a;
	}
	BTNode*  b=BinaryTreeFind(root->right, x);
	if (b)
	{
		return b;
	}
	return NULL;

}

       至此,便是我遇见二叉树,了解二叉树,实现二叉树,使用二叉树的过程。简单的展示一下,详解需等后续。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值