1、树的平衡:对于指定数量的节点,保证树的高度尽可能短。即节点加入下一层之前必须保证本层节点满。
2、AVL树是平衡二叉搜索树的一种。
3、四种周游算法:先序遍历、中序遍历、后序遍历、层级遍历
4、二叉树实现代码
(1)数据结构
#ifndef _BITTREE_H
#define _BITTREE
typedef struct _BiTreeNode{
void *data;
struct _BiTreeNode *left;
struct _BiTreeNode *right;
}BiTreeNode;
typedef struct _BiTree{
int size;
BiTreeNode *root;
int compare (const void *data1, const void *data2);
void (*destroy)(void *data);
}BiTree;
#define bittree_size(tree) tree->size
#define bittree_data(node) node->data
#define bittree_left(node) node->left
#define bittree_right(node) node->right
#define bittree_root(node) node->root
void bittree_init(BiTree *bittree, void (*destroy)(void *data));
void bittree_destroy(BiTree *bittree);
int bittree_ins_left(BiTree *bittree, BiTreeNode *node,const void *data);
int bittree_ins_right(BiTree *bittree, BiTreeNode *node,const void *data);
int bittree_rem_left(BiTree *bittree, BiTreeNode *node);
int bittree_rem_right(BiTree *bittree, BiTreeNode *node);
int bittree_merge(BiTree *merge_tree, BiTree *left_tree, BiTree *right_tree, const void *data)
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "bittree.h"
void bittree_init(BiTree *bittree, void (*destroy)(void *data))
{
bittree->size = 0;
bittree->root = NULL;
bittree->destroy = destroy;
return;
}
void bittree_destroy(BiTree *bittree)
{
bittree_rem_left(bittree, NULL);
memset(bittree, 0, sizeof(BiTree));
return;
}
//在node左子叶插入节点(左子树) ,如果node=NULL则插入第一个节点(根节点)
int bittree_ins_left(BiTree *bittree, BiTreeNode *node, const void *data)
{
BiTreeNode *new_node, **position;//position决定插入节点的位置
if(node == NULL)
{
if(bittree_size(tree)>0)
return -1;
position = &bittree->root;
}
else{
if(bittree_left(node)!=NULL)
return -1;
position = &node->left;
}
if((new_node = (BiTreeNode *)malloc(sizeof(BiTreeNode))) == NULL)
return -1;
*position = new_node;
new_node->data = (void *)data;
new_node->left = NULL;
new_node->right = NULL;
bittree->size++;
return 0;
}
int bittree_ins_right(BiTree *bittree, BiTreeNode *node, void *data)
{
BiTreeNode *new_node, **position;//position决定插入节点的位置
if(node == NULL)
{
if(bittree_size(tree)>0)
return -1;
position = &bittree->root;
}
else{
if(bittree_right(node)!=NULL)
return -1;
position = &node->right;
}
if((new_node = (BiTreeNode *)malloc(sizeof(BiTreeNode))) == NULL)
return -1;
*position = new_node;
new_node->data = (void *)data;
new_node->left = NULL;
new_node->right = NULL;
bittree->size++;
return 0;
}
//删除node节点的左子树 ,如果 node等于NULL,则从头结点开始删除整个树
//要删除的节点存在子树,则要递归删除
void bittree_rem_left(BiTree *bittree, BiTreeNode *node)
{
BiTreeNode **position;
if(bittree_size(bittree) == 0)
return;
if(node == NULL)
position = &bittree->root;
else
position = node->left;
//如果要删除的节点存在子树,则递归删除
if(*position != NULL)
{
bittree_rem_left(bittree, *position);
bittree_rem_right(bittree, *position);
bittree->destroy(position->data);
free(position);
*position=NULL;
bittree->size--;
}
return 0;
}
int bittree_rem_right(BiTree *bittree, BiTreeNode *node)
{
BiTreeNode **position;
if(bittree_size(bittree) == 0)
return;
if(node == NULL)
position = &bittree->root;
else
position = node->right;
//如果要删除的节点存在子树,则递归删除
if(*position != NULL)
{
bittree_rem_left(bittree, *position);
bittree_rem_right(bittree, *position);
bittree->destroy(position->data);
free(position);
*position=NULL;
bittree->size--;
}
return 0;
}
//合并两颗树 ,创建一个头结点,数据为data,合并的两棵树分别为左右子树
int bittree_merge(BiTree *merge_tree, BiTree *left_tree, BiTree *right_tree, const void *data)
{
bittree_init(merge_tree, left_tree->destroy);
//先插入头部父节点
bittree_ins_left(merge_tree, NULL,data);
bittree_root(merge_tree)->left = bittree_root(left_tree);
bittree_root(merge_tree)->right = bittree_root(right_tree);
merge_tree->size = left_tree->size + right_tree->size;
//关闭左右子树的属性
left_tree->size = 0;
left_tree->root = NULL;
right_tree->size = 0;
right_tree->root = NULL;
return 0;
}
5、遍历二叉树应用-表达式处理代码
遍历的目的是把二叉树中元素提取出来以链表的新式组织起来
表达式存储在二叉树中,操作符存储在父节点,其操作数由其子节点延伸出来的子树组成。后缀表达式(后续遍历)最适合计算机处理。只有最底层的叶为数字。
如图表达式为:(3+(2*3) ) - (6 /3 )
(1)前缀表达式: (- (+ 3(* 2 3)) (/ 6 3))
//链表插入顺序:父节点数据,左子树得出的数据,右子树得出的数据
int preorder(const BiTreeNode *node, List *list)
{
if(!bitree_is_eob(node))
{
if(list_ins_next(list, list_tail(list), bitree_data(node)) != 0)
return -1;
if(!bitree_is_eob(bitree_left(node)))
if(preorder(bitree_left(node), list) != 0);
return -1;
if(!bitree_is_eob(bitree_right(node)))
if(preorder(bitree_right(node), list) != 0);
return -1;
}
return 0;
}
(2)中缀表达式: (3 + (2*3)) - (6 /3)
//链表插入顺序:左子树得出的数据,父节点数据,右子树得出的数据
//子树递归得到子叶的值
int inorder(const BiTreeNode *node, List *list)
{
if(!bitree_is_eob(node))
{
if(!bitree_is_eob(bitree_left(node)))
if(inorder(bitree_left(node), list) != 0);
return -1;
if(list_ins_next(list, list_tail(list), bitree_data(node)) != 0)
return -1;
if(!bitree_is_eob(bitree_right(node)))
if(inorder(bitree_right(node), list) != 0);
return -1;
}
return 0;
}
(3)后缀表达式:((3 (2 3 *) +) (6 3 /) - )
//链表插入顺序:左子树得出的数据,右子树得出的数据,父节点数据
int postorder(const BiTreeNode *node, List *list)
{
if(!bitree_is_eob(node))
{
if(!bitree_is_eob(bitree_left(node)))
if(inorder(bitree_left(node), list) != 0);
return -1;
if(!bitree_is_eob(bitree_right(node)))
if(postorder(bitree_right(node), list) != 0);
return -1;
if(list_ins_next(list, list_tail(list), bitree_data(node)) != 0)
return -1;
}
return 0;
}