4 树
4.1 二叉树的遍历
4.1.1 先序遍历
[算法描述]
1.若二叉树为空则退出
否则:
(1)访问处理根节点;
(2)先序遍历左子树;
(3)先序遍历右子树.
[源程序]
数组:
void PreOrder(struct TreeType *Tree, int x)
{
if(x!=0)
{
printf("%d",Tree[x].Data);
PreOrder(Tree,Tree[x].Lch);
PreOrder(Tree,Tree[x].Rch);
}
}
链表:
struct TreeType
{
intDate;
structTreeType *Lch;
structTreeType *Rch;
};
void PreOrder(struct TreeType *Tree)
{
if(Tree!=NULL)
{
printf("%d",(*Tree).Data);
PreOrder((*Tree).Lch);
PreOrder((*Tree).Rch);
}
}
4.1.2 中序遍历
[算法描述]
1.若二叉树为空则退出
否则:
(1)中序遍历左子树;
(2)访问处理根节点;
(3)中序遍历右子树.
[源程序]
数组:
void InOrder(struct TreeType *Tree, int x)
{
if(x!=0)
{
InOrder(Tree,Tree[x].Lch);
printf("%d",Tree[x].Data);
InOrder(Tree,Tree[x].Rch);
}
}
链表:
struct TreeType
{
intDate;
structTreeType *Lch;
structTreeType *Rch;
};
void InOrder(struct TreeType *Tree)
{
if(Tree!=NULL)
{
InOrder((*Tree).Lch);
printf("%d",(*Tree).Data);
InOrder((*Tree).Rch);
}
}
4.1.3 后序遍历
[算法描述]
1.若二叉树为空则退出
否则:
(1)后序遍历左子树;
(2)后序遍历右子树;
(3)访问处理根节点.
[源程序]
数组:
void PostOrder(struct TreeType *Tree, int x)
{
if(x!=0)
{
PostOrder(Tree,Tree[x].Lch);
PostOrder(Tree,Tree[x].Rch);
printf("%d",Tree[x].Data);
}
}
链表:
struct TreeType
{
intDate;
structTreeType *Lch;
structTreeType *Rch;
};
void PostOrder(struct TreeType *Tree)
{
if(Tree!=NULL)
{
PostOrder((*Tree).Lch);
PostOrder((*Tree).Rch);
printf("%d",(*Tree).Data);
}
}
4.2 根据先序和中序遍历建立二叉树
[算法描述]
1.在中序遍历中找出先序的第一个元素(即根);
2.根据根在中序遍历中划分出左右子树;
3.对左右子树执行以上操作.
[源程序]
struct TreeType
{
intLch,Rch;
} ;
int Pos(int c, int *s); //求元素c在数组s中的位置
void Copy(int *Input, int Pos, int x, int*Output); //在数组Input中从Pos位置开始顺序截取长度为x的数组,保存在Output中
int Length(int *s); //测量数组s的长度(元素个数)
void Create(struct TreeType *Tree, int *PreOrder, int*InOrder)
{
intx,LTP[256],RTP[256],LTI[256],RTI[256]; //均初始化为0
x=Pos(PreOrder[1],InOrder);
Copy(InOrder,1,x-1,LTI);
Copy(InOrder,x+1,Length(InOrder)-x,RTI);
Copy(PreOrder,2,Length(LTI),LTP);
Copy(PreOrder,Length(LTI)+2,Length(RTI),RTP);
if(Length(LTP)>0)
{
Tree[PreOrder[1]].Lch=LTP[1];
Create(Tree,LTP,LTI);
}
if(Length(RTP)>0)
{
Tree[PreOrder[1]].Rch=RTP[1];
Create(Tree,RTP,RTI);
}
}
4.3 二叉排序树
[算法描述]
如果树为空,则将元素添加至根节点;如果树不为空则与根节点比较,如果小于等于根节点的值,则向左子树添加,否则就向右子树添加.
[源程序]
struct TreeType
{
intData,Lch,Rch;
} ;
void Insert(struct TreeType *Tree, int x, int Root, int*Count)
{
if(*Count==0) Tree[++(*Count)].Data=x;
else
if (x<=Tree[Root].Data)
{
if (Tree[Root].Lch==0)
{
(*Count)++;
Tree[Root].Lch=*Count;
Tree[*Count].Data=x;
}
else Insert(Tree,x,Tree[Root].Lch,Count);
}
else
if (Tree[Root].Rch==0)
{
(*Count)++;
Tree[Root].Rch=*Count;
Tree[*Count].Data=x;
}
else Insert(Tree,x,Tree[Root].Rch,Count);
}
4.4 建立哈夫曼树
[算法描述]
1.将给定的n个结点构成n棵二叉树的集合F={T1,T2,T3,...,Tn}.其中每棵二叉树Ti中只有一个权值为wi的根结点ki,其左右子树均为空;
2.在F中选取根结点最小的两棵二叉数作为左右子树,构造一棵新的二叉树,并且置新的二叉树的根结点的权值为其左右子树根结点的权值之和;
3.在F中删除这两棵二叉树,同时将新得到的二叉数加入F中;
4.重复2,3,直到F中只含有一棵二叉树为止.
这棵二叉树就是哈夫曼树.
[源程序]
struct TreeType
{
intData,Lch,Rch;
} ;
struct RecType
{
intData,Addr;
} ;
void Huffman(struct TreeType *Tree, int *Root, struct RecType*w, int n)
{
inti,Count;
for(i=1;i<=n;i++)
{
Tree[i].Data=w[i].Data;
Tree[i].Lch=0;
Tree[i].Rch=0;
w[i].Addr=i;
}
*Root=n;
Count=n;
while(Count>1)
{
Sort(w,Count); //对w的前count个元素按data域升序排序
(*Root)++;
Tree[*Root].Data=w[1].Data+w[2].Data;
Tree[*Root].Lch=w[1].Addr;
Tree[*Root].Rch=w[2].Addr;
w[1].Data=Tree[*Root].Data;
w[1].Addr=*Root;
w[2]=w[Count--];
}
}