这里写自定义目录标题
二叉树
二叉查找树(二叉排序树)
- 定义
它或者是一颗空树,或者是具有下列性质的二叉树
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;
}