#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;
}
posted on 2024-01-07 17:19  lulixiu  阅读(3)  评论(0编辑  收藏  举报