研究ノート:二重リンクリスト(配列シミュレーション)

AcWing827。二重リンクリスト

二重リンクリストを実現します。二重リンクリストは最初は空で、次の5つの操作をサポートします。

(1)左端に数字を挿入します。

(2)右端に数字を挿入します。

(3)k番目に挿入された番号を削除します。

(4)k番目に挿入された数字の左側に数字を挿入します。

(5)k番目に挿入された数字の右側に数字を挿入します

次に、リンクリストに対してM個の操作を実行する必要があります。すべての操作が完了すると、リンクリスト全体が左から右に出力されます。

注:タイトルに挿入されたk番目の番号は、現在のリンクリストのk番目の番号を参照していません。たとえば、操作中に合計n個の番号が挿入されます。挿入の時系列によれば、n個の番号は、最初に挿入された番号、2番目に挿入された番号、... n番目に挿入された番号です。

入力形式
最初の行には、演算の数を表す整数Mが含まれています。

次のM行、各行には操作コマンドが含まれています。操作コマンドは次のとおりです。

(1)「Lx」は、リンクリストの左端に数字xを挿入することを意味します。

(2)「Rx」は、リンクリストの右端に数字xを挿入することを意味します。

(3)「Dk」は、k番目に挿入された番号を削除することを意味します。

(4)「ILkx」とは、k番目に挿入された数字の左側に数字を挿入することを意味します。

(5)「IRkx」とは、k番目に挿入された数字の右側に数字を挿入することを意味します。

出力形式は
1行で、リンクリスト全体が左から右に出力されます。

データ範囲
1≤M≤100000
すべての操作が合法であることが保証されています。

#include<cstdio>
#include<cmath>
#include<ctime>
#include<cstring>
#include<iostream>
#include<map>
#include<set>
#include<stack>
#include<queue>
#include<string>
#include<vector>
#define ll long long
#define ull unsigned long long
#define up_b upper_bound
#define low_b lower_bound
#define m_p make_pair
#define mem(a) memset(a,0,sizeof(a))
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define inf 0x3f3f3f3f
#define endl '\n'
#include<algorithm>
using namespace std;

inline ll read()
{
    
    
	ll x=0,f=1; char ch=getchar();
	while(ch<'0'||ch>'9')	{
    
     if(ch=='-') f=-1; ch=getchar(); }
	while('0'<=ch&&ch<='9')	x=x*10+ch-'0', ch=getchar();
	return f*x;
}

const int N = 1e5+5;

//l左指针, r右指针 
int idx,e[N],l[N],r[N];

void init()
{
    
    
	r[0]=1; l[1]=0; //0为左端点,1为右端点 
	idx=2; //编号从2开始 
}

void insert(int k,int x) //在节点 k的右边插入一个数 x
{
    
    
	e[idx]=x; l[idx]=k; r[idx]=r[k]; // idx的左边指向  k,右边指向 k 向右指向的位置 
	l[r[k]]=idx; // k右边的节点向左指向idx 
	r[k]=idx++; // k向右指向idx 
}

void remove(int k) //删除 k节点 
{
    
    
	l[r[k]]=l[k]; //k右边的节点向左指向 k向左指向的位置 
	r[l[k]]=r[k]; //k左边的节点向右指向 k向右指向的位置 
}

int main()
{
    
    
	init();
	int m;	cin>>m;
	string op; int x,k;
	while(m--)
	{
    
    
		cin>>op;
		if(op=="L")
		{
    
    
			cin>>x;
			insert(0,x);
		}
		else if(op=="R")
		{
    
    
			cin>>x;
			insert(l[1],x);
		}
		else if(op=="D")
		{
    
    
			cin>>k;
			remove(k+1); //因为编号idx是从2开始的 
		}
		else if(op=="IL")
		{
    
    
			cin>>k>>x;
			insert(l[k+1],x); //在 k节点的左侧插入x 相当于 在 k左边节点的右侧插入x 
		}
		else if(op=="IR")
		{
    
    
			cin>>k>>x;
			insert(k+1,x);
		}
	}
	for(int i=r[0];i!=1;i=r[i])	cout<<e[i]<<" ";cout<<endl; // 从左到右输出
//	for(int i=l[1];i!=0;i=l[i])	cout<<e[i]<<" ";cout<<endl; // 从右到左输出
	return 0;
}

おすすめ

転載: blog.csdn.net/m0_50815157/article/details/113485719