单链表的结构以及基础算法

单链表

链表的结构

//单链表结构
typedef struct LNode
{
int val;
//data *info;
//不仅可以存储一个int整形变量,还可以存储一个新结构体
struct LNode *next;//指向新的下一个节点的指针
//struct LNode *ptr;//双向指针指向前一个节点的指针
}LNode,*linkList;
//以上代码类似于
/*
typedef struct LNode LNode; //将结构体重命名为LNode,是结构体类型
typedef struct LNode *LinkList; //将结构体指针重命名为LinkList,是指针类型
*/
typedef struct data
{
int a;
char b;
string c;
boolean d;
...
}data;

创建链表

//前插法创建单向链表,链表最终是输入的倒序
void createListFormer(linkList &L,int n)
{
linkList p;
L=new LNode;
L->next=NULL;
for(int i=0;i<n;i++)
{
p=new LNode;
cin>>p->val;
p->next=L->next;
L->next=p;
}
}
//后插法创建链表,链表最终是正序
void createListTail(linkList &l, int n)
{
l = new LNode;
l->next = NULL;
linkList r = l;
linkList p;
while (n--)
{
p = new LNode;
cin >> p->val;
p->next = NULL;
r->next = p;
r = p;
}
}

链表翻转

/*假设链表为1→2→3→∅,我们想要把它改成 ∅←1←2←3。
在遍历链表时,将当前节点的 next 指针改为指向前一个节点。由于节点没有引用其前一个节点,因此必须事先存储其前一个节点。在更改引用之前,还需要存储后一个节点。最后返回新的头引用。
每次要做的就是将当前节点的next指向pre
*/
//单链表
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode* prev = nullptr;
ListNode* curr = head;//curr是当前节点
while (curr) {
ListNode* next = curr->next;//提前存储下一个节点
curr->next = prev;//指向已经改变了
prev = curr;//当前节点会变成下一个节点的pre节点
curr = next;
}
return prev;
}
};

添加节点

void addPoint(linkList &L) //这里定义添加节点为在第pos个节点之前添加
{
int pos, data;
cin >> pos >> data;
linkList p = L;
linkList pre;
linkList t = new LNode;
t->next = NULL;
t->val = data;
//链表为空或向链表尾部添加节点
if (p->next == NULL || pos == p->val + 1)
{
while (p->next)
{
p = p->next;
}
p->next = t;
}
else //其他
{
if (pos < 1 || pos > p->val + 1)
{
cout << "不存在该位置" << endl;
return;
}
while (pos--)
{
pre = p;
p = pre->next;
}
t->next = p;
pre->next = t;
}
}

删除节点

//单链表
void deletePoint(linkList &L)//删除第n个节点
{
int n;
cin >> n;
linkList p = L;
linkList pre;
if (p->next == NULL) //链表为空
{
cout << "链表为空" << endl;
return;
}
if (n <= 0 || n > p->val)
{
cout << "不存在该位置" << endl;
return;
}
if (n == p->val) //删除尾节点
{
cout << "删除尾节点" << endl;
while (p->next->next)
{
p = p->next;
}
p->next = NULL;
}
else //其他
{
while (n--)
{
pre = p;
p = pre->next;
}
pre->next = p->next;
}
}

查找节点

void findPoint(linkList L)
{
linkList p = L;
if (!L->next)
{
cout << "链表空" << endl;
return;
}
int n;
cin >> n;
if (n < 1 || n > p->val)
{
cout << "不存在该位置" << endl;
return;
}
while (n--)
{
p = p->next;
}
cout << p->val << endl;
}

打印链表

//打印链表
void printList(linklist L)
{
linklist p;
p = L->next;
while (p)
{
cout << p->val << " ";
p = p->next;
}
}
posted @   K-L  阅读(131)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示