单链表其实是很简单的东西,但是对于很多大二初学数据结构的同学来说可能会有点懵,所以我这里简单的写一下单链表的基本操作。
下面的一串代码我分部分来说一下。
(1)创建结构体部分,你会发现我们创建的结构体里面有一个存储的数据和一个指向下一个结点的指针构成,而且结构体的名字有两个,一个是node,一个是指针类型的*LinkList。
这里说一下: node *p 这个在下面频繁出现的定义是为了创建一个临时的结点,用来存储我们想要插入的数据,然后将结点插入进链表里。
那个LinkList L其实就是链表的头结点。
这里再说一点,有很多同学搞不明白为什么会有的时候用 node *p来定义一个结点,有的时候用LinkList p来定义一个结点,其实:node *p和LinkList p是等价的。
如果这里搞不明白的话,这里就推荐《C程序设计》谭浩强第三版去补强一下基础。
(2)LinkList CreateList(int n)函数部分,这里的函数类型是LinkList,也就是指针型的函数,所以这个函数的返回值是一个地址,这里的返回值就是return L;
L就是头结点的地址。
然后我们这里再搞两个临时的指针*p1,*q1,用来帮助插入结点。
L=(node*)malloc(sizeof(node));//开辟存储空间
上面这行代码为头结点开辟一个空间,但是头结点里不存储数据,只是存储一个指向第一个结点的指针罢了,也就是L当中只有 *next 没有 data。
(3)print函数和FindDatanum就不说了,就是沿着链表进行操作就ok了。
(4)LinkList Deletenode(LinkList L,int x)
这个函数的返回值也是一个地址,return L;
这里就要说一点了,我们这里用p指针指向一个结点 S,然后我们想删除结点S后面的那个结点D,结点D后面还有一个结点F。 链表是这样的: S–D--F
我们就这么写代码:p->next=p->next->next;
链表就变成了:S–F.
其实结点D还是存在的,只不过我们的链表不再链接它了罢了。
#include<stdio.h>
#include<stdlib.h>
typedef struct LNode
{
int data;
struct LNode* next;
}node,*LinkList;
LinkList CreateList(int n)
{
LinkList L;
node *p1,*p2;//这里的p1其实就相当于课本上的s,一个需要插入的结点
L=(node*)malloc(sizeof(node));//开辟存储空间
p2=L;
while(n--)
{
p1=(node*)malloc(sizeof(node));
scanf("%d",&p1->data);
p2->next=p1;//尾插法
p2=p1;
}
p2->next=NULL;
return L;
}
void print(LinkList L)//输出链表
{
node *p;
p=L->next;
while(p!=NULL){
printf("%d ",p->data);
p=p->next;
}
printf("\n");
}
//这个函数是用来查找我们要找的值在链表的哪个位置
int FindDatanum(LinkList L,int x)
{
int i=0;
node *p;
p=L->next;
while(p!=NULL)
{
i++;
if(p->data==x)
break;
p=p->next;
}
return i;
}
//下面的是删除结点的函数
LinkList Deletenode(LinkList L,int x)
{
node *p;
p=L->next;
while(p->next!=NULL)
{
if(p->next->data==x)
{
p->next=p->next->next;
}
p=p->next;
}
return L;
}
int main()
{ int result=0;
int x;
scanf("%d",&x);
getchar();
//首先我们要确定这个链表的长度是5
int n=5;
LinkList L=NULL;
//首先创建一个链表
L=CreateList(n);
//下面现实的是输出的我们输入的链表
print(L);
//这个结果是显示我们找的值在链表的哪个位置
result=FindDatanum(L,x);
printf("%d\n",result);
//这里我们要删除结点的值为x的结点,然后将删除结点后的链表输出出来
L=Deletenode(L,x);
print(L);
return 0;
}