学习笔记:单链表(数组模拟)

AcWing 826. 单链表

实现一个单链表,链表初始为空,支持三种操作:

(1) 向链表头插入一个数;

(2) 删除第k个插入的数后面的数;

(3) 在第k个插入的数后插入一个数

现在要对该链表进行M次操作,进行完所有操作后,从头到尾输出整个链表。

注意:题目中第k个插入的数并不是指当前链表的第k个数。例如操作过程中一共插入了n个数,则按照插入的时间顺序,这n个数依次为:第1个插入的数,第2个插入的数,…第n个插入的数。

输入格式
第一行包含整数M,表示操作次数。

接下来M行,每行包含一个操作命令,操作命令可能为以下几种:

(1) “H x”,表示向链表头插入一个数x。

(2) “D k”,表示删除第k个插入的数后面的数(当k为0时,表示删除头结点)。

(3) “I k x”,表示在第k个插入的数后面插入一个数x(此操作中k均大于0)。

输出格式
共一行,将整个链表从头到尾输出。

数据范围
1≤M≤100000
所有操作保证合法。

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#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
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;

//头结点 head ,数据域 e ,指针域 ne 
int head,e[N],ne[N];
int idx; //idx是当前可用节点编号 

void init() //初始化 
{
	head=-1; //-1表示空节点 ( head-->空 )
	idx=0; //编号从0开始 
}

void add_to_head(int x) //向链表头插入x 
{
	e[idx]=x; //将x放到第idx个节点的数据域 
	ne[idx]=head; //x的指针域指向头结点指向的位置 
	head=idx++; // 最后让头结点指向idx 
}

void add(int k,int x) // 在第k个数后面插入一个数x 
{
	e[idx]=x; //将x放到第idx个节点的数据域 
	ne[idx]=ne[k]; //x的指针域指向k节点指向的位置 
	ne[k]=idx++; //k节点指向x 
}

void remove(int k) //将k节点后面的节点删除 
{
	ne[k]=ne[ne[k]]; // k节点的指针域指向它后面的节点指向的位置 
}

int main()
{
	int m;	cin>>m;
	init(); //先初始化 
	char op; int x,k;
	while(m--)
	{
		cin>>op;
		if(op=='H')
		{
			cin>>x;
			add_to_head(x);
		}
		else if(op=='D')
		{
			cin>>k;
			if(k==0)	head=ne[head]; //k=0时 删除头结点 
			else remove(k-1); //因为编号是从0开始的,第k个插入的编号其实是k-1 
		}
		else
		{
			cin>>k>>x;
			add(k-1,x);
		}
	}
	//遍历链表 
	for(int i=head;i!=-1;i=ne[i]) //从 head 遍历到 -1 
		cout<<e[i]<<" ";
		
	return 0; 
}

你可能感兴趣的:(笔记)