ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

双向链表学习笔记

2022-08-12 10:30:47  阅读:180  来源: 互联网

标签:Node pre zd 笔记 next 链表 tail 双向


双向链表学习笔记


啰嗦

双向链表
这是百度里给出的解释.
说的通俗一点,就是左右都连着元素的数据结构.(好像也不怎么通俗)
这次手打,不玩STL.
啰嗦完了,那就切入正题了.

双向链表

双向链表嘛,那就是长这个样子:

大家看看就好了.

定义(struct)

定义长这样:

struct Node{
	int x;
	Node *next,*pre;
}head,tail;

是什么意思呢?我们一个一个解释:

struct Node{
	int x;  //值.
	Node *next,*pre;  //next指向下一个节点,pre指向前一个节点.
}head,tail;//head是链表顶端元素,tail是链表末端元素(head和tail没有值,head.pre=tail.next=NULL)

看完了吧?我们继续.

插入一个数(addl与addr)

这是两个函数的代码:

void addl(Node *r,int x){  //在地址
	Node *l=r->pre;
	Node *zd=new Node{x,r,l};
	l->next=zd;
	r->pre=zd;
}
void addr(Node *l,int x){
	Node *r=l->next;
	Node *zd=new Node{x,l,r};
	l->next=zd;
	r->pre=zd;
}

注:出现警告是正常的,不用害怕(我也不知道为什么,能过就行了),如果有个别强迫症,如下代码也行

void addl(Node *w,int x){
	Node *l=r->pre;
	Node *zd=new Node;
	zd->x=x;
	zd->next=r;
	zd->pre=l;
        l->next=zd;
	r->pre=zd;
}
void addr(Node *l,int x){
	Node *r=l->next;
	Node *zd=new Node;
	zd->x=x;
	zd->next=r;
	zd->pre=l;
	l->next=zd;
	r->pre=zd;
}

现在就开始解释了.
注:x->y就相当于(*x).y.
先看如下图:

现在有一个\(a_4\) 想要插在\(a_3\) 与\(tail\)之间,那么我们应该把\(a_3\) 的\(next\)指向\(a_4\) ,把\(tail\)的\(pre\)指向\(a_4\) ,即(可能画的有点丑):

然后再把\(a_4\) 的\(next\)指向\(tail\),\(pre\)指向\(a_3\) 就好了.我就不画了(画太丑了).
这里再补充一下:
new:新建一个节点(类型自定),返回该节点的地址.
这下应该都懂了吧?先练练手!

练习1

题目描述

创建一个新链表,往里面添加\(n\)个元素,请在最后分别正向与反向输出链表.

输入

第一行\(n\),表示初始链表n个点.
第二行\(n\)个数字,表示链表.

输出

第一行正向输出链表.
第二行反向输出链表.

input

5
1 2 3 4 5

output

1 2 3 4 5
5 4 3 2 1

思考

这题的重点就是正向反向输出链表.
那么我们可以像循环一样输出,也可以用一个指针\(while\)输出,我选择的是\(while\).
那么起点与终点该怎么设置呢?我们再看原来那张图:

我们要从\(a_1\)出发,到达\(a_3\) .
但是我们没有\(a_1\)的确切地址,该怎么办?
往回看,\(head\)的\(next\)就指向\(a_1\) .
那么,起点就是\(head->next\).
但是终点可不是\(tail->pre\),而是\(tail\).
因为设置成\(tail->pre\)了话,到达\(a_3\)也就是\(tail->pre\)的时候就结束了循环.
代码如下:

void print1(){  //正向
	Node *i=head.next;
	while (i!=&tail) cout<<i->x<<" ",i=i->next;
	cout<<"\n";
}
void print2(){  //反向
	Node *i=tail.pre;
	while (i!=&head) cout<<i->x<<" ",i=i->pre;
}

代码

#include<bits/stdc++.h>
//#define int long long
using namespace std;
int n,x,m,y;
struct Node{
	int x;
	Node *next,*pre;
}head,tail;
void addl(Node *w,int x){
	Node *t=w->pre;
	Node *zd=new Node;
	zd->x=x;
	zd->next=w;
	zd->pre=t;
	t->next=zd;
	w->pre=zd;
}
void delet(Node *qwq){
	Node *t=qwq->pre;
	Node *w=qwq->next;
	w->pre=t;
	t->next=w;
	free(qwq);
}
Node *find(int x){
	Node *k=head.next;
	while (k->x!=x&&k!=&tail) k=k->next;
	return k;
}
void print1(){
	Node *i=head.next;
	while (i!=&tail) cout<<i->x<<" ",i=i->next;
	cout<<"\n";
}
void print2(){
	Node *i=tail.pre;
	while (i!=&head) cout<<i->x<<" ",i=i->pre;
}
signed main(){
	ios::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
	head.next=&tail;  //把head和tail连起来可别忘了哦!
	tail.pre=&head;
	cin>>n>>m;
	for (int i=1;i<=n;i++){
		cin>>x;
		addl(&tail,x);
	}
	print1();print2();
	return 0;
}

(未完待续)

标签:Node,pre,zd,笔记,next,链表,tail,双向
来源: https://www.cnblogs.com/Sity-Hugh/p/16577582.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有