单链表的一些基本操作
@
前言
在网上看到了很多奇奇怪怪的链表操作,不仅代码多还难以理解,给出的代码还会编译错误(也许只是小编愚钝……),后来找了很多资料,终于找到一种精简的链表,所以写一篇文章来介绍一下。
单链表的的定义
十分简单,只要定义一个头指针,尾指针就好了。
struct node{
int data;
node *next;
}*head,*p,*tail;//head头指针,tail尾指针,p用于操作
在链尾添加新节点
inline void push(int x){
p=new node;//申请一个新的空间
p->data=x;//存储数据
p->next=NULL;//最后一个节点的后继为空
tail->next=p;//接在链尾后
tail=tail->next;//链尾后移
}
在链中插入节点
设在第\(dis\)个位置后插入元素\(k\);
inline void insert(int dis,int k){
p=head->next;//因为头指针没有数据,p直接赋值为第二个节点的地址
int i=2;//i表示p是第几个节点的地址
while((p!=NULL) && (i<=dis)){//循环后p应该指向第dis个节点
//假如dis超出链表长度的话,(p!=NULL)可以防止溢出
p=p->next;
++i;
}
if(p!=NULL){//如果p非空
node *q;
q=new node;//申请新的空间
q->data=k;//赋值将被插入的数据
q->next=p->next;//将q的后继变为p的后继
p->next=q;//p的后继变为q
}
}
在链中删除节点
设删除第\(dis\)个节点
inline void del(int dis){
p=head->next;
int i=2;
while((p->next!=NULL) && (i<dis)){
p=p->next;
++i;
}//循环结束后p指向第dis-1个节点,也就是说,p的后继就是第dis个节点
if(p->next!=NULL){//如果第dis个节点非空
node *q;
q=p->next;//q暂存第dis个节点
p->next=q->next;//第dis-1个节点的后继变成第dis+1个节点
free(q);//释放第dis个节点的内存
}
}
完整操作实例
首先输入一个初始序列,直到输入\(-1\)停止,然后再输入操作指令,每条操作指令形式如\((1,a,b)\)或者\((2,x)\),第一条表示在第\(a\)元素后插入\(k\),第二条表示删除第\(x\)个元素,每次操作后程序都会输出操作后的序列。
#include<iostream>
#include<cstdlib>
#include<cstdio>
using namespace std;
struct node{
int data;
node *next;
}*head,*p,*tail;
int x,y,z;
inline void insert(int dis,int k){
p=head->next;int i=2;
while((p!=NULL) && (i<=dis)){
p=p->next;
++i;
}
if(p!=NULL){
node *q;
q=new node;
q->data=k;
q->next=p->next;
p->next=q;
}
}
inline void del(int dis){
p=head->next;int i=2;
while((p->next!=NULL) && (i<dis)){
p=p->next;
++i;
}
if(p->next!=NULL){
node *s;
s=p->next;
p->next=s->next;
free(s);
}
}
inline void push(int x){
p=new node;
p->data=x;
p->next=NULL;
tail->next=p;
tail=tail->next;
}
int main(){
scanf("%d",&x);
head=new node;
tail=head;
while(x!=-1){
push(x);
scanf("%d",&x);
}
scanf("%d",&x);
while(x!=-1){
if(x==1){
scanf("%d%d",&y,&z);
insert(y,z);
}
else{
scanf("%d",&y);
del(y);
}
p=head->next;
while(p!=NULL){
printf("%d ",p->data);
p=p->next;
}printf("\n");
scanf("%d",&x);
}
return 0;
}