C语言数据结构:链表基本操作(增删查改,逆置,合并)

链表基本操作

本文是 链表建立 的下篇

本文主要完善一些单链表的基本操作

废话不多说,直接上代码

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

#define ElemType int
#define true 1
#define false 0

typedef struct LNode
{
 ElemType data;
 struct LNode *next;  //此处next为只能指向LNode(即链表结点)的结构体指针变量,因为结点为结构体
}LNode,*LinkList;

LNode *numserch(LinkList L,int i);

//建立
LinkList TailInsert_List()  //尾插法
{
 int x,i=1;
 LinkList L;
 L=(LinkList)malloc(sizeof(LNode)); //头结点分配空间,即带头结点
 LNode *s,*p=L,*r=L;
 printf("请输入尾插法链表%d号数据(输入9999结束):",i);
 scanf("%d",&x);
 while(x!=9999)
 {
 i++;
 s=(LNode*)malloc(sizeof(LNode));
 s->data=x;
 r->next=s;
 r=s;
 printf("请输入尾插法链表%d号数据(输入9999结束):",i);
 scanf("%d",&x);
 }
 r->next=NULL;
 printf("建立成功!\n\n");
 return L;
}

//在指定位置插入元素
void Insert_Elem(LinkList L,int i)
{
 int x;
 LNode *s,*p;
 p=numserch(L,i-1);
 s=(LNode *)malloc(sizeof(LNode));
 s->next=p->next;
 p->next=s;
 printf("请输入插入元素的数据:");
 scanf("%d",&x);
 s->data=x;
}

//删除指定序号的元素
void Delete_ELem(LinkList L,int i)
{
 int j=1;
 LNode *p=L->next;
 LNode *q=L;
 if(i==0) printf("头结点数据为空");
 if(i<0) printf("序号不得小于0");
 while(p&&j<i)
 {
  q=q->next;  //q指向被删结点的前一个结点
  p=p->next;  //p指向被删结点
  j++;
 }
 q->next=p->next;
 free(p);        //释放空间,删除P结点成功
 printf("删除%d号元素成功!\n\n",i);
}

//按序号查询元素值
LNode *numserch(LinkList L,int i)
{
 int j=1;
 LNode *p=L->next;
 if(i==0) return L;
 if(i<0) return 0;
 while(p&&j<i)
 {
  p=p->next;
  j++;
 }
 return p;
}

//按数值查询元素序号
void Dataserch(LinkList L,int x)
{
 LNode *p=L->next;
 int i=1;
 while(p)
 {
  if(p->data==x) printf("序号为:%d\t\n\n",i);
  i++;
  p=p->next;
 }
}

//按序号修改元素值
void Revise_Elem(LinkList L,int i)
{
 int x;
 LNode *p=L->next;
 p=numserch(L,i);
 printf("请输入修改后的元素值:");
 scanf("%d",&x);
 p->data=x;
}

//顺序输出所有元素值
void Output_Elem(LinkList L)
{
 int i=1;
 LNode *p=L->next;
 while(p)
 {
  printf("第%d号元素数据为%d\n",i,p->data);
  p=p->next;
  i++;
 }
 printf("\n");
}

//两个链表合并 
LinkList Combine(LinkList m,LinkList l)
{
 LNode *p;
 p=m->next;
 while(p->next!=NULL)
 {
  p=p->next;
 }
 p->next=l->next;
 free(l);
 return m;
}

//逆置,将各个结点摘下,按顺序头插法插入到头结点之后
LinkList Reverse(LinkList L)
{
 LNode *p,*r;
 p=L->next;
 L->next=NULL;
 while(p!=NULL)
 {
  r=p->next;
  p->next=L->next;
  L->next=p;
  p=r;
 }
 return L;
}

void main()
{
 int i,j=1,k;
 LNode *p,*a;
 LinkList n,m,l;
 while(j)
 {
  printf("请输入您想进行的操作:\n1.新建链表\n2.输出所有元素值\n3.按序号查找结点\n4.按序号插入结点\n5.按序号删除结点\n6.按数值查询元素值,输出元素序号\n7.按序号修改元素值\n8.链表逆置\n9.合并两个链表\t");
  scanf("%d",&i);
  switch(i){
  case 1: {n=TailInsert_List();break;}  //尾插法建立
  case 2: {Output_Elem(n);break;}    //输出所有元素值
  case 3: {                           //按序号查找
     printf("请输入查询序号:");
     scanf("%d",&k);
     a=numserch(n,k);
     printf("%d号数据为%d\n\n",k,a->data);break;
   }
  case 4: {                             //按序号插入
     printf("请输入插入元素的序号:");
     scanf("%d",&k);
     Insert_Elem(n,k);
     printf("插入成功!\n\n");break;
    }
  case 5:{                               //按序号删除
     printf("请输入需要删除的结点序号:");
     scanf("%d",&k);
     Delete_ELem(n,k);
     break;
      }
  case 6:{                               //按数值查询元素值,输出元素序号
     printf("请输入需要查询的元素值:");
     scanf("%d",&k);
     Dataserch(n,k);break;
      }
  case 7:{                               //按序号修改元素值
     printf("请输入需要修改的结点序号:");
     scanf("%d",&k);
     Revise_Elem(n,k);
     printf("修改成功!\n\n");break;
      }
  case 8:{                               //链表逆置
     n=Reverse(n);
     printf("逆置后的链表元素为:\n");
     Output_Elem(n);break;
      }
  case 9:{                               //将链表二合并到链表一之后
     printf("请输入链表一:");
     m=TailInsert_List();
     printf("请输入链表二:");
     l=TailInsert_List();
     m=Combine(m,l);
     printf("新链表数据为:");
     Output_Elem(m);break;
      }
 }
 }
 
}

因为比较简单,不需要什么思维,就不赘述说明了,直接上运行结果

1.新建一个单链表
在这里插入图片描述

2.输出全部元素值在这里插入图片描述

3查找某一序号的结点元素值
查询某一序号结点的元素值
4.按序号插入结点
在这里插入图片描述
5.删除指定序号的结点
在这里插入图片描述
6.按数值查询,输出元素序号
在这里插入图片描述
7.按序号修改元素值
在这里插入图片描述
8.链表逆置
在这里插入图片描述

9.合并两个链表
在这里插入图片描述
总结:本文有些划水,内容比较基础,下一篇会介绍单链表的考研题目。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

事多做话少说

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值