C语言 单向链表 自定义基本操作

c语言 单向链表 自定义基本操作

单向链表和顺序链表比较

在数据的删除和增加方面,单向链表的操作更加方便,只需要找到相应的节点,然后删除该节点或者在这个节点之后增加一个节点,不需要对其他节点进行移动。而顺序表在数据的随机读取方面更加便利,不需要从头结点一个节点一个节点的后移。

单向链表和双向链表相比较

在单向链表上,对于指针的移动,只能从前到后。所以,如果要获的指针前的一个数据,只能让指针从链表的头部开始往后移,如此做会占用大量的时间,扩大运算的时间复杂度。然而双向链表通过多定义一个指针指向前一个节点,使指针可以往前移动,从而减少不必要的操作。

单向链表和单向循环链表相比

两种数据结构类似,只是单向循环链表的最后一个节点的指针域指向的是第一个节点,不是NULL。而且通过定义两个指针,一个指向第一个节点,另一个指向最后一个节点作为标记。防止随后输入的数据把之前输入的数据覆盖。

单向链表的基本操作

我把单向链表的基本操作分为:创建头结点、链表插入节点到正指向指针cur后、链表的指针cur定长n移动、用指针cur搜寻某值为m的节点、删除节点cur、清空链表、清空表头、输出指针cur的值、改变指针变量cur的数据。而其他操作大多可以有这些基本操作相互结合完成。

结构体定义
typedef struct Elem{
 int data;//数据 
 struct Elem * next; //指针 
}Elem,*Elemp;
typedef struct {
 Elemp head;//头指针 
 Elemp cur;//正指向的指针 
 Elemp tail;//尾指针 
 int elem_length; //链表节点数 
 int elem_size;//节点大小 
}Sqlist,*Sqlistp;
创建头结点函数
status InitList(&L){
  Sqlistp L=(Sqlistp)malloc(sizeof(Sqlist));
  if(!L)  return ERROR; 
     L->head =(Elemp)malloc(sizeof(Elem));
     if(!L->head)  return ERROR;
     L->cur=L->tail=L->head;    L->head->next=NULL;   
     L->elem_size=sizeof(Elem);   L->elem_length=0;
  return OK; 
 }
链表插入节点到正指向指针cur后函数
status addList(&L,m){
  if(L==NULL){
      printf("表头不存在\n");
      return ERROR;
     } 
     Elemp p1=(Elemp)malloc(sizeof(Elem));//申请空间 
     if(!p1)   return ERROR;
     p1->next=L->cur->next;    L->cur->next=p1;  p1->data=m;//节点赋值
     L->cur=L->cur->next;//移动指针到添加节点
     L->elem_length++;//节点数加一 
     return OK;
 }
链表的指针cur定长n移动函数(起始位置为0)
status moveList(&L,n){
 if(L==NULL||L->elem_length==0){
  printf("链表不存在\n");
  return ERROR;
 }
 if(n>L->elem_length){
  printf("移动失败!\n");
  return ERROR;
 }    
 else{
     for(i=0;i<n;i++)  L->cur=L->cur->next;
  return OK; 
    }
}
用指针cur搜寻某值为m的节点函数
status searchList(&L,m){
 if(L==NULL||L->elem_length==0){
  printf("链表不存在\n");
  return ERROR;
 }
 L->cur=L->head;
 for(;L->cur->next!=NULL&&L->cur->data!=m;)    L->cur=L->cur->next; 
 if(L->cur->data!=m){
  printf("没有搜到\n");
  return ERROR;
 } 
 else{
  printf("找到\n");
  return OK;
 }
}
删除节点cur函数
stastus delList(&L){
 if(L==NULL||L->elem_length==0){
  printf("链表不存在\n");
  return ERROR;
 }
 if(L->cur==L->tail){//当删除元素为尾节点 
  L->tail=L->head;
  for(;L->tail->next!=L->cur;)   L->tail=L->tail->next;//使尾指针指向前一个节点 
 }
 p2=L->cur;
 L->cur=L->cur->next;
 free(p2);//释放节点 
 L->elem_length--;//节点数减一 
 return OK; 
}
清空链表函数
status delallList(&L){
 if(L==NULL||L->elem_length==0){
  printf("链表不存在\n");
  return ERROR;
 }
 else{
     L->cur=L->head->next;//指向第一个节点 
  for(;L->cur!=NULL;){//节点清空 
      p2=L->cur;
      L->cur=L->cur->next;
      free(p2);
     }
     L->tail=L->head;//表头赋值 
     L->head->next=NULL;
     L->elem_length=0;
     return OK;
 }
}
清空表头函数
status del(&L){
 if(L==NULL){
  printf("表头不存在\n");
  return ERROR;
 }
 if(L->head->next!=NULL){
  printf("链表非空,请先清空链表\n");
     return ERROR;
 }
 else{
  free(L->head);
  free(L);
  L=NULL;
  return OK;
 }
}
输出指针cur的值函数
status printfList(&L){
 if(L==NULL){
  printf("表头不存在\n");
  return ERROR;
 }
 else if(L->elem_length==0){
  printf("链表为空\n");
  return ERROR;
 } 
 else{
  printf(L->cur->data);
  return OK;
 }
}
改变指针变量cur的数据函数
status printfList(&L,m){
 if(L==NULL){
  printf("表头不存在\n");
  return ERROR;
 }
 else if(L->elem_length==0){
  printf("链表为空\n");
  return ERROR;
 } 
 else{
  L->cur->data = m;
  return OK;
 }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值