1.树的性质:
性质1 树中的结点数等于所有结点的度数之和加1。
性质2 度为m的树中第i层上至多有mi-1个结点(i≥1)。
性质3 高度为h的m次树至多有 个结点。
性质4 具有n个结点的m次树的最小高度为【logm(n(m-1)+1)】。
2.树的基本运算
查找、插入删除、遍历
树的遍历:前根遍历、后跟遍历、层次遍历
3.树的存储结构
双亲存储结构、孩子链存储结构、孩子兄弟链存储结构
4.二叉树的定义:
二叉树是有限的节点的集合(递归的定义)
- 这个集合或者是空。
- 或者由一个根结点和两棵互不相交的称为左子树和右子树的二叉树组成。
5.两种特殊的二叉树:
满二叉树,完全二叉树
6.二叉树的性质:
性质1 非空二叉树上叶结点数等于双分支结点数加1。即:n0=n2+1。
性质2 非空二叉树上第i层上至多有2i-1个结点(i≥1)。
性质3 高度为h的二叉树至多有2h-1个结点(h≥1)。
性质4 完全二叉树性质(含n为结点):
1. n1=0或者n1=1。n1可由n的奇偶性确定:
2.若i≤|n/2|,则编号为i的结点为分支结点,否则为叶结点。
3.除树根结点外,若一个结点的编号为i,则它的双亲结点的编号为【i/2】。
4.若编号为i的结点有左孩子结点,则左孩子结点的编号为2i;若编号为i的结点有右孩子结点,则右孩子结点的编号为2i+1。
7.二叉树的基本运算实现
1.构造二叉树:
void CreateBTNode(BTNode * &b,char *str)
{ //由str 二叉链b
BTNode *St[MaxSize], *p;
int top=-1, k , j=0;
char ch;
b=NULL; //建立的二叉链初始时为空
ch=str[j];
while (ch!='\0') //str未扫描完时循环
{ switch(ch)
{
case '(': top++; St[top]=p; k=1; break; //可能有左孩子结点,进栈
case ')': top--; break;
case ',': k=2; break; //后面为右孩子结点
default: //遇到结点值
p=(BTNode *)malloc(sizeof(BTNode));
p->data=ch; p->lchild=p->rchild=NULL;
if (b==NULL) //p为二叉树的根结点
b=p;
else //已建立二叉树根结点
{ switch(k)
{
case 1: St[top]->lchild=p; break;
case 2: St[top]->rchild=p; break;
}
}
}
j++; ch=str[j]; //继续扫描str
}
}
2.销毁二叉树:
void DestroyBTree(BTNode *&b)
{ if (b==NULL) return ;
else
{ DestroyBTree(b->lchild);
DestroyBTree(b->rchild);
free(b); //剩下一个结点b,直接释放
}
}
3.查找节点:
BTNode *FindNode(BTNode *b,ElemType x)
{ BTNode *p;
if (b==NULL) return NULL;
else if (b->data==x) return b;
else
{ p=FindNode(b->lchild,x);
if (p!=NULL) return p;
else return FindNode(b->rchild,x);
}
}
4.找孩子节点:
BTNode *LchildNode(BTNode *p)
{
return p->lchild;
}
BTNode *RchildNode(BTNode *p)
{
return p->rchild;
}
5.求高度:
int BTHeight(BTNode *b)
{ int lchilddep,rchilddep;
if (b==NULL) return(0); //空树的高度为0
else
{ lchilddep=BTHeight(b->lchild);
//求左子树的高度为lchilddep
rchilddep=BTHeight(b->rchild);
//求右子树的高度为rchilddep
return(lchilddep>rchilddep)? (lchilddep+1):(rchilddep+1));
}
}
6.输出二叉树
void DispBTree(BTNode *b)
{ if (b!=NULL)
{ printf("%c",b->data);
if (b->lchild!=NULL || b->rchild!=NULL)
{ printf("(");
DispBTree(b->lchild); //递归处理左子树
if (b->rchild!=NULL) printf(",");
DispBTree(b->rchild); //递归处理右子树
printf(")");
}
}
}
8.先序、中序、后序遍历的递归算法
1.先序遍历:
void PreOrder(BTNode *b)
{ if (b!=NULL)
{ printf("%c ",b->data); //访问根结点
PreOrder(b->lchild);
PreOrder(b->rchild);
}
}
2.中序遍历:
void InOrder(BTNode *b)
{ if (b!=NULL)
{ InOrder(b->lchild);
printf("%c ",b->data); //访问根结点
InOrder(b->rchild);
}
}
3.后序遍历
void PostOrder(BTNode *b)
{ if (b!=NULL)
{ PostOrder(b->lchild);
PostOrder(b->rchild);
printf("%c ",b->data); //访问根结点
}
}
9.层次遍历算法:
typedef struct
{ BTNode *data[MaxSize]; //存放队中元素
int front,rear; //队头和队尾指针
} SqQueue; //环形队列类型
void LevelOrder(BTNode *b)
{ BTNode *p;
SqQueue *qu; //定义环形队列指针
InitQueue(qu); //初始化队列
enQueue(qu,b); //根结点指针进入队列
while (!QueueEmpty(qu)) //队不为空循环
{ deQueue(qu,p); //出队结点p
printf("%c ",p->data); //访问结点p
if (p->lchild!=NULL) //有左孩子时将其进队
enQueue(qu,p->lchild);
if (p->rchild!=NULL) //有右孩子时将其进队
enQueue(qu,p->rchild);
}
}
、