链表基本操作
本文是 链表建立 的下篇
本文主要完善一些单链表的基本操作
废话不多说,直接上代码
#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.合并两个链表
总结:本文有些划水,内容比较基础,下一篇会介绍单链表的考研题目。