单向链表是链表中的一种,其特点是链表的链接方向是单向的,对链表的访问要通过从头部开始,依序往下读取。当然,往后对数据结构的深入学习,还会涉及到双向链表、循环链表等线性表,我在这里就不再解释了。
链表主要是由结点一个个相继串起来的,其中每一个结点又被分为两个部分:(data)数据域、(next)指针域。
- 数据域(data):主要是保存的是关于结点的信息
- 指针域(next):存储的是下一个结点的地址
单向链表的形式:
那么,既然我们知道了单链表的元素是什么样了,以及单链表的形式是如何了,我们就可以开始动手实现简单的增、删、查、改。
首先,要学会链表的创建,创建无非也就是增加:
- 如果链表为空,那么建立链表并且将增加的这个结点作为第一个结点
- 如果链表不为空,那么就直接遍历插到尾部
需要说明的是,为了避免二重指针的操作,便于各位的理解,我这里用的是头结点来保存指向第一个结点的地址,也就是我舍去了头结点的数据域,以它的next指向一个新的结点,如上图的单向链表的形式
//两个参数 一个是头结点,一个是 要插入的结点
//头结点:它的next指向的才是一个新的结点开始
void addNode(listNode * head, listNode * q)
{
listNode * p = head->next;
if (head->next == NULL)
{
head->next = q;
}
else
{
while (p->next != NULL)
{
p = p->next;
}
p->next = q;
}
}
链表的删除:这里的删除,指的是删除其中的某个结点,既然要删除某个结点,那么便是要遍历出符合给定条件的就把它删除。
void deleteNode(listNode * head, int data)
{
listNode * p = head->next, *q = head;
//如果是空的 可以返回一个提醒也可以不处理
while (p)
{
if (p->data == data)
{
q->next = p->next;
free(p);
break;
}
q = p;
p = p->next;
}
}
查、改的操作在这里我就不细说了,因为,这个实现起来就是一个循环,然后再判断每一个数据域是否与你要查找的一致…
最后,我以一个整体的程序结束这篇博客:
#include <stdio.h>
#include <stdlib.h>
struct listNode
{
int data;
struct listNode * next;
};
typedef struct listNode listNode;
void addNode(listNode * head, listNode * q);
void deleteNode(listNode * head, int data);
int main()
{
listNode head,*q,*p;
head.next = NULL;
int i;
//链表的创建
for (i = 1; i < 6; i++)
{
q = (listNode *)malloc(sizeof(listNode));
if (!q) exit(0);
q->data = i;
q->next = NULL;
addNode(&head, q);
}
p = head.next;
while (p)
{
printf("%d ", p->data);
p = p->next;
}
printf("\n");
deleteNode(&head, 2); //删除数据域为 2 的结点
p = head.next;
//遍历输出
while (p)
{
printf("%d ", p->data);
p = p->next;
}
//释放整个链表的内存空间
p = head.next;
q = &head;
while (p)
{
q->next = p->next;
free(p);
p = q->next;
}
return 0;
}
//两个参数 一个是头结点,一个是 要插入的结点
//头结点:它的next指向的才是一个新的结点开始
void addNode(listNode * head, listNode * q)
{
listNode * p = head->next;
if (head->next == NULL)
{
head->next = q;
}
else
{
while (p->next != NULL)
{
p = p->next;
}
p->next = q;
}
}
void deleteNode(listNode * head, int data)
{
listNode * p = head->next, *q = head;
//如果是空的 可以返回一个提醒也可以不处理
while (p)
{
if (p->data == data)
{
q->next = p->next;
free(p);
break;
}
q = p;
p = p->next;
}
}
运行结果:
如果您喜欢的话,记得点个赞哇!!!Thanks.