树的基本操作算法

  关于树的一些基本操作,本来把自己的一些研究写出来!方便大家学习!
    树可以以数组的形式存放,也可以以链表的形式存放!根据程序不同的需要选择不同的存放形式!数组的操作比较简单作有限!本文不做研究!本文只是对链式存储,做了一些简单的研究!

    树的链表形式:
   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);
 }

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值