单链表的创建以及基本操作函数详解(C语言)

单链表是带有头结点的单链表,讲解及注释在代码中:

#define _CRT_SECURE_NO_WARNINGS
#pragma once//防止头文件重复包含
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define OK 1
#define ERROR 0
#define ElemType int
typedef struct {
	ElemType data;
	struct LNode* next;
}LNode,*Link;
int Creat(Link* L) {//结构体指针地址改变,需作用到外面,故需要使用二级指针
	*L = (LNode*)malloc(sizeof(LNode));
	if (*L == NULL) {
		printf("内存开辟失败\n");
		return ERROR;
	}
	(*L)->next = NULL;
	(*L)->data = 0;
	return OK;
	//LNode node; 
	//*L = &node;//这种方式开辟内存出函数内存就被销毁
};
void Append_lian(Link L, ElemType e) {//尾插法添加
	while (L->next)//next为NULL时停止循环表示找到了
	{
		L = L->next;
	}//找到链表的最后一个结构体
	Link p;//创建一个临时的结构体指针,将两块结构体缝补到一起,离开函数指针消失
	Creat(&p);//获取临时地址
	p->data = e;//添加值
	L->next = p;//将p的临时地址赋予next,至此p的任务圆满完成,离开函数p消失
}
int Lenth(Link L) {//求链表长度,不包含头结点
	int len = 0;
	while (L->next)
	{
		L = L->next;
		len++;
	}
	return len;
}
int Search(Link L, int p) {//根据下标找值(类似python中列表的索引)从1开始,支持-1作为倒数第一个,0作为头节点位置
	if (p == 0) {
		printf("头结点不存储数据\n");
		return ERROR;
	}
	else if (p > 0 && p <= Lenth(L)) {
		while (p )//移动到下标p位置
		{
			L = L->next;
			p--;
		}
		return L->data;
	}
	else if(p < 0 && p >= -Lenth(L))
	{
		int count = Lenth(L) + 1 + p;
		while (count)//移动到下标p位置
		{
			L = L->next;
			count--;
		}
		return L->data;
	}
	else
	{
		printf("超出链表长度\n");
		return ERROR;
	}
}

int Insert(Link L, int p, ElemType e) {//p表位置从1开始,e表元素,在选定位置插入,也可用此方法创建链表,p的值为1就是头插法
	if (p > Lenth(L)+1) return ERROR;
	Link q;
	Creat(&q);
	while (p-1)//移动到下标p的前一个元素的位置
	{
		L = L->next;
		p--;
	}
	q->data = e;
	q->next = L->next;
	L->next = q;
	return OK;

}
int Del_index_lian(Link L, int p) {//根据下标删除,删除成功返回删除的元素值
	if (p == 0) {
		printf("头结点不可删除\n");
		return ERROR;
	}
	else if (p > 0 && p <= Lenth(L)) {
		while (p-1)//移动到下标p的前一个元素的位置
		{
			L = L->next;
			p--;
		}
		
	}
	else if (p < 0 && p >= -Lenth(L))
	{
		int count = Lenth(L) + p;
		while (count)//移动到下标p的前一个元素的位置
		{
			L = L->next;
			count--;
		}
		
	}
	else
	{
		printf("超出链表长度\n");
		return ERROR;
	}
	Link q = L;
	L = L->next;
	q->next = L->next;
	free(L);
	return L->data;

}
void Print_List(Link L) {

	while (L->next)
	{
		L = L->next;
		printf("%d\n", L->data);
	}

}
int Find_elem_lian(Link L, int e) {
	int n = 0;
	while (1)
	{
		if (L->data == e) return n ;
		else if (L->next == NULL)
		{
			printf("查无此元素\n");
			return ERROR;
		}
		else
		{
			L = L->next;
		}
		n++;
	}

}
int Del_elem(Link L, int e) {
	Link q = L;//拷贝一份用来查找
	int n =Find_elem_lian(q, e);
	Del_index_lian(L, n);
	return OK;

}

测试代码:

int main() {
	Link list;
	Creat(&list);
	for (int i = 0; i < 10; i++)
	{
		Append_lian(list, i + 1);
	}
	Del_elem(list, 5);
	Del_index_lian(list, 5);
	Insert(list, 5, 55);
	printf("%d\n", Search(list, 5));
	Print_List(list);

	return 0;
}

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值