线性表的链式存储结构

 

typedef  struct  Lnode

{   ElemType  data;     /*数据域,保存结点的值 */

         struct   Lnode  *next;      /*指针域*/

}LNode;        /*结点的类型 */

 

1 建立单链表

⑴ 头插入法建表

LNode  *create_LinkList(void)

    /*  头插入法创建单链表,链表的头结点head作为返回值  */ 

{   

         int data ;

         LNode *head, *p;

         head= (LNode  *) malloc( sizeof(LNode));

         head->next=NULL;       /*  创建链表的表头结点head  */

         while (1)

         {  

                   scanf(“%d”, &data) ;

                   if (data==32767)  break ;

                   p= (LNode  *)malloc(sizeof(LNode));

                   p–>data=data;     /*  数据域赋值  */

                   p–>next=head–>next ; 

                   head–>next=p ;

       /*  钩链,新创建的结点总是作为第一个结点  */

         }

         return (head);

}

 

(2)    尾插入法建表

LNode  *create_LinkList(void)

     /*  尾插入法创建单链表,链表的头结点head作为返回值  */ 

{  

         int data ;

         LNode *head, *p, *q;

         head=p=(LNode  *)malloc(sizeof(LNode));

         p->next=NULL;        /*  创建单链表的表头结点head  */

         while (1)

         {   

                   scanf(“%d”,& data);

                   if (data==32767)  break ;

                   q= (LNode  *)malloc(sizeof(LNode));

                   q–>data=data;     /*   数据域赋值  */

                   q–>next=p–>next; 

                   p–>next=q;

                   p=q ;

                   /*钩链,新创建的结点总是作为最后一个结点*/

         }

         return (head);  

}

 

2 单链表的查找

(1)  按序号查找  取单链表中的第i个元素

ElemType   Get_Elem(LNode *L , int  i)

{   

         int j ;  

         LNode *p;

         p=L->next;  /*  使p指向第一个结点  */

         j=1;    

         while  (p!=NULL && j<i)

         {  

                   p=p–>next; 

                   j++; 

         }        /*  移动指针p , j计数  */

         if  (j!=i)  return(-32768) ;

         else      return(p->data);

        /*   p为NULL 表示i太大;  j>i表示i为0  */

}

 

(2)  按值查找

LNode *Locate_Node(LNode *L,int key)

/*  在以L为头结点的单链表中查找值为key的第一个结点  */

{  

         LNode *p=L–>next;

         while  ( p!=NULL&& p–>data!=key)    p=p–>next;

         if  (p–>data==key)   return p;

         else 

         {   

                   printf(“所要查找的结点不存在!!\n”);

                   retutn(NULL); 

         }

}

 

3 单链表的插入

插入运算是将值为e的新结点插入到表的第i个结点的位置上,即插入到ai-1与ai之间。

void  Insert_LNode(LNode *L,int i,ElemType e)

    /*  在以L为头结点的单链表的第i个位置插入值为e的结点 */

{  

         int  j=0; 

         LNode *p,*q;

         p=L–>next ;

         while  ( p!=NULL&& j<i-1)

         { 

                   p=p–>next; 

                   j++;  

         }

         if  (j!=i-1)     printf(“i太大或i为0!!\n ”);

         else

         { 

                   q=(LNode *)malloc(sizeof(LNode));

                  q–>data=e;  

                  q–>next=p–>next;

                  p–>next=q;

         }

}

 

4 单链表的删除

⑴ 按序号删除  

    删除单链表中的第i个结点。

void  Delete_LinkList(LNode *L, int i)

  /*  删除以L为头结点的单链表中的第i个结点  */

         int  j=1; 

         LNode *p,*q;

         p=L; 

         q=L->next;

         while  ( p->next!=NULL &&  j<i)

         { 

                   p=q; 

                   q=q–>next; 

                   j++; 

         }

         if  (j!=i)     printf(“i太大或i为0!!\n ”); 

         else   

         { 

                   p–>next=q–>next;  

                   free(q);   

         }

}

 

⑵ 按值删除 

    删除单链表中值为key的第一个结点。

void  Delete_LinkList(LNode *L,int key)

/*  删除以L为头结点的单链表中值为key的第一个结点  */

{    

         LNode *p=L,  *q=L–>next;

         while  ( q!=NULL&& q–>data!=key)    

         { 

                   p=q; 

                   q=q–>next;  

         }

         if  (q–>data==key)  

         { 

                   p->next=q->next; 

                   free(q);  

         }

         else  printf(“所要删除的结点不存在!!\n”);

}

变形之一:

    删除单链表中值为key的所有结点。

void  Delete_LinkList_Node(LNode *L,int key)

{    

         LNode *p=L,  *q=L–>next;

         while  ( q!=NULL)

         { 

                   if (q–>data==key)

              { 

                            p->next=q->next; 

                            free(q); 

                            q=p->next; 

                   }

                   else

              { 

                            p=q; 

                            q=q–>next;  

                   }

         }

}

 

变形之二:

    删除单链表中所有值重复的结点,使得所有结点的值都不相同。

void  Delete_Node_value(LNode *L)

/*  删除以L为头结点的单链表中所有值相同的结点  */

{    

         LNode *p=L->next, *q, *ptr;

         while  ( p!=NULL)   /*  检查链表中所有结点  */

         {  

                   q=p,  ptr=p–>next;

                   /*  检查结点p的所有后继结点ptr  */

                   while (ptr!=NULL)

              {    

                            if (ptr–>data==p->data)

                { 

                                     q->next=ptr->next; 

                                     free(ptr); 

                   ptr=q->next; 

                            }

                    else 

                            { 

                                     q=ptr; 

                                     ptr=ptr–>next;  

                            }

              }

                   p=p->next ;

         }

}

 

5 单链表的合并

设有两个有序的单链表,它们的头指针分别是La 、 Lb,将它们合并为以Lc为头指针的有序链表。

算法说明:算法中pa ,pb分别是待考察的两个链表的当前结点,pc是合并过程中合并的链表的最后一个结点。

LNode  *Merge_LinkList(LNode *La, LNode *Lb)

      /*  合并以La, Lb为头结点的两个有序单链表   */

{   

         LNode *Lc,  *pa ,  *pb ,  *pc, *ptr ;

         Lc=La ; 

         pc=La ;   

         pa=La->next ; 

         pb=Lb->next  ;

        while (pa!=NULL        &&  pb!=NULL)

        { 

                   if  (pa->data<pb->data)

             {  

                            pc->next=pa ; 

                            pc=pa ;  

                            pa=pa->next  ;  

                   }

                   /*  将pa所指的结点合并,pa指向下一个结点  */

                   if  (pa->data>pb->data)

             {  

                            pc->next=pb ; 

                            pc=pb ;  

                            pb=pb->next  ;  

                   }

                   /*  将pa所指的结点合并,pa指向下一个结点  */

                   if  (pa->data==pb->data)

             {  

                            pc->next=pa ; 

                            pc=pa ;  

                            pa=pa->next  ;

                  ptr=pb ;

                            pb=pb->next ;

                            free(ptr) ;  

                   }

                   /*  将pa所指的结点合并,pb所指结点删除  */

         }

        if  (pa!=NULL)  pc->next=pa ;

         else   pc->next=pb ;     /*将剩余的结点链上*/

         free(Lb) ;

         return(Lc) ;

}

 

循环链表

判断是否是空链表:head->next==head ;

判断是否是表尾结点:p->next==head ;

 

双向链表

1   双向链表的结点及其类型定义

typedef struct Dulnode

{   ElemType  data ;

         struct Dulnode  *prior , *next ;

}DulNode ;

 

(1)  双向链表的插入  将值为e的结点插入双向链表中。

①  插入时仅仅指出直接前驱结点,钩链时必须注意先后次序是: “先右后左” 。部分语句组如下:

         S=(DulNode *)malloc(sizeof(DulNode));

         S->data=e;

         S->next=p->next;   p->next->prior=S;

         p->next=S;  S->prior=p;    /*  钩链次序非常重要  */

②   插入时同时指出直接前驱结点p和直接后继结点q,钩链时无须注意先后次序。部分语句组如下:

         S=(DulNode *)malloc(sizeof(DulNode));

         S->data=e;

         p->next=S;       S->next=q;

         S->prior=p;       q->prior=S;

 

(2)  双向链表的结点删除 

    设要删除的结点为p ,删除时可以不引入新的辅助指针变量,可以直接先断链,再释放结点。部分语句组如下:

         p->prior->next=p->next;

         p->next->prior=p->prior;

         free(p);

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值