数据结构-链表

这篇博客介绍了链表的基本概念,包括单向、双向和循环链表,并通过代码展示了如何在链表中进行插入和删除操作。此外,还详细解释了约瑟夫问题的解决方案,以及如何利用链表解决添加字符的问题。通过实例代码,帮助读者理解链表的使用和操作。
摘要由CSDN通过智能技术生成

了解什么是数据结构

数据结构的定义<----<-----点击即可查看。

简介

链表属于线性表(1维)数据结构。含有指针,种类分单向指针链表、双向指针链表、单向循环链表、双向循环链表4类。可以使用O(1)的方法增删,需要用O(n)进行查找。

操作

让我们了解一下链表究竟是怎样存储的。

图片表示

单向指针链表

Alt

双向指针链表

Alt

单向循环指针链表

Alt

双向循环指针链表

Alt

具体实现

本人暂时只用数组的方式实现双指针循环链表(用标准指针太复杂了,暂且用数组)。

  1. 定义方式: const int maxn=1e3+10; struct node{ int data,pre,next;}list[maxn]; int tot;
  2. 插入元素a在list[pos]的前面:list[tot].data=a; list[tot].pre=list[pos].pre; list[tot].next=pos; list[list[pos].pre].next=tot; list[pos].pre=tot; tot++;//注意顺序很重要
  3. 删除元素list[pos]:list[list[pos].pre].next=list[pos].next; list[list[pos].next].pre=list[pos].pre;

经典题目

(由于数据结构只是用于辅助程序,暂时不做分类)

约瑟夫问题

(会上面基本操作就行)

题目链接

约瑟夫问题

题目思路

(此题属于模板题,大佬勿喷)

  1. 按题目需求建一个双指针循环链表(单指针循环链表也可以)
  2. 循环模拟出圈直至只剩1人。
  3. 将最后1人输出

代码实现

#include<iostream>
using namespace std;

const int maxn=3e2+10;
int n,m;
struct node{
	int data,pre,next;
};
node list[maxn]; 
//删除函数
void remove(int pos){
	list[list[pos].pre].next=list[pos].next;
	list[list[pos].next].pre=list[pos].pre;
}
int main(){
	while(1){
		cin>>n>>m;
		if(n==0&&m==0)break;
		//初始化
		for(int i=0;i<n;i++){
			list[i].data=i+1;
			if(i==0)list[i].pre=n-1;
			else list[i].pre=i-1;
			if(i==n-1)list[i].next=0;
			else list[i].next=i+1;
		}
		int current=0;
		//循环模拟
		for(int i=0;i<n-1;i++){
			for(int j=0;j<m-1;j++){
				current=list[current].next;
			}
			remove(current);
			current=list[current].next;
		}
		cout<<list[current].data<<endl;
	}
	return 0;
}

添加字符

题目链接

添加字符

题目思路

(模板)

  1. 按题目需求建一个双指针循环链表(单指针循环链表也可以)
  2. 按题目模板操作即可
  3. 输出最终字符串

代码实现

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

const int maxn=2e5+10;
struct node{
	char data;
	int pre,next;
};
node a[maxn];
int n,tot;
string s;
//插入元素
int insert(int pos,char data){
	a[tot].data=data;
	a[tot].pre=a[pos].pre;
	a[tot].next=pos;
	a[a[pos].pre].next=tot;
	a[pos].pre=tot;
	return tot++;
}
int main(){
	cin>>s;
	int len=s.length();
	//初始化
	for(int i=0;i<len;i++){
		a[tot].data=s[i];
		a[tot].next=(i==len-1 ?-1:i+1);
		a[tot].pre=i-1;
		tot++;
	}
	cin>>n;
	int pos=0;
	//执行操作
	while(n--){
		int dis;
		cin>>dis;
		if(dis==0){
			char c;
			cin>>c;
			pos=insert(pos,c); 
		}
		else if(dis<0){
			for(int i=0;i<-dis;i++)if(a[pos].pre!=-1)pos=a[pos].pre;
		}
		else {
			for(int i=0;i<dis;i++)if(a[pos].next!=-1)pos=a[pos].next;
		}
	}
	while(a[pos].pre!=-1)pos=a[pos].pre;
	while(pos!=-1){
		cout<<a[pos].data;
		pos=a[pos].next; 
	}
	cout<<endl;
	return 0;
}

感谢大家观看,希望多多评论。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

materialistOier

我只是一名ssfoier

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值