链表

本文探讨了在使用链表时可能遇到的问题,如访问空节点导致程序卡死,并提供了创建单链表的头插法实现。此外,还介绍了双向链表的优化方法,特别是如何避免在插入和查找时遍历整个链表,以提高效率。通过实例展示了如何在双向链表中插入和删除元素。
摘要由CSDN通过智能技术生成

踩到的坑:

在使用链表时如果那个结点没有东西,
如 q->r->NULL,但你还要printf("%d", q->r->date);
程序就会卡住。。。
也就是说当双链表的时候你要在q的右结点插入一个结点,
但是你不是到q->r是不是等于NULL
盲目的直接链接两边就也会像上面一样卡住。

=>还有关于结构体中什么时候用 “.“ 什么时候用“->“以及其他的问题

简单的单链表:

#include<bits/stdc++.h>
using namespace std;

typedef struct Node
{
	int date;
	struct Node *next;	
}LNode, *linklist;

 
void Illustrate(linklist head)//输出函数的函数 
{
	linklist tem = head; //将头指针的地址赋值给零时指针tem 
	while(tem->next != NULL) {
		tem = tem->next;
		printf("%d\n", tem->date);
	}
}

linklist Creat_list(linklist head)//创建头插法单链表 
{
	head = (linklist)malloc(sizeof(Lode));//为头指针开辟内存空间,没开空间就存不了东西,只能指方向 
	Lnode *node = NULL;										//定义一个结构体指针 node它指向 NULL 
	int count = 0;  											//创建结点的个数 
	head->next = NULL;
	node = head->next;										//最后一个结点永远为 null 
	printf("Input the node number: ");
	scanf("%d", &count);									//看你要创建几个结点 
	for(int i=0; i<count; i++)
	{
		node = (linklist)malloc(sizeof(Lnode)); //为新结点开辟内存空间 
		node->date = i;											//为你的结点的数据域赋值 
		node->next = head->next;						//node的下一个结点为 head的下一个结点	
		head->next = node;  								//head断开下一个结点连接上 node 
	}																					//这样 node就插到 head的后面了 
	return head;
}

int main()
{
	linklist head = NULL;//链表的头指针
	head = Creat_list(head);//创建链表
	Illustrate(head);//输出每一个结点的数据域
	system("pause");//暂停 
	return 0;
}

双向链表

双向链表跟单链表差不多
但是它每次要找一个数都要完全遍历一次
所有有点麻烦,我们来说优化后的双向链表
做题目时我们要找到合适的优化方法

如下面的例题
https://www.luogu.com.cn/problem/P1160
答案:

#include<bits/stdc++.h>
using namespace std;
struct node
{
	int date;
	node *l;
	node *r;	
}arr[100003]; 

//输入:找到目标数 k 根据 p在 k的周围插入一个数 
void input(int k, int p, int i)
{
	//给新建立的数字赋值 
	arr[i].date = i;
	arr[i].l = NULL; arr[i].r = NULL;
	 
	//连接操作 
	if(p == 1)//右边 
	{
		arr[i].l = &arr[k];
		arr[i].r = arr[k].r;
		arr[k].r = &arr[i];							 
		arr[i].r->l = &arr[i];
	}
	else
	{
		arr[i].r = &arr[k];
		arr[i].l = arr[k].l;
		arr[k].l = &arr[i];							 
		arr[i].l->r = &arr[i];
	}
} 
 
void output(int k)//删除 数为k 的值 
{
	if(arr[k].date != -1)
	{
		arr[k].l->r = arr[k].r;
		arr[k].r->l = arr[k].l;
		arr[k].date = -1;
	}
} 
 
int main()
{
	//初始化
  /*思路: 为了避免上面谈到的错误,我们建立一个front与 rear 来放在最前面跟最后面
					这样插入数据时就不会出现上面谈及的问题*/ 
	arr[1].date = 1;										
	arr[1].l = &arr[0];
	arr[1].r = &arr[100002];
	
	node *front = &arr[0];
	node *rear  = &arr[100002];
	front->l = NULL; front->r = &arr[1]; front->date = -1;
	rear->r = NULL; rear->l = &arr[1];	rear->date = -1;
	/*-------------------------------------------*/
	int n, m;
	int k, q;
	
	cin >> n;
	for(int i=2; i<=n; i++)
	{
		cin >> k >> q;
		input(k, q, i);
	}
	cin >> m;
	for(int j=1; j<=m; j++)
	{
		cin >> k;
		output(k);
	}
	
	node *t = front->r;
	while(t->date != -1)
	{
		printf("%d ", t->date);
		t = t->r;
	}
  return 0;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值