带头结点的线性链表的实现

/*========带头节点的线性链表类型=========*/
typedef  char  ElemType
 
//结点类型
typedef  struct  LNode
{
     char  data;
     struct  LNode *next;
}*Link,*Position;
 
//链表类型
typedef  struct
{
     Link head,tail;
     int  len;
}LinkList;
 
 
/*======================================================*/
/*=======一些在其他函数定义中会调用的函数===============*/
/*======================================================*/
 
/*---compare---比较两个元素的大小关系*/
int  Compare( char  a, char  b)
     return  a-b;
}
 
/*---visit---*/
int  Visit(Link p)
{
     if (...)
         return  1;
     else
         return  0;
     
}
 
/*---length---求链的长度*/
int  Length(Link s)
{
     int  i=0;
     Link p=NULL;
     p=s;
     while (p->next!=NULL)
     {
         p=p->next;
         i++;
     }
     return  i;
}
 
/*---print---在屏幕上输出链表的所有元素*/
void  Print(LinkList L)
{    
     Link p=NULL;
     p=L.head;
     if (!p->next)
     {
         printf ( "\nThe LinkList is empty.\n\n" );
         return  ;
     }
     printf ( "The List:" );
     while (p)
     {
         printf ( "%c-" ,p->data);
         p=p->next;
     }
}
 
/*======================================================*/
/*==========对带头结点的单链线性表进行操作的函数的定义==*/
/*======================================================*/
 
/*---分配由p指向的结点并赋值为e---*/
Position MakeNode(ElemType e)
{      
     Link p=NULL;
     p=(Link) malloc ( sizeof ( struct  LNode));
     if (p)
     {
         p->data=e;
         p->next=NULL;
     }
     else  return ;
     return  p;
}
 
/*---释放p所指向的结点-*/
void  FreeNode(Link p)
{         
     free (p);
}
 
 
/*---构造一个由L指向的空的线性表-*/
void  InitList(LinkList *L)
{     
     L->head=MakeNode( 'L' ); //生成头结点
     L->head->next=NULL; /*不是l->head=NULL*/
     L->tail=L->head;
     L->len=0;
}
 
/*----------销毁由L指向的线性表---------*/
void  DestroyList(LinkList *L)
{  
     Link p;
     p=(*L).tail;
     while (p!=(*L).head)
     {
         p=PriorPos(*L,p);
         FreeNode(p->next);
     }
     FreeNode((*L).head);
}
 
/*将线性表L置为空表,并释放原链表的头结点*/
void  ClearList(LinkList *L)
{    
     Link p;
     p=(*L).tail;
     while (p!=(*L).head)
     {
         p=PriorPos(*L,p);
         FreeNode(p->next);
     }
     FreeNode((*L).head);
}
 
/*---将s指向的结点插入线性链表的第一个结点之前-*/
void  InsFirst(LinkList *L,Link s)
{   
     s->next=L->head->next;
     if (!L->head->next)
         L->tail=s;       /*当向一个空的线性表执行该操作时*/
     L->head->next=s;
     L->len++;
}
 
/*---删除表中第一个结点并以q返回-*/
void  DelFirst(LinkList *L,Link q)
{   
     if (!L->head->next)
     {
         printf ( "\nThe LinkList is empty,can not delete..\n" );
         return  0;
     }
     q=L->head->next;
     L->head->next=L->head->next->next;
}
 
/*---将指针s所的一串结点链接在线性表L的最后一个结点-*/
void  Append(LinkList *L,Link s)
     Link q;
     q=L->head;
     if (!L->tail)
     { /*考虑到链表为空的情况*/
         L->head->next=s;
         while (q->next)
             q=q->next; /*尾结点的处理*/
         L->tail=q;
     }
     L->tail->next=q=s;
     while (q->next)
         q=q->next; /*不能忘了对尾结点的处理*/
     L->tail=q;
     L->len+=Length(s);
}
 
/*---删除线性表l中的尾结点-*/
void  Remove(LinkList *L,Link q)
{  
     if (!L->tail)
     {
         printf ( "\nthe LinkList is empty,can not remonde..\n" );
         return  0;
     }
     q=L->tail;                     
     L->tail=PriorPos(*L,q);
     L->tail->next=NULL;
}
 
/*---将s所指向结点插入在p所指结点之前-*/
void  InsBefore(LinkList *L,Link p,Link s)
{  
     Link q;
     q=PriorPos(*L,p);
     s->next=p;
     q->next=s;
}
 
/*---将s所指向结点插入在p所指结点之后-*/
void  InsAfter(LinkList *L,Link p,Link s)
{   
     s->next=p->next;
     p->next=s;
}
 
/*---用e更新p所指向的当前结点-*/
void  SetCurElem(Link p,ElemType e)
{        
     p->data=e;
}
 
/*---返回p所指结点中元素的值-*/
ElemType GetCurElem(Link p)
{       
     return  p->data;
}
 
 
int  Listempty(LinkList L)
{         /*---若线性表为空表则返回1,否则返回0-*/
     if (L.head==L.tail)
         return  1;
     return  0;
}
 
 
int  Listlength(LinkList L)
{      /*---返回线性表中元素个数-*/
     return  L.len;
}
 
 
Position GetHead(LinkList L)
{     /*---返回线性表l中头结点的位置-*/
     return  L.head;
}
 
 
Position GetLast(LinkList L)
{      /*-----返回线性表l中最后一个结点的位置-------*/
     return  L.tail;
}
 
 
/*---返回p所指结点的直接前驱的位置-*/
Position PriorPos(LinkList L,Link p)
{   
     Link q;
     q=L.head;
     if (q->next==p)
         return  0;
     while (q->next!=p)  
         q=q->next;
     return  q;
}
 
/*-----返回p所指结点的直接后继的位置-------*/
Position NextPos(Link p)
{    
     Link q;
     q=p->next;
     return  q;
}
 
/*-----用p返回线性表l中第i个结点的位置,并返回ok-------*/
void  LocatePos(LinkList L, int  i,Link p)
{   
     p=L.head;
     if (i<=0||i>Listlength(L))  
         return  0;
     while (i)
     {
         p=p->next;
         i--;
     }
}
 
/*----返回表中第一个与e满足一定函数关系的结点次序位置----*/
int  LocatElem(LinkList L,ElemType e)
{    
     int  i=0;
     Link p;
     p=L.head->next;
     while (compare(p->data,e)&&p)
     {
         p=p->next;
         ++i;
     }
     if (!p)
     { /*考虑到查找不到指定元素的情况*/
         printf ( "\nthere's no '%c' in this LinkList." ,e);
         return  0;
     }
     return  i;
}
 
/*----用一个函数遍历表中所有结点-------*/
void  ListTraverse(LinkList L)
{        
     Link p;
     p=L.head;
     while (!visit(p)) 
         p=p->next;  

}

应用:将单链线性表La和Lb的元素按值非递减排列

Status MergeList_L(NLinkList &La, NLinkList &Lb, NLinkList &Lc,
                    int  (*compare)(ElemType, ElemType))
     // 算法2.21
     // 已知单链线性表La和Lb的元素按值非递减排列。
     // 归并La和Lb得到新的单链线性表Lc,Lc的元素也按值非递减排列。
     NLink ha, hb;
     Position pa, pb, q;
     ElemType a, b;
     if  (!InitList(Lc))
         return  ERROR;  // 存储空间分配失败
     ha = GetHead(La);      // ha和hb分别指向La和Lb的头结点
     hb = GetHead(Lb);
     pa = NextPos(La, ha);  // pa和pb分别指向La和Lb中当前结点
     pb = NextPos(Lb, hb);
     while  (pa && pb)
     {     // La和Lb均非空
         a = GetCurElem(pa);  // a和b为两表中当前比较元素
         b = GetCurElem(pb);
         if  ((*compare)(a, b)<=0)
         // a≤b
             DelFirst(ha, q);  Append(Lc, q);  pa = NextPos(La, pa); 
         }
         else
         {   // a>b
             DelFirst(hb, q);  Append(Lc, q);  pb = NextPos(Lb, pb); 
         }
     } // while
     if  (pa)
         Append(Lc, pa);        // 链接La中剩余结点
     else
         Append(Lc, pb);        // 链接Lb中剩余结点
     FreeNode(ha);  
     FreeNode(hb);              // 释放La和Lb的头结点
     return  OK;
} // MergeList_L

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值