顺序表、链式表、栈、队列:线性——一对一的结构
树形结构(一对多)
叶子节点(终端结点):只有前驱没有后继结点
度
深度(树的度):树中各节点度的最大值
广度:从根节点到最底层节点的层数
节点度:子节点的个数称之为度
二叉树
满二叉树:在不增加层数的情况选无法在增加一个结点
K层满二叉树:第K层结点个数:2^(K-1)
K层结点总个数:2^K-1
知道总的结点数求叶子节点的个数:
1)、求出最外层的节点数num;求出倒数第二层的被占用的节点数pnum = num/2;求出倒数第二层的节点数p; 叶子节点数: num+(p - pnum)。
2)、总节点数 - 总结点数/2。
完全二叉树:想增加结点必须从上到下、从左到右依次增加;想删除结点必须从右向左、从下向上依次删除。
遍历:(前三种是深度优先;最后一种是广度与优先)
前序遍历: 根节点——左子树——右子树
中序遍历:左子树——根——右子树
后序遍历:左子树——右子树——根
层序遍历:从上到下——从左至右——逐层遍历
.h文件
#ifndef __TREE_H_
#define __TREE_H_typedef char BDATA_TYPE;typedef struct tree_node
{BDATA_TYPE data;struct tree_node *pl; //指向左子树的指针struct tree_node *pr; //指向右子树的指针}TREE_NODE;extern TREE_NODE *create_Btree(); //创建
extern void pre_order(TREE_NODE *pnode); //遍历(前序)
extern void in_order(TREE_NODE *pnode); //遍历(中序)
extern void post_order(TREE_NODE *pnode); //遍历(后序)
extern int Number_of_nodes(TREE_NODE *pnode); //获得二叉树的结点数
extern int Number_of_layers(TREE_NODE *pnode); //获取二叉树的层数
extern void destroy_tree(TREE_NODE *pnode); //销毁二叉树
extern int floor_order(TREE_NODE *pnode); //遍历(层序)#endif
创建一颗二叉树
/* 创建一颗二叉树 (前序的方式) * 根---左---右 */
TREE_NODE *create_Btree()
{TREE_NODE *pnode = NULL;BDATA_TYPE data = 0;data = tree[idx++]; //依次获取数组中的元素if ('#' == data) //如果获取到的是# 则返回NULL{return NULL;}pnode = malloc(sizeof(TREE_NODE)); //创建一个结点空间if (NULL == pnode){perror("fail to malloc");return NULL;}pnode->data = data; //将获取到的数据赋值到数据域中pnode->pl = create_Btree(); //先指向左子树递归调用pnode->pr = create_Btree(); //再指向右子树递归调用return pnode;}
遍历(深度优先、三种)
/* 遍历 (前序) */
void pre_order(TREE_NODE *pnode)
{if (NULL == pnode) //如果遍历到空 {return ;}printf("%c", pnode->data); //先打印出根pre_order(pnode->pl); //继续递归遍历左子树pre_order(pnode->pr); //在递归遍历右子树}/* 遍历 (中序) * 左---根---右 */
void in_order(TREE_NODE *pnode)
{if (NULL == pnode){return ;}in_order(pnode->pl);printf("%c", pnode->data);in_order(pnode->pr);
}/* 遍历 (后序)* 左---右---根 */
void post_order(TREE_NODE *pnode)
{if (NULL == pnode){return ;}post_order(pnode->pl);post_order(pnode->pr);printf("%c", pnode->data);}
获取二叉树的结点个数
/* 获取二叉树的结点个数 */
int Number_of_nodes(TREE_NODE *pnode)
{if (NULL == pnode){return 0;}return 1 + Number_of_nodes(pnode->pl) + Number_of_nodes(pnode->pr); //递归依次记录左右子树的结点数}
获取二叉树的层数
/* 获取二叉树的层数 */
int Number_of_layers(TREE_NODE *pnode)
{if (NULL == pnode){return 0;}int layL = Number_of_layers(pnode->pl); //递归调用记录左子树的层数int layR = Number_of_layers(pnode->pr); //递归调用记录右子树的层数return layL > layR ? layL + 1 : layR + 1; //左右层数比较 返回数量多的}
销毁二叉树
/* 销毁二叉树 */
void destroy_tree(TREE_NODE *pnode)
{if (NULL == pnode){return ;}destroy_tree(pnode->pl);destroy_tree(pnode->pr);free(pnode);
}
层序遍历——用到了顺序队列
/* 遍历 (层序)* 从上到下 从左到右 */
int floor_order(TREE_NODE *pnode)
{QUEUE_LIST *pque = NULL;QUEUE_ONDE *prot = NULL;DATA_TYPE outdata = 0;pque = create_linked(); //创建链式队列if (NULL == pque){return -1;}prot = create_node(pnode); //往队列中添加数据(结点的地址)Tail_Plug_List(pque, prot); //插入队列while(!is_empty_link(pque)) //只要队列不为空{Head_Delete(pque, &outdata); //出列(先入先出)printf("%c", outdata->data); //打印地址所指向的数据域的数据if (NULL != outdata->pl) //左子树不为空{prot = create_node(outdata->pl);Tail_Plug_List(pque, prot);}if (NULL != outdata->pr) //右子树不为空{prot = create_node(outdata->pr);Tail_Plug_List(pque, prot);}}Destroy_Queue(pque);return 0;}