单链表和双链表

单链表

单链表的最大特点是可以将物理地址上不连续的数据连接起来,通过指针来对物理地址进行操作,实现增删改查等功能。单链表可以用来写邻接表邻接表可以用来存储图和树。
  链表中的数据是以结点来表示的,每个结点存个值:数据+next指针,空集的下标为-1,单链表是链式存取的结构,为找第 i 个数据元素,必须先找到第 i-1 个数据元素。
  单链表结点中只有一个只指向后继的指针,使得单链表只能从头结点开始一次顺序的先后遍历。要访问某个结点的前驱结点(插入删除操作时),只能从头开始遍历,访问后继节点的时间复杂度为O(1),访问前驱结点的时间复杂度为O(n)。
  举例:用单链表储存一串数3,5,7,9,11,13.(数据e[i],next指针ne[i],结点下标idx)
  在这里插入图片描述

单链表的简单操作

  • 在一个结点后插入一个结点
    在这里插入图片描述

在这里插入图片描述

  • 清除某个结点
    将该结点的next指针指向下下一个结点
    在这里插入图片描述
#include<iostream>

using namespace std;

const int N = 100005;
//head 是头结点的下标 
//e[i] 是i结点的值
// ne[i] 是i的下一个结点的地址
//idx 储存当前结点的地址 
int  head, e[N], ne[N], idx;
//初始化
void init()
{
	head = -1;//head 头结点为空(为空的结点的下标都用-1表示) 
	idx = 0;//单链表初始化 ,idx从0开始分配 
}
//将x插入到头结点
void add_to_head(int x)
{
	e[idx] = x,ne[idx] = head,head = idx,idx ++;
}
//在k结点后插入一个x 
void add(int k,int x)
{
	e[idx] = x;//新结点赋值
	ne[idx] = ne[k];//新结点的next指针为下标为k的结点的next指针
	ne[k] = idx;//将下标为k的结点的next指针指向新节点的下标
	idx++;
}
//删除下标是k的结点的后面一个结点 
void  remove(int k)
{
	ne[k] = ne[ne[k]];//下标为k的结点的next下标指向它的下下一个结点
}
int main()
{
	init();
	int x;
	cin >> x;
	add_to_head(x);//在头结点 插入一个x 
	for(int i = head;i != -1;i = ne[i])
	cout << e[i] <<' ';
	cout << endl;
	int k1,x1;
	cin >> k1 >>x1;
	add(k1,x1);//在下标为k1的结点后面插入一个x1 
	for(int i = head;i != -1;i = ne[i])
	cout << e[i] <<' ';
	cout << endl;
	int k2;
	cin >> k2;
	remove(k2);//清除下标为k2的结点的后面一个结点 
	for(int i = head;i != -1;i = ne[i])
	cout << e[i] <<' ';
	cout << endl;
	return 0;
 } 

在这里插入图片描述

双链表

双向链表也叫双链表,是链表的一种,它的每个数据结点中都有 两个指针,分别指向直接后继直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。一般我们都构造双向循环链表。
举例:存储下标和数据分别为1和3,2和4,3和5的双链表。
在这里插入图片描述

双链表的简单操作

  • 删除一个结点
    在这里插入图片描述
  • 插入一个结点

在这里插入图片描述

#include<iostream>

using namespace std;

const int N = 100005;
//e[i]表示下标为i的结点的值
//l[i]表示下标为i的结点的左结点的值
//r[i]表示下标为i的结点的右结点的值
//idx表示该结点的下标 
int e[N],l[N],r[N],idx;
//初始化
void init()
{
	r[0] = 1;//初始化下标0和1为双列表的两个边界 
	l[1] = 0;
	idx = 2;//0和1的下标已经被占用,idx从2开始 
} 
//在下标为k的结点的右边插入一个结点
void add(int k,int x)
{
	e[idx] = x;//初始赋值 
	r[idx] = r[k];
	l[idx] = k;
	l[r[k]] = idx;
	r[k] = idx;
	idx ++;
 } 
//清除下标为k的结点
void remove(int k)
{
	l[r[k]] = l[k];
	r[l[k]] = r[k];
}
int main()
{
	init();
	int k,x;
	cin >> k >> x;
	add(k,x);
	for(int i=r[0];i!=1;i=r[i])
	cout << e[i] << ' ';
	cout << endl; 
	int k1;
	cin >> k1;
	remove(k1);
	for(int i=r[0];i!=1;i=r[i])
	cout << e[i] << ' ';
	cout << endl;
	return 0;
}
	

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值