文章目录
树的基本概念
有序树
- 有确定的根
- 树根和子根之间为有向关系
如上图,是两个不同的树
定义
结点
:数据元素+指向子树的分支结点的度
:分支的个数树的度
:树中所有结点的度的最大值叶子结点
:度为零的结点(终点结点)分支结点
:度大于零的结点(非终端结点)结点的层次
:假设根结点的层次为1,第n层的结点的子树根结点的层次为n+1从根到结点的路径
: 孩子结点,双亲结点,兄弟结点,祖先,子孙树的深度
:树中叶子结点所在的最大层次森林
:是m棵互不相交树的集合- 任何一棵非空树是一个二元组
Tree=(root,F)
其中,root被称为根结点,F被称为子树森林
树型结构和其他表示方法
括号表示法
嵌套集合表示法
凹入表示法
树的存储结构
双亲表示法
#define MAXSIZE 100
typedef char datatype;//结点值的类型
typedef struct node//结点类型
{
datatype data;
int parent;//结点双亲的下标
}node;
typedef struct tree
{
node treelist[MAXSIZE];//存放结点的数组
int length,root;//树中实际所含结点的个数及根结点的位置
}tree;
孩子表示法
- 指针方式的孩子表示法
- 数组方式的孩子表示法
- 链表方式的孩子表示法
#define MAXSIZE 50
typedef char datatype;
typrdef struct chnode{//孩子结点类型
int child;
struct chnode *next;
}chnode;
typedef chnode* chpoint;
typedef struct{//树中每个结点类型
datatype data;
chpoint firstchild;//指向第一个子女的指针
}node;
typedef struct{//数的类型
node treelist [MAXSIZE];
int length,root;
}tree;
孩子兄弟表示法
树的遍历
树的前序,后序,层次遍历算法思想
void preorder(tree p)//p为指向树根结点的指针
{
int i;
if(p!=NULL)//树不为空
{
printf("%c",p->data);
for(i=0;i<m;++i)
preorder(p->child[i]);//递归对各子树进行遍历
}
}
void postorder(tree p)//p为指向树根结点的指针
{
int i;
if(p!=NULL)//树不为空
{
for(i=0;i<m;++i)
postorder(p->child[i]);//递归对各子树进行遍历
printf("%c",p->data);
}
}
建立树的存储结构
如何根据线性输入建立树的链式存储结构?
- 按前序遍历顺序建立一棵m度树的递归算法
tree createtree()
{
int i;
char ch;
tree t;
if((ch=getchar())=='#') t=NULL;
else
{
t=(tree)malloc(sizeof(node));
t->data=ch;
for(i=0;i<m;i++)
t->child[i]=
}
}
读到A,建立三个子节点
树的前序遍历非递归算法
利用栈实现树的前序搜索
树的层次遍历算法实现(队列)
队列:前面出队,后面进队
树的括号表示与层号表示法
括号表示法
层号表示法
课后补充
算法
由前面式子可得,度为1不进行计算
1+10x2+20x3+1=82
一定一定记得最后+1
ABEFGHICDJKL//不回到根结点
EGHIFBCJKDLA
ABCDLEFJKGHI
三叉树
AB###CE###FH###I####G###D###
- 为什么AB后面三个#
B有三个空儿子 - I为什么有4个#
- 树最适合用来表示具有( 层次 )性和( 有序 )性的数据。
- 在选择存储结构时,既要考虑数据值本身的存储,还需要考虑( 数据间关系 )的存储。
- 树的宽度:各层结点数的最大值
- 指定结点最近的叶子
- A最近叶子是C,没有孩子,B的最近子叶是E,孩子层的第一个
A 树的度
:树中所有结点的度的最大值
原理同上
结点
n=n0+n1+n2+n3+n4
n=23+n4
度数
n-1=0n0+1n1+2n2+3n3+4n4
n=1+4+6+6+4n4=17+4n4
n=25 n4=2