C语言数据结构之二叉树

二叉树

二叉查找树(二叉排序树)

  • 定义
    它或者是一颗空树,或者是具有下列性质的二叉树
    1.若它的左子树不空,则左子树上所有节点的值均小于它的根结构的值;
    2.若它的右子树不空,则右子树上所有节点的值均大于它的根节点的值;
    3.它的左、右子树也分别为二叉查找树

平衡二叉树(AVL树)

  • 定义
    平衡二叉树是一种排序树,其中每一个节点的左子树和右子树的高度差至多等于1。
  • 平衡因子
    将二叉树上节点的左子树深度减去右子树深度的值称为平衡因子BF(Balance Factor).

B树

//==================================================================================================
//                                            BiTree 
//==================================================================================================
//
//! file		
//! ingroup		
//! brief		Here, you write a brief explanation of the module functionality.
//==================================================================================================

//==================================================================================================
//  I N C L U D E D   F I L E S
//==================================================================================================
#ifndef _BITREE_H_
#define _BITREE_H_

//==================================================================================================
//  G L O B A L   D E F I N I T I O N S
//==================================================================================================

//==================================================================================================
//  G L O B A L   T Y P E S
//==================================================================================================
typedef char TElemType;				//self defined element type, may be other types

//--------------------------------------------------------------------------------------------------
//  | lchild ptr|  data  |  rchild ptr |
//--------------------------------------------------------------------------------------------------

/* another define in LeetCode
struct TreeNode {
	int val;
	struct TreeNode *left;
	struct TreeNode *right;
};
*/

//The following define always used in C
typedef struct BiTNode{

	TElemType  data;					//element data
	struct BiTNode *lchild;			//left child 
	struct BiTNode *rchild;			//right child

}BiTNode, *BiTree;
//==================================================================================================
//  G L O B A L   C O N S T A N T S
//==================================================================================================

//==================================================================================================
//  G L O B A L   V A R I A B L E S   S H A R E D   I N   M O D U L E
//==================================================================================================


//==================================================================================================
//  G L O B A L   F U N C T I O N   I M P L E M E N T A T I O N
//==================================================================================================
//--------------------------------------------------------------------------------------------------
//Create BiTree
//!brief 传入的二叉树的节点参数为二叉树指针的地址,这种参数传入,便于更改二叉树结构体的指针(即地址)
//!
//!param	input   BiTree *T 指向根节点的指针的指针
//!return 
//--------------------------------------------------------------------------------------------------
int CreateBiTree(BiTree *T);


//--------------------------------------------------------------------------------------------------
//CreateBiTree_ByPreorder
//!brief 根据前序的字符串,创建二叉树。例如已知“ABC##DE#G##F###”,根据前序创建二叉树
//
//!param	input char preorder[], 存放前序序列的数组
//!param    input BiTree *T,指向根节点的指针的指针
//!return 
//--------------------------------------------------------------------------------------------------
int CreateBiTree_ByPreorder(BiTree *T, char preOrder[], int size,  int *pUsed);


//--------------------------------------------------------------------------------------------------
//CreateNode
//!brief 创建一个二叉树节点,初始化lchild和rchild
//!param  none
//!return 指向二叉树节点控件的指针
//--------------------------------------------------------------------------------------------------
BiTNode *CreateNode(void);

//--------------------------------------------------------------------------------------------------
//CreateBiTree_AccrodingToPreOrderString
//!brief 根据前序的字符串,创建二叉树。例如已知“ABC##DE#G##F###”,根据前序创建二叉树。
//!		 注意该函数与上述CreateBiTree_ByPreorder入参的区别,已知的前序序列是入参。而该函数内需要借助
//!		 变量保存字符串中元素的位置。
//
//!param	none
//!return   返回指向二叉树的根节点
//--------------------------------------------------------------------------------------------------
BiTree  CreateBiTree_AccrodingToPreOrderString(void);

//--------------------------------------------------------------------------------------------------
//BiTree_PreOrderTraverse
//--------------------------------------------------------------------------------------------------
//!brief  前序遍历
//
//!param  input    二叉树
//!return   
//--------------------------------------------------------------------------------------------------
void BiTree_PreOrderTraverse(BiTree T);

//--------------------------------------------------------------------------------------------------
//BiTree_InOrderTraverse
//--------------------------------------------------------------------------------------------------
//!brief  中序遍历
//
//!param  input    二叉树
//!return   
//--------------------------------------------------------------------------------------------------
void BiTree_InOrderTraverse(BiTree T);

//--------------------------------------------------------------------------------------------------
//BiTree_PostOrderTraverse
//--------------------------------------------------------------------------------------------------
//!brief  后序遍历
//
//!param  input    二叉树
//!return   
//--------------------------------------------------------------------------------------------------
void BiTree_PostOrderTraverse(BiTree T);

//-----------------------------------------------------------------------------------------------
//测试函数
//-----------------------------------------------------------------------------------------------
void BiTreeTest(void);


#endif  //_BITREE_H

//==================================================================================================
//                                            Bi Tree
//==================================================================================================
//
//! file		
//! ingroup		
//! brief		Here, you write a brief explanation of the module functionality.
//==================================================================================================

//==================================================================================================
//  I N C L U D E D   F I L E S
//==================================================================================================
#include "BiTree.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "assert.h"

//==================================================================================================
//  L O C A L   V A R I A B L E S
//==================================================================================================
static unsigned int s_preOrderPos;					//Pre order string character position
static char s_preOrderString[] = "ABC##DE#G##F###";
//==================================================================================================
//  G L O B A L   V A R I A B L E S   S H A R E D   I N   M O D U L E
//==================================================================================================

//==================================================================================================
//  L O C A L   F U N C T I O N   I M P L E M E N T A T I O N
//==================================================================================================

//==================================================================================================
//  G L O B A L   F U N C T I O N   I M P L E M E N T A T I O N
//==================================================================================================
//--------------------------------------------------------------------------------------------------
//Create BiTree
//传入的二叉树的节点参数为二叉树指针的地址,这种参数传入,便于更改二叉树结构体的指针(即地址)
//该方法属于输入方法构造二叉树. 一次性输入"ABDG##H###CE#I##F##",以前序遍历的方式输入二叉树,也就是要告诉
//计算机,什么是叶节点 ,否则将一直递归。当输入"#"时,指针指向NULL, 说明是叶节点。
//注意:在本函数中,所有地方都必须以(*T)的形式出现
//     CreateBitTree(BiTree T)传形参的方式会失败,详见https://www.cnblogs.com/sgawscd/p/9873615.html
//--------------------------------------------------------------------------------------------------
int CreateBiTree(BiTree *T)
{
	TElemType ch;
	scanf_s("%c", &ch, 1);					//这样调用scanf_s时,树的节点一次全部输入,如果要一次一个的输入,在%c前加个空格
	if (ch == '#') {
		*T = NULL;
	}
	else {
		*T = (BiTNode *)malloc(sizeof(BiTNode));
		if (*T == NULL){
			return 0;
		}
		else {
			(*T)->data = ch;				//生成节点数据
			CreateBiTree(&(*T)->lchild);	//生成左子树
			CreateBiTree(&(*T)->rchild);	//生成右子树
		}
	}

	return 1;
}

//--------------------------------------------------------------------------------------------------
//CreateBiTree_ByPreorder
//!brief 根据前序的字符串,创建二叉树。例如已知“ABC##DE#G##F###”,根据前序创建二叉树
//
//!param    input BiTree *T,指向根节点的指针的指针
//!param	input char preorder[], 存放前序序列的数组
//!param	input size,  前序序列元素个数
//!param    input *pUsed, 被使用掉的元素个数
//!return 
//--------------------------------------------------------------------------------------------------
int CreateBiTree_ByPreorder(BiTree *T, char preOrder[], int size ,int *pUsed)
{
	TElemType ch;
	ch = preOrder[0];
	if (size == 0)
	{
		*pUsed = 0;
		(*T) = NULL;
		return 0;
	}
	else if (preOrder[0] == '#')
	{
		*pUsed = 1;
		(*T) = NULL;
		return 0;
	}
	else
	{
		(*T) = (BiTNode *)malloc(sizeof(BiTNode));
		if ((*T) == NULL)
		{
			return 0;
		}
		else
		{
			(*T)->data = ch;
			//左子树
			int leftUsed;			//用来保存创建左子树用掉的元素个数
			int rightUsed;			//用来保存创建右子树用掉的元素个数
			if (size == strlen(preOrder))
			{
				printf("Create root node %c\r\n", ch);
			}
			else
			{
				printf("Create %c node's left node\r\n", ch);
			}
			CreateBiTree_ByPreorder(&(*T)->lchild, preOrder + 1, size -1 , &leftUsed);
			

			printf("Create %c node's right node \r\n", ch);
			CreateBiTree_ByPreorder(&(*T)->rchild, preOrder + 1 + leftUsed, size - 1 - leftUsed, &rightUsed);
			

			*pUsed = 1 + leftUsed + rightUsed; //根 + 左子树 + 右子树
			printf("pUsed size is = %d\r\n", *pUsed);
			return 1;
		}
	}
	
}

//--------------------------------------------------------------------------------------------------
//CreateNode
//!brief 创建一个二叉树节点,初始化lchild和rchild
//!param  none
//!return 指向二叉树节点控件的指针
//--------------------------------------------------------------------------------------------------
BiTNode *CreateNode(void)
{
	BiTNode *pNode = NULL;
	pNode = (BiTNode *)malloc(sizeof(BiTNode));
	if (pNode != NULL)
	{
		pNode->lchild = NULL;
		pNode->rchild = NULL;
		return pNode;
	}
	else
	{
		return NULL;
	}
}



//--------------------------------------------------------------------------------------------------
//CreateBiTree_AccrodingToPreOrderString
//!brief 根据前序的字符串,创建二叉树。例如已知“ABC##DE#G##F###”,根据前序创建二叉树。
//!		 注意该函数与上述CreateBiTree_ByPreorder入参的区别,已知的前序序列是入参。而该函数内需要借助
//!		 变量保存字符串中元素的位置。
//
//!param	none
//!return   返回指向二叉树的根节点
//--------------------------------------------------------------------------------------------------
BiTree  CreateBiTree_AccrodingToPreOrderString(void)
{
	if (s_preOrderPos >= strlen(s_preOrderString))
	{
		return NULL;
	}
	if (*(s_preOrderString + s_preOrderPos) == '#')
	{
		s_preOrderPos++; //准备处理下一个字符
		return NULL;
	}
	{
		BiTNode *pNode = CreateNode();
		pNode->data = *(s_preOrderString + s_preOrderPos);
		s_preOrderPos++;
		pNode->lchild = CreateBiTree_AccrodingToPreOrderString();
		pNode->rchild = CreateBiTree_AccrodingToPreOrderString();
		return pNode;
	}
	
}

//--------------------------------------------------------------------------------------------------
//BiTree_PreOrderTraverse
//--------------------------------------------------------------------------------------------------
//!brief  前序遍历
//
//!param  input    二叉树
//!return   
//--------------------------------------------------------------------------------------------------
void BiTree_PreOrderTraverse(BiTree T)
{
	if (T == NULL){
		return;
	}
	printf("%c", T->data);
	BiTree_PreOrderTraverse(T->lchild);
	BiTree_PreOrderTraverse(T->rchild);
	return;
}

//--------------------------------------------------------------------------------------------------
//BiTree_InOrderTraverse
//--------------------------------------------------------------------------------------------------
//!brief  中序遍历
//
//!param  input    二叉树
//!return   
//--------------------------------------------------------------------------------------------------
void BiTree_InOrderTraverse(BiTree T)
{
	if (T == NULL) {
		return;
	}
	BiTree_InOrderTraverse(T->lchild);
	printf("%c", T->data);
	BiTree_InOrderTraverse(T->rchild);
	return;
}

//--------------------------------------------------------------------------------------------------
//BiTree_PostOrderTraverse
//--------------------------------------------------------------------------------------------------
//!brief  后序遍历
//
//!param  input    二叉树
//!return   
//--------------------------------------------------------------------------------------------------
void BiTree_PostOrderTraverse(BiTree T)
{
	if (T==NULL)
	{
		return;
	}
	BiTree_PostOrderTraverse(T->lchild);
	BiTree_PostOrderTraverse(T->rchild);
	printf("%c", T->data);
	
	return;
}

void BiTreeTest(void)
{

	BiTree T;
	char preOrder[] = "ABC##DE#G##F###";
	int size = strlen(preOrder);
	int used;
	
#if 1
	CreateBiTree_ByPreorder(&T, preOrder, size,&used);
	assert(used == size);
	BiTree_PreOrderTraverse(T);
	printf("\r\n");
	BiTree_InOrderTraverse(T);
	printf("\r\n");
	BiTree_PostOrderTraverse(T);
	printf("\r\n");
#else 
	T = CreateBiTree_AccrodingToPreOrderString();
	BiTree_PreOrderTraverse(T);
	used = 1;
#endif	
	return;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值