树型结构:
1、树的基本概念
一种表示层次关系的(一对多)数据结构
有且仅有一个特定的节点,该节点没有前驱,被称为根节点。
剩余的n个互不交集的子集,每个子集也都是一棵树,被称为根节点的子树。
注意:树型结构具有递归性(树中有树)
2、树的表示方法:倒悬树、嵌套法、凹凸法。
3、!!树的专业术语:
节点:组成树的基础元素,同时他也是一棵树。
节点的度:该节点子树的数量。
树的度(密度):树中节点的数量。
叶子的节点:节点的度为零的节点。
双亲和孩子:节点的子树被称为孩子节点,该节点就是他们的双亲。
兄弟:具有同一个双亲节点被称为兄弟节点。
祖先:从根节点出发到,经过的所有节点都被称为该节点的祖先。
子孙:一个节点的子树中任意一个节点都被称为他的子孙。
节点的层次:根节点层次为1,他的孩子层次为2,孩子的层次为3,以此类推。
堂兄弟:双亲在同一层的互称为堂兄弟。
树的深度:树的最大层次为树的深度。
森林:n个不相交的树的集合被称为森林。
4、树的存储
树可以顺序存储、链式存储、也可以混合存储,由于存储的信息不同,有以下表示方式:
双亲表示法:顺序存储
位置 data 双亲
0 A -1
1 B 0
2 C 0
3 D 1
4 E 2
5 G 4
6 F 4
7 H 2
优点:方便找到双亲,缺点:查找孩子不方便。
学习代码 :
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include "list_queue.h"
#define TREE_TYPE char
#define EMPTY '#'
typedef struct BinTree
{
TREE_TYPE * arr;
size_t cal;
}BinTree;
// 构建
BinTree* create_tree(TREE_TYPE* arr,size_t len)
{
BinTree* tree = malloc(sizeof(BinTree));
tree->arr = malloc(sizeof(TREE_TYPE)*len);
memcpy(tree->arr,arr,len*sizeof(TREE_TYPE));
tree->cal = len;
return tree;
}
// 销毁
void destory_tree(BinTree* tree)
{
free(tree->arr);
free(tree);
}
void _dlr_show(BinTree* tree,size_t index)
{
if(index-1 >= tree->cal || EMPTY == tree->arr[index-1]) return;
// 减1是因为由序号转为下标
printf("%c ",tree->arr[index-1]);
_dlr_show(tree,index*2);
_dlr_show(tree,index*2+1);
}
// 前序
void dlr_show(BinTree* tree)
{
_dlr_show(tree,1);
printf("\n");
}
void _ldr_show(BinTree* tree,size_t index)
{
if(index-1 >= tree->cal || EMPTY == tree->arr[index-1]) return;
// 减1是因为由序号转为下标
_ldr_show(tree,index*2);
printf("%c ",tree->arr[index-1]);
_ldr_show(tree,index*2+1);
}
// 中序
void ldr_show(BinTree* tree)
{
_ldr_show(tree,1);
printf("\n");
}
void _lrd_show(BinTree* tree,size_t index)
{
if(index-1 >= tree->cal || EMPTY == tree->arr[index-1]) return;
// 减1是因为由序号转为下标
_lrd_show(tree,index*2);
_lrd_show(tree,index*2+1);
printf("%c ",tree->arr[index-1]);
}
// 后序
void lrd_show(BinTree* tree)
{
_lrd_show(tree,1);
printf("\n");
}
// 层序
void layer_show(BinTree* tree)
{
// 创建队列
ListQueue* queue = create_list_queue();
push_list_queue(queue,1);
// 入队根
while(!empty_list_queue(queue))
{
// 获取队头
int index = head_list_queue(queue);
// 计算左子树,检查并入队
int left = index*2;
if(left-1 < tree->cal && EMPTY!=tree->arr[left-1])
push_list_queue(queue,left);
// 计算右子树,检查并入队
int right = index*2+1;
if(right-1 < tree->cal && EMPTY!=tree->arr[right-1])
push_list_queue(queue,right);
// 显示根
printf("%c ",tree->arr[index-1]);
// 出队
pop_list_queue(queue);
}
// 销毁队列
destory_list_queue(queue);
printf("\n");
}
int _high_tree(BinTree* tree,size_t index)
{
if(index-1 >= tree->cal || EMPTY == tree->arr[index-1])
return 0;
int lh = _high_tree(tree,index*2);
int rh = _high_tree(tree,index*2+1);
return lh>rh ? lh+1 : rh+1;
}
// 树的高度
int high_tree(BinTree* tree)
{
return _high_tree(tree,1);
}
int _density_tree(BinTree* tree,size_t index)
{
if(index-1 >= tree->cal || EMPTY == tree->arr[index-1])
return 0;
return 1+_density_tree(tree,index*2)+_density_tree(tree,index*2+1);
}
// 树的密度
int density_tree(BinTree* tree)
{
//return _density_tree(tree,1);
int density = 0;
for(int i=0; i<tree->cal; i++)
{
if(EMPTY != tree->arr[i])
{
density++;
}
}
return density;
}
//插入
bool insert_tree(BinTree* tree,TREE_TYPE pdata,TREE_TYPE data)
{
size_t index = 1;
while(index-1 < tree->cal)
{
if(tree->arr[index-1] == pdata)
{
if(index*2-1 >= tree->cal)
{
tree->arr = realloc(tree->arr,(tree->cal+1)*2);
for(int i=tree->cal; i<(tree->cal+1)*2; i++)
tree->arr[i] = EMPTY;
tree->cal = (tree->cal+1)*2;
}
if(EMPTY == tree->arr[index*2-1])
return tree->arr[index*2-1] = data;
if(EMPTY == tree->arr[index*2])
return tree->arr[index*2] = data;
return false;
}
index++;
}
return false;
}
//删除
bool del_tree(BinTree* tree,TREE_TYPE data)
{
size_t index = 1;
while(index-1 < tree->cal)
{
if(data == tree->arr[index-1])
{
if(index*2-1 <tree->cal && EMPTY!=tree->arr[index*2-1])
return false;
if(index*2 < tree->cal && EMPTY!=tree->arr[index*2])
return false;
tree->arr[index-1] = EMPTY;
return true;
}
index++;
}
}
//求左
int left_tree(BinTree* tree,TREE_TYPE data)
{
size_t index = 1;
while(index-1 < tree->cal)
{
if(tree->arr[index-1] == data)
{
if(index*2-1 < tree->cal && EMPTY!=tree->arr[index*2-1])
return index*2-1;
return -1;
}
index++;
}
return -1;
}
//求右
int right_tree(BinTree* tree,TREE_TYPE data)
{
size_t index = 1;
while(index-1 < tree->cal)
{
if(tree->arr[index-1] == data)
{
if(index*2 < tree->cal && EMPTY!=tree->arr[index*2])
return index*2;
return -1;
}
index++;
}
return -1;
}
//求根
int root_tree(BinTree* tree,TREE_TYPE data)
{
size_t index = 1;
while(index-1 < tree->cal)
{
if(tree->arr[index-1] == data)
{
return index-1;
}
index++;
}
return -1;
}
int main(int argc,const char* argv[])
{
char* str = "ACBD#FE#G";
BinTree* tree = create_tree(str,strlen(str));
dlr_show(tree);
ldr_show(tree);
lrd_show(tree);
layer_show(tree);
insert_tree(tree,'G','H');
printf("index:%d\n",insert_tree(tree,'G','I'));
printf("%d\n",high_tree(tree));
printf("%d\n",density_tree(tree));
layer_show(tree);
del_tree(tree,'G');
layer_show(tree);
printf("%d\n",left_tree(tree,'G'));
printf("%d\n",right_tree(tree,'G'));
printf("%d\n",root_tree(tree,'G'));
}