关于树的一些基本操作,本来把自己的一些研究写出来!方便大家学习!
树可以以数组的形式存放,也可以以链表的形式存放!根据程序不同的需要选择不同的存放形式!数组的操作比较简单作有限!本文不做研究!本文只是对链式存储,做了一些简单的研究!
树的链表形式:
struct node2
{
datatype data; /* 数据 */
struct node2 *lch,*rch; /* 左孩子和右孩子 */
};
也可以是:
struct node3
{
datatype data; /* 数据 */
struct node3 *lch,*rch,*parent; /* 左孩子和右孩子和双亲结点 */
};
二叉树二叉链表的生成算法有两种:
算法一(迭代):
#define N 50
struct node2* creat()
{
int i,x,j;
struct node2 *p,*t,*S[n];
printf("The i=?,the x=? /n");
scanf("The i=%d,the x=%d",&i,&x);
printf("/n");
while((i!=0)&&(x!=0))
{
q=(struct node2 *)malloc(sizeof(struct node2));
q->data=x;
q->lch=NULL;
q->rch=NULL;
S[i]=q;
if(i==1) t=q;
else
{
j=i/2;
if(i%2)==0) S[j]->lch=q;
else S[j]->rch=q;
}
printf("The i=?,the x=? /n");
scanf("The i=%d,the x=%d",&i,&x);
printf("/n");
}
return(t);
}
算法二(递归):
void create(struct node2* t)
{
int ch;
printf("The date /n");
scanf("%d",&ch);
printf('/n");
if(ch==0) /* 值为0,表示空树 */
{
t=NULL;
}
else
{
if(!(t=(struct node2 *)malloc(sizeof(struct node2))))
{
exit(0);
}
t->data=ch;
create(t->lch);
create(t->rch);
}
}
遍历二叉数:
先根遍历:
void preorder(struct node2 *p)
{
if(p!=NULL)
{
printf("%d/t",p->data);
preorder(p->lch);
preorder(p->rch);
}
}
中根遍历:
void inorder(struct node2 *p)
{
if(p!=NULL)
{
inorder(p->lch);
printf("%d/t",p->data);
inorder(p->rch);
}
}
后根遍历:
void postorder(struct node2 *p)
{
if(p!=NULL)
{
postorder(p->lch);
postorder(p->rch);
printf("%d/t",p->data);
}
}
线索二插数:
struct nodex
{
datatype data; /* 数据 */
struct nodex *lch,*rch; /* 左右孩子 */
int ltag,rtage; /* 左右标志 */
}
/* ltage=0 表示lch指向左孩子 */
/* ltage=1 表示lch指向直接前驱 */
/* rtage=0 表示rch指向右孩子 */
/* rtage=1 表示rch指向直接后续 */
中根次序线索化算法有两种:
算法一(递归):
void inthread(struct nodex *p)
{
if(p!=NULL)
{
inthread(p->lch);
printf("%4d",p->data);
if(p->lch!=NULL)
{
p->ltag=0;
}
else
{
p->ltage=1;
p->lch=pr;
}
if(pr!=NULL)
{
if(pr->rch!=NULL)
{
pr->rtag=0;
}
else
{
pr->rtag=1;
pr->rch=p;
}
}
pr=p;
inthread(p->rch);
}
}
算法二(迭代):
void inthread(struct nodex *t)
{
p=t->lch;
while(p!=t)
{
while(p->ltag==0)
{
p=p->lch;
}
printf("%4d",p->data);
while((p->rtag==1)&&(p->rch!=t)
{
p=p->rch;
printf("%4d",p->data);
}
p=p->rch;
}
}
在中根线索树中检索某结点的前驱和后续:
找前驱:
struct nodex *impre(struct nodex *q)
{
if(q->ltag==1)
{
p=q->lch;
else
{
r=q->lch;
while(r->rtag!=1)
{
r=r->rch;
}
p=r;
}
return(p);
}
找后续:
struct nodex *insucc(struct nodex *q)
{
if(q->rtag==1)
{
p=q->rch;
}
else
{
r=q->rch;
while(r->lch!=1)
{
r=r->lch;
}
p=r;
}
return(p);
}
在中根线索树上遍历二叉树:
typedef char datatype
void inthorder(struct nodex *t)
{
struct nodex *p;
p=t;
if(p!=NULL)
{
while(p->lch!=NULL)
{
p=p->lch;
}
}
printf("%4c",p->data);
while(P->rch!=NULL)
{
p=insucc(p);
printf("%4c",p->data);
}
}
二叉排序树:
struct nodb
{
int data;
struct nodb *lch,*rch;
};
二叉排序树插入:
void insert(struct nodb *t,struct nodb *s)
{
if(t=NULL) t=s;
elseif(s->data<t->data) insert(t->lch,s);
else insert(t->rch,s);
}
二插排序树的建立:
struct nodb *creat()
{
int n,i,k;
t=NULL;
printf("How many node you want put!/n");
scanf("%d",&n);
printf("/n");
for(i=1;i<=n;i++)
{
printf("Please the data!/n");
scanf("%d",&K);
printf("/n");
s=(struct nodb*)malloc(sizeof(struct nodb));
s->data=k;
s->lch=NULL;
s->rch=NULL;
insert(t,s);
}
return(t);
}
二叉排序树上查找结点:
struct nodb *find(struct nodb *t,int x)
{
struct nodb *p=t;
while((p!=NULL)&&(p->data!=x))
{
if(x<p->data) p=p->lch;
else p=p->rch;
}
return(p);
}
哈夫曼树:
struct nodeh
{
int data;
int lch,rch;
int tag; /* tag=0 表示结点独立;tag=1表示结点已并入树中 */
};
哈夫曼树算法的实现:
#define MAX 50
int huffman(struct nodeh r[MAX])
{
int i,j,n,m1,m2,x1,x2,t;
printf("Please input number of the leaf!/n");
scanf("%d",&n);
for(j=1;j<=n;j++)
{
scanf("%d",&r[j].data);
r[j].tag=0;
r[j].lch=0;
r[j].rch=0;
}
i=0;
while(i<n-1)
{
x1=0;
m1=35000;
x2=0;
m2=35000;
for(j=1;j<=n+i;j++)
{
if((r[j].data<m1)&&(r[j].tag==0))
{
m2=m1;
x2=x1;
m1=r[j].data;
x1=j;
}
elseif((r[j].data<m2)&&(r[j].tag==0))
{
m2=r[j].data;
x2=j;
}
}
r[x1].tag=1;
r[x2].tag=1;
i++;
r[n+i].data=r[x1].data+r[x2].data;
r[n+i].tag=0;
r[n+i].lch=x1;
r[n+i].rch=x2;
}
t=2*n-1;
return(t);
}