指针版:
用到malloc动态开组,平时做项目可以用,打比赛算了
#include <stdio.h>
#include <stdlib.h>
#include<iostream>
using namespace std;
struct list{
int num;
struct list *next;
};
struct list* p;
struct list* pm;//head
typedef struct list list_single;
list *creat_list_tail(int n){
//尾插法创建一个链表,并返回一个头指针
int i=0;
list *head,*rear,*node;
head=(list *)malloc(sizeof(list));
rear=head;
for(;i<n;i++){
node=(list *)malloc(sizeof(list));
node->num=i+1;//这里值需要变通
rear->next=node;
rear=node;
}
rear->next=NULL;
head->num=n;
return head;
}
void list_delete_val(list_single *list,int val){
list_single *pre,*temp;
while(list!=NULL){
pre=list;//记录现在的节点,链表头指针没使用数据域,因此可以从头指针后一个节点开始查询
temp=list->next;//查询的事当前节点指向下一个节点的值
if(temp==NULL){
printf("没找到相关节点val=%d\n",val);
return;
}
if(temp->num==val){
pre->next=temp->next;
free(temp); //删除后记得释放内存!
return;
}
list=list->next;
}
}
void list_insert(list_single *list,int i,int x){
list_single *target = (list_single *)malloc(sizeof(list_single));
list_single *pre;
int num=0;
target->num=x;
if(i<0){
printf("位置输入错误\n");
return ;
}
while(list!=NULL){
//在最后一个位置和第一个位置特殊处理
if(list->next==NULL) {
printf("这是最后一个位置\n");
list->next=target;
target->next=NULL;
return;
}
else if(i==0){
pre=list->next;
printf("这是第一个位置\n");
list->next=target;
target->next=pre;
return;
}
if(num==i){
pre=list->next;
list->next=target;
target->next=pre;
break;
}
num++;
list=list->next;
}
}
int main(){
int n;
cout<<"输入链表长度:";
cin>>n;
p =creat_list_tail(n);
pm=p;
while (pm->next != NULL){
printf("%-5d", pm->next->num);
pm = pm->next;
}
printf("\n");
printf("在第0位插入424:\n");
list_insert(p,0,424);
pm=p;
while (pm->next != NULL){
printf("%-5d", pm->next->num);
pm = pm->next;
}
printf("\n");
printf("删除为5的数字:\n");
list_delete_val(p,5);
pm=p;
while (pm->next != NULL){
printf("%-5d", pm->next->num);
pm = pm->next;
}
printf("\n");
}
普通版,用结构体+node一维数组
这个版本带了左右插入与删除,但我觉得可以直接用
原题是洛谷P1160:
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
struct node{
int L, R;
}a[100003];
int n, m;
inline void addRight(int x, int pos) { //插入右边
a[x].L = pos;
a[a[pos].R].L = x;
a[x].R = a[pos].R;
a[pos].R = x;
}
inline void addLeft(int x, int pos) { //插入左边
a[x].R = pos;
a[a[pos].L].R = x;
a[x].L = a[pos].L;
a[pos].L = x;
}
inline void del(int x) {
if(a[x].L == -1) return;
a[a[x].L].R = a[x].R;
a[a[x].R].L = a[x].L;
a[x].L = -1;
a[x].R = -1;
}
inline void go() {
int x = a[0].R;
while(1) {
cout<<x<<" ";
if(a[x].R == -1) break;
x = a[x].R;
}
}
inline void init() {
for(int i = 1; i <= n; ++i) a[i].L = a[i].R = -1;
a[1].R = -1; a[1].L = 0; a[0].R = 1;
}
int main() {
scanf("%d", &n);
int cmd1, cmd2;
init();
for(int i = 2; i <= n; ++i) {
scanf("%d %d", &cmd1, &cmd2);
if(!cmd2) addLeft(i, cmd1);
else addRight(i, cmd1);
}
scanf("%d", &m);
for(int i = 1; i <= m; ++i) {
scanf("%d", &cmd1);
del(cmd1);
}
go();
return 0;
}
这里一个有意思的点,说到删除有的时候没必要真的删除,设为隐藏什么之类的可以减少操作。
STL版:题解 P1160 【队列安排】 - Orina_zju 的博客 - 洛谷博客
list<int> myList;
myList.push_front(1);
myList.push_back(2);
//对应地,pop_front()用于移除头部的元素,pop_back()用于移除尾部的元素。
typedef list<int>::iterator Iter;
Iter itBegin = myList.begin();
Iter itEnd = myList.end();
for (; itBegin != itEnd; ++itBegin)
printf(" %d", *itBegin);
这段的下半部分代码演示的是list提供的,用于访问内部元素的迭代器。迭代器的类型是list<Tp>::iterator(这里模板参数Tp需要与你操作的链表一致)。迭代器的用法和指针有些像,可以用*运算符访问内部的元素,++和--运算符可以将它后移或前移一位(建议写成前置形式),
用==和!=运算符进判断两个迭代器所指的位置是否一致。但要注意:list的迭代器不支持it += x或it1 - it2这样的运算,也不支持<,<=等运算符。
begin()成员函数返回指向头部元素的迭代器。end()成员函数返回指向末尾位置的迭代器。这个“末尾位置”指的是最后一个元素再往后一位,也就是说end()所指的位置不包含有效元素,它相当于一个虚设的节点。这样设计是为了满足C++标准库表示区间时左闭右开的惯例。
insert(it, val)成员函数用于在链表中插入元素。it为该链表的一个迭代器,val为待插入的值,插入后val位于it所指位置的前一位。返回值为一个迭代器,表示val插入到了哪个位置。remove(it)成员函数用于删除某个迭代器所指的节点。注意在删除之后it就失效了,除非给it重新赋值,否则对它的任何操作都会导致错误!remove(val)用于移除所有值为val的节点
#include <cstdio>
#include <list>
using namespace std;
using Iter = list<int>::iterator;//自定义了哈
const int maxN = 1e5 + 10;
Iter pos[maxN];
list<int> queList;
bool erased[maxN];//这里懒得删除了,直接标记了
int N;
void buildQueue(){
queList.push_front(1);
pos[1] = queList.begin();
for (int i = 2; i <= N; i++){
int k, p;
scanf("%d%d", &k, &p);
if (p == 0)pos[i] = queList.insert(pos[k], i); //left
else{
auto nextIter = next(pos[k]);
pos[i] = queList.insert(nextIter, i); //right
}
}
int M;
scanf("%d", &M);
for (int x, i = 1; i <= M; i++){
scanf("%d", &x);
if (!erased[x])queList.erase(pos[x]);
erased[x] = true;
}
}
int main(){
scanf("%d", &N);
buildQueue();
bool first = true;
for (int x:queList){
if (!first)putchar(' ');
first=false;
printf("%d",x);
}
putchar('\n');
return 0;
}