单链表是带有头结点的单链表,讲解及注释在代码中:
#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;
}