#include <stdio.h>
#include <stdlib.h>
/*
// 双向链表节点结构体
typedef struct ListNode {
int val; // 节点值
struct ListNode* next; // 指向后继节点的指针
struct ListNode* prev; // 指向前驱节点的指针
} ListNode;
// 构造函数
ListNode* newList Node(int val) {
ListNode* node, * next;
node = (ListNode*)malloc(sizeof(ListNode));
node->val = val;
node->next = NULL;
node->prev = NULL;
return node;
}
*/
/* 单向链表节点结构体 */
typedef struct ListNode {
int val; // 节点值
struct ListNode* next; // 指向下一节点的指针
} ListNode;
/* 构造函数 */
ListNode* newListNode(int val) {
ListNode* node = (ListNode*)malloc(sizeof(ListNode));
node->val = val;
node->next = NULL;
return node;
}
/* 在链表的节点 n0 和节点 n1 之间插入节点 P */
void insert(ListNode* n0, ListNode* P) {
ListNode* n1 = n0->next;
P->next = n1;
n0->next = P;
}
//删除链表指定节点
void removeItem(ListNode* n0) {
if (!n0->next)
return;
//在一般情况下,我们会删除一个节点后,需要更新之前节点的 next 指针,将其指向被删除节点的下一个节点,以保持链表的完整性。
// 而在这段代码中,由于删除了中间节点 P,我们直接将 n0 的 next 指针指向了 n1,绕过了 P,相当于直接删除了 P。
// 所以在这种情况下是没有必要再继续遍历链表进行删除操作的,直接返回即可。
// n0 -> P -> n1变成 n0 -> n1
ListNode* P = n0->next;
ListNode* n1 = P->next;
n0->next = n1;
// 释放内存
free(P);
}
/* 访问链表中头部为 n0 , 索引为 index 的节点 */
ListNode* access(ListNode* head, int index) {
while (head && head->next && index) {
head = head->next;
index--;
}
return head;
}
/* 在链表中查找值为 target 的首个节点,返回索引 */
int find(ListNode* head, int target) {
int index = 0;
while (head) {
if (head->val == target)
return index;
head = head->next;
index++;
}
return -1;
}
int main() {
// 初始化链表 1 -> 3 -> 2 -> 5 -> 4
// 初始化各个节点
ListNode* n0 = newListNode(1);
ListNode* n1 = newListNode(3);
ListNode* n2 = newListNode(2);
ListNode* n3 = newListNode(5);
ListNode* n4 = newListNode(4);
// 构建引用指向
n0->next = n1;
n1->next = n2;
n2->next = n3;
n3->next = n4;
//插入指定节点
ListNode* P = newListNode(7);
insert(n0, P);
printf("%d\n", P->val);
//删除链表指定节点
removeItem(n0);
//访问链表中索引为 index 的节点值
int* p = access(n0, 3);
printf("%d\n", *p);
/* 在链表中查找值为 target 的首个节点,返回索引 */
int m = find(n0, 2);
printf("%d\n", m);
// 遍历链表并输出节点的值
ListNode* current = n0;
while (current != NULL) {
printf("%d ", current->val);
current = current->next;
}
return 0;
}
啊哈算法头的
#include<stdio.h>
#include<stdlib.h>
//这里创建一个结构体用来表示链表的结点类型
typedef struct node
{
int data;
struct node* next;
}node;
int main()
{
node* head, * p=NULL, * q=NULL, * t;
int i, n, a;
scanf_s("%d", &n);
head = NULL;//头指针初始为空
for (i = 1; i <= n; i++)//循环读入n个数
{
scanf_s("%d", &a);
//动态申请一个空间,用来存放一个结点,并用临时指针p指向这个结点
p = (node*)malloc(sizeof(node));
p->data = a;//将数据存储到当前结点的data域中
p->next = NULL;//设置当前结点的后继指针指向空,也就是当前结点的下一个结点为空
if (head == NULL)
head = p;//如果这是第一个创建的结点,则将头指针指向这个结点
else
q->next = p;//如果不是第一个创建的结点,则将上一个结点的后继指针指向当前结点
q = p;//指针q也指向当前结点
}
//插入特定元素
scanf_s("%d", &a);//读入待插入的数
t = head;//从链表头部开始遍历
while (t != NULL)//当没有到达链表尾部的时候循环
{
if (t->next->data > a)//如果当前结点下一个结点的值大于待插入数,将数插入到中间
{
p = (node*)malloc(sizeof(node));//动态申请一个空间,用来存放新增结点
p->data = a;
p->next = t->next;//新增结点的后继指针指向当前结点的后继指针所指向的结点
t->next = p;//当前结点的后继指针指向新增结点
break;//插入完毕退出循环
}
t = t->next;//继续下一个结点
}
//输出链表中的所有数
t = head;
while (t != NULL)
{
printf("%d ", t->data);
t = t->next;//继续下一个结点
}
free(p);
return 0;
}
模拟链表
#include <stdio.h>
int main()
{
int data[101], right[101];
int i, n, t, len;
//读入已有的数
scanf_s("%d", &n);
for (i = 1; i <= n; i++)
scanf_s("%d", &data[i]);
len = n;
//初始化数组right
for (i = 1; i <= n; i++)
{
if (i != n)
right[i] = i + 1;
else
right[i] = 0;
}
//直接在数组data的末尾增加一个数
len++;
scanf_s("%d", &data[len]);
//从链表的头部开始遍历
t = 1;
while (t != 0)
{
if (data[right[t]] > data[len])//如果当前结点下一个结点的值大于待插入数,将数插入到中间
{
right[len] = right[t];//新插入数的下一个结点标号等于当前结点的下一个结点编号
right[t] = len;//当前结点的下一个结点编号就是新插入数的编号
break;//插入完成跳出循环
}
t = right[t];
}
//输出链表中所有的数
t = 1;
while (t != 0)
{
printf("%d ", data[t]);
t = right[t];
}
getchar();
getchar();
return 0;
}