链表的基本操作(c语言)

链表声明

规定每一个节点存储一个正整数值

struct list
{
	int value;
	struct list* next;
};//by wqs

根据序列创建链表

链表的创建分为从头插入从尾插入两种方法,本文采用从尾部插入的方法,至于头部插入法在注释中会提到。

首先要初始化链表(让头结点的next为NULL),然后根据序列创建列表。

我们在main函数里面创建链表,n表示序列的长度。

int main()
{
    struct list *p, *head, *tail;//head为头结点,tail为尾节点
    p = (struct list*)malloc(sizeof(struct list));
    head = p;
    tail = p;
    head->next = NULL;//链表的初始化完成
    int n;//序列长度
    scanf("%d", &n);
    for (i = 0; i < n; i++)
    {
        p = (struct list*)malloc(sizeof(struct list));
        scanf("%d", &p->value);//下面几行的注释演示头部插入法
        tail->next = p;//p->next = head->next;
        tail = p;//head->next = p;
        tail->next = NULL;//演示完毕
    }//链表的创建完成
}//by wqs

链表的查找操作

接下来的函数接受已经创建好的链表p的指针,以及要查找的数字x,如果找到了返回该节点的地址,否则返回NULL(如果p为NULL也返回NULL)。

struct list* find(struct list* p, int x)
{
    if (p == NULL) return NULL;
    struct list* m = p->next;
    while(m != NULL && m->value != x)
    {
        m = m->next;
    }//直到m为NULL(p里面没有x)或者m里面的值为x时,直接返回m,就是我们想要的结果
    return m;
}//by wqs

链表的插入操作

如果只是在尾部插入,或者头部插入只要按在main函数的方法既可,但是应该考虑一种可以在任何地方插入的方法

接下来的函数接受链表任意节点的指针p,已经要插入的数字x,无任何返回值,功能是将x插入到p位置的后方。

void insert(struct list* p, int x)
{
    if (p == NULL) return;
    struct list* m = (struct list*)malloc(sizeof(struct list));
    m->value = x;
    m->next = p->next;
    p->next = m;
}//by wqs

如果你把tail作为参数传入函数的话,就相当于尾部插入,头部插入同理。

链表的删除操作

首先规定,如果找不到这个数,或者表为NULL,我们便什么都不做,否则删除这个节点

在此之前我们可以编写一个findpre函数与find函数不同的是,他返回x的前一个节点,我们在delete里面要用到它,它与find函数编写策略是一样的。

struct list* findpre(struct list* p, int x)
{
    if (p == NULL) return NULL;
    while(p->next != NULL && p->next->value != x)
    {
        p = p->next;
    }
    return p;
}//by wqs

有了find函数与findpre接下来的链表删除函数将非常简单

void delete(struct list* p, int x)
{
    struct list* m = find(p, x);
    if (m == NULL) return;
    struct list* w = findpre(p, x);
    if (w == NULL) return;
    w->next = m->next;
    free(m);
}//by wqs

在这里再提供一种不借助find函数和findpre函数的链表删除方法,但这并不比上面的方法好,所以在总代码里面不会有它

void delete(struct list* p, int x)
{
    if (p == NULL) return;
    struct list* m = p->next;
    while(m != NULL && m->value != x)
    {
        p = p->next;
        m = p->next;
    }
    if (p != NULL && m != NULL)
    {
        p->next = m->next;
        free(m);
    }
}//by wqs

其他代码

下面的函数可以打印一个链表的结构

void jiegou(struct list* p)
{
	if (p == NULL || p->next == NULL) return;
	struct list* m = p->next;
	printf("链表的结构是:");
	while (m->next != NULL)
	{
		printf("%d->", m->value);
		m = m->next;
	}
	printf("%d\n", m->value);
}//by wqs

总代码

#include<stdio.h>
#include<stdlib.h>
struct list
{
	int value;
	struct list* next;
};
struct list* find(struct list*, int);
struct list* findpre(struct list*, int);
void delete(struct list*, int);
void insert(struct list*, int);//插入到这个位置的后面
void jiegou(struct list*);
int main()
{
	int n, x, i = 0;
	printf("一共多少个数字:");
	scanf("%d", &n);
	struct list* head, * tail, * p;
	p = (struct list*)malloc(sizeof(struct list));
	head = p;
	tail = p;
	head->next = NULL;
	printf("它们依次是:");
	for (i = 0; i < n; i++)
	{
		p = (struct list*)malloc(sizeof(struct list));
		scanf("%d", &p->value);
		tail->next = p;
		tail = p;
		tail->next = NULL;
	}
	printf("链表创建成功\n");
	jiegou(head);
	printf("查找:");
	scanf("%d", &x);
	if (find(head, x) == NULL) printf("不在链表中\n");
	else printf("找到了\n");
	int y;
	printf("在谁的后面插入:");
	scanf("%d", &y);
	printf("插入:");
	scanf("%d", &x);
	insert(find(head, y), x);
	printf("插入成功\n");
	jiegou(head);
	printf("删除:");
	scanf("%d", &x);
	delete(head, x);
	printf("删除成功");
	jiegou(head);
}
struct list* find(struct list* p, int x)
{
	if (p == NULL) return NULL;
	struct list* m = p->next;
	while (m != NULL && m->value != x)
	{
		m = m->next;
	}
	return m;
}
struct list* findpre(struct list* p, int x)
{
	if (p == NULL) return NULL;
	while (p->next != NULL && p->next->value != x)
	{
		p = p->next;
	}
	return p;
}
void delete(struct list* p, int x)
{
	struct list* m = find(p, x);
	if (m == NULL) return;
	struct list* w = findpre(p, x);
	if (w == NULL) return;
	w->next = m->next;
	free(m);
}
void insert(struct list* p, int x)
{
	if (p == NULL) return;
	struct list* m = (struct list*)malloc(sizeof(struct list));
	m->value = x;
	m->next = p->next;
	p->next = m;
}
void jiegou(struct list* p)
{
	if (p == NULL || p->next == NULL) return;
	struct list* m = p->next;
	printf("链表的结构是:");
	while (m->next != NULL)
	{
		printf("%d->", m->value);
		m = m->next;
	}
	printf("%d\n", m->value);
}//by wqs

输入样例

8
5 6 3 4 7 8 1 2
9
4
9
1

输出样例

一共多少个数字:
它们依次是:
链表创建成功
链表的结构是:5->6->3->4->7->8->1->2
查找:
不在链表中
在谁的后面插入:
插入:
插入成功
链表的结构是:5->6->3->4->9->7->8->1->2
删除:
删除成功链表的结构是:5->6->3->4->9->7->8->2

效果展示
在这里插入图片描述

王道408链表是指《王道计算机考研系列:数据结构(上)》中的一道考题,要求使用C语言实现链表基本操作链表是一种常用的数据结构,与数组相比,链表的大小可以动态变化,不需要预先指定大小。 链表基本操作包括:初始化、插入元素、删除元素、遍历元素、搜索元素和销毁链表。 1. 初始化:初始化一个空链表,即创建一个头节点,并将头节点的指针域设置为空。 2. 插入元素:向链表中插入一个新的节点,可以在链表的任意位置插入。具体操作为:创建一个新的节点,将新节点的数据赋值给新节点的数据域,将新节点的指针域指向需要插入位置的下一个节点,将前一个节点的指针域指向新节点。 3. 删除元素:从链表中删除一个节点,可以根据节点的位置或者特定的值进行删除。具体操作为:找到该节点的前一个节点,将前一个节点的指针域指向该节点的下一个节点,释放该节点内存空间。 4. 遍历元素:从链表的头节点开始,通过遍历节点的指针域,依次输出链表中的所有元素,直到指针域为空。 5. 搜索元素:根据给定的值,在链表中搜索相应的节点。具体操作为:从头节点开始,通过遍历节点的数据域,逐个比较节点中的值,如果找到匹配的值,返回该节点的地址;如果遍历完链表仍未找到匹配的值,返回空。 6. 销毁链表:释放链表中所有节点的内存空间,以免内存泄漏。具体操作为:循环遍历链表,释放每一个节点的内存空间,同时将链表的头节点设置为空。 通过以上的基本操作,可以在C语言中实现对链表的增删改查等操作。但需要注意的是,具体的实现可能会根据题目的要求有所不同,例如可能需要处理链表中的特殊情况(如删除头节点)或者自定义其他操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值