C语言实现单链表(可直接使用+详细注释)

大学生-程序元,开始记录生活
南枫在这里和大家一同进步,一同交流学习
注:代码实现用Visual Studio 2019

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
typedef int ElemType;
//单链表结点的定义
typedef struct LNode {//单链表结点类型
	ElemType data;//数据域
	struct LNode* next;//指针域
}LNode,*LinkList;
	//指针类型的LinkList,指向这个结构体
//*LinkList 等价于 struct LNode *

//头插法新建链表
LinkList CreatList1(LinkList& L)
{
	LNode* s; int x;
	L = (LinkList)malloc(sizeof(LNode));//带头结点的链表
	L->next = NULL;//L->data里面没放东西
	scanf("%d", &x);//从标准输入读入数据
	//3 4 5 6 7 9999
	while (x != 9999)
	{
		s = (LNode*)malloc(sizeof(LNode));//申请一个新空间,强制类型转换
		s->data = x;//把读取到的值,给新空间中的数据部分
		s->next = L->next;
		L->next = s;
		scanf("%d", &x);//读取标准输入
	}
	return L;
}
LinkList CreatList2(LinkList &L) {
	int x;
	L = (LinkList)malloc(sizeof(LNode));
	//			我们认为r是指向表尾节点的
	LNode* s, * r = L;
	//3 4 5 6 7 9999
	scanf("%d", &x);
	while (x != 9999) {
		s = (LNode*)malloc(sizeof(LNode));
		s->data = x;
		r->next = s;
		r = s;//r指向新的表尾节点
		scanf("%d", &x);
	}
	r->next = NULL;//尾节点的next指针赋值为NULL
	return L;
}
//打印链表中每个节点的数值
/*void PrintList(LinkList L)
{
	L = L->next;
	while (L != NULL)
	{
		printf("%3d", L->data);
		L = L->next;
	}
	printf("\n");
}*/
void PrintList(LinkList L)
{
	L = L->next;
	while (L != NULL)
	{
		printf("%3d", L->data);//打印当前结点数据
		L = L->next;//指向下一个结点
	}
	printf("\n");
}
LinkList GetElem(LinkList L,int i)
{
	int j = 1;
	LNode* p = L->next;//开始就让p指向第一个节点(不是头节点)
	if (i == 0)
		return L;
	if (i < 1)
		return NULL;
	while (p && j < i) {
		p = p->next;//让p指向下一个节点
		j++;
	}
	return p;
}
LinkList LocateElem(LinkList L, ElemType e)
{
	LinkList p = L->next;
	while (p != NULL && p->data != e) {
		p = p->next;
	}
	return p;
}
//往第i个位置插入元素
bool ListFrontInsert(LinkList L, int i, ElemType e)
{
	//拿到要插入位置的前一个位置的地址值
	LinkList p = GetElem(L, i-1);
	if (NULL == p) {
		return false;
	}
	LinkList s = (LNode*)malloc(sizeof(LNode));//为新插入的节点申请空间
	s->data = e;
	s->next = p->next;
	p->next = s;
	return true;
}
//删除第i个位置的元素
bool ListDelete(LinkList L, int i)
{
	LinkList p = GetElem(L, i - 1);//查找删除位置的前驱节点
	if (NULL == p) {
		return false;//要删除的位置不存在
	}
	LinkList q = p->next;
	if (q == NULL)//删除的元素不存在
		return false;
	p->next = q->next;//断链
	free(q);//释放对应节点的空间
	q = NULL;//为了避免野指针
	return true;
}
int main()
{
	LinkList L;//链表头,是结构体指针类型,等于struct LNode* L;
	LinkList search;//用来存储拿到的某一个结点
	//CreatList1(L);//输入数据可以为3 4 5 6 7 9999 头插法新建链表
	//PrintList(L);
	CreatList2(L);//尾插法新建链表
	//PrintList(L);
	search = GetElem(L, 2);//按序号查询
	if (search != NULL) {
		//printf("按序号查找成功\n");
		printf("%d\n", search->data);
	}
	//search = LocateElem(L, 6);//按值查询
	//if (search != NULL) {
	//	printf("按值查找成功\n");
	//	printf("%d\n", search->data);
	//}
	ListFrontInsert(L, 2, 99);//新节点插入第i个位置
	PrintList(L);//链表打印
	ListDelete(L, 4);
	PrintList(L);
	return 0;
}

如果您感觉这篇文章有帮助,希望大家可以点个赞,支持一下。
您的支持,就是我的动力。

  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,下面是链表的 C 语言实现注释: ```c #include <stdio.h> #include <stdlib.h> // 定义链表结点的结构体 struct Node { int data; // 数据域 struct Node* next; // 指针域,指向下一个结点 }; // 定义一个函数,用于在链表的末尾插入一个结点 void appendNode(struct Node** head_ref, int new_data) { // 为新结点分配内存 struct Node* new_node = (struct Node*)malloc(sizeof(struct Node)); // 将新结点的数据域赋值为 new_data new_node->data = new_data; // 将新结点的 next 指针设置为 NULL,表示该结点是链表的最后一个结点 new_node->next = NULL; // 如果链表为空,则将新结点作为链表的第一个结点 if (*head_ref == NULL) { *head_ref = new_node; return; } // 否则,遍历链表,找到最后一个结点,将其 next 指针指向新结点 struct Node* last = *head_ref; while (last->next != NULL) { last = last->next; } last->next = new_node; } // 定义一个函数,用于在链表中查找某个值,并返回该结点的位置 int searchNode(struct Node* head, int target) { // 遍历链表,查找目标值 int pos = 1; struct Node* current = head; while (current != NULL) { if (current->data == target) { return pos; } current = current->next; pos++; } // 如果链表中不存在目标值,则返回 -1 return -1; } // 定义一个函数,用于删除链表中的某个结点 void deleteNode(struct Node** head_ref, int target) { // 如果链表为空,则直接返回 if (*head_ref == NULL) { return; } // 如果第一个结点就是要删除的结点,则将头指针指向第二个结点 if ((*head_ref)->data == target) { struct Node* temp = *head_ref; *head_ref = (*head_ref)->next; free(temp); return; } // 否则,遍历链表,找到要删除的结点 struct Node* current = *head_ref; while (current->next != NULL && current->next->data != target) { current = current->next; } // 如果找到了要删除的结点,则将它从链表中删除 if (current->next != NULL) { struct Node* temp = current->next; current->next = current->next->next; free(temp); } } // 定义主函数,测试链表的各种操作 int main() { // 定义头指针,并将它初始化为 NULL,表示链表为空 struct Node* head = NULL; // 在链表末尾插入一些结点 appendNode(&head, 1); appendNode(&head, 2); appendNode(&head, 3); // 查找链表中是否存在某个结点 int pos = searchNode(head, 2); if (pos != -1) { printf("2 is found at position %d\n", pos); } else { printf("2 is not found in the list\n"); } // 删除链表中的某个结点 deleteNode(&head, 2); // 再次查找链表中是否存在某个结点 pos = searchNode(head, 2); if (pos != -1) { printf("2 is found at position %d\n", pos); } else { printf("2 is not found in the list\n"); } return 0; } ``` 以上就是链表的 C 语言实现注释,希望对你有帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

南枫_Y

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

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

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

打赏作者

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

抵扣说明:

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

余额充值