AcWing 826. 单链表

发布时间 2023-12-04 11:26:58作者: 爬行的蒟蒻

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

  1. 向链表头插入一个数;
  2. 删除第 k 个插入的数后面的数;
  3. 在第 k 个插入的数后插入一个数。

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

原题链接:826. 单链表 - AcWing

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

const int N = 100005;
int e[N];	//数据数组
int ne[N];	//指向下一个节点的指针数组
int head, cnt;	//头结点的位置与计数器

void init() {
	head = -1;	//头结点指向-1,代表没有内容
}

void headAdd(int x) {
	e[cnt] = x;	//将第一个数据结点值存入数据数组
	ne[cnt] = head;	//更新最后一个结点为头结点
	head = cnt++;	//头结点位置后移
}

void deleteNode(int k) {
	if (k == -1)
		head = ne[head];	//将头结点的下一个值赋给头结点,即删除头结点
	else
		ne[k] = ne[ne[k]];
}

void indexAdd(int k, int x) {
	e[cnt] = x;	//加入插入的数据
	ne[cnt] = ne[k];
	ne[k] = cnt++;	//k所在位置的下一个结点即是第k+1个插入的数
}

void printList() {
	for (int i = head; i != -1; i = ne[i])
		cout << e[i] << " ";
	cout << endl;
}

int main()
{
	int m;
	cin >> m;
	init();
	while (m--) {
		char op;
		int k, x;
		cin >> op;
		switch (op) {
		case'H':
			cin >> x; 
			headAdd(x); 
			break;
		case'D':
			cin >> k; 
			deleteNode(k - 1);
			break;
		case'I':
			cin >> k >> x; 
			indexAdd(k - 1, x);
			break;
		}
	}
	printList();
	return 0;
}

Q:为什么不使用链表而是使用顺序表?
A:链表会在每一次关于k的操作时,都通过遍历寻找k,时间复杂度太高

//惨遭TLE的链表写法
int cnt = 1;

struct Node {
	int data;
	int No;
	Node* next;
};
typedef Node* LinkList;

void init(LinkList& L) {
	L = new Node;
	L->next = NULL;;
	L->No = NULL;;
}

void headAddList(LinkList& L, int x) {
	LinkList p = new Node;
	p->data = x;
	p->next = L->next;
	L->next = p;
	p->No = cnt++;
}

void deleteList(LinkList& L, int k) {
	if (!k) {
		LinkList p = L->next;
		L = p;
	}
	else {
		LinkList p = L->next;
		while (p && p->next && p->No != k)
			p = p->next;
		LinkList tmp = p->next;
		p->next = p->next->next;
		delete tmp;
	}
}

void indexAddList(LinkList& L, int k, int x) {
	LinkList pre = L;
	while (pre && pre->next && pre->No != k)
		pre = pre->next;
	LinkList p = new Node;
	p->data = x;
	p->next = pre->next;
	pre->next = p;
	p->No = cnt++;
}

void printList(LinkList& L) {
	LinkList p = L->next;
	while (p) {
		cout << p->data << " ";
		p = p->next;
	}
	cout << endl;
}

int main()
{
	int m;
	cin >> m;
	LinkList L;
	init(L);
	while (m--) {
		char op;
		int k, x;
		cin >> op;
		switch (op) {
		case'H':
			cin >> x; 
			headAddList(L, x); 
			break;
		case'D':
			cin >> k; 
			deleteList(L, k); 
			break;
		case'I':
			cin >> k >> x; 
			indexAddList(L, k, x); 
			break;
		}
	}
	printList(L);
	return 0;
}