链表(linked list)
链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。
链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。
每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。
相比于线性表顺序结构,操作复杂。由于不必须按顺序存储,链表在插入的时候可以达到 Θ ( 1 ) \Theta(1) Θ(1) 的复杂度,比另一种线性表顺序表快得多,但是查找一个节点或者访问特定编号的节点则需要 Θ ( n ) \Theta (n) Θ(n)的时间,而线性表和顺序表相应的时间复杂度分别是 Θ ( l o g n ) \Theta (logn) Θ(logn)和 Θ ( 1 ) \Theta(1) Θ(1)。
使用链表结构可以克服数组链表需要预先知道数据大小的缺点,链表结构可以充分利用计算机内存空间,实现灵活的内存动态管理。
但是链表失去了数组随机读取的优点,同时链表由于增加了结点的指针域,空间开销比较大。
单链表
指针写法:
#include <bits/stdc++.h>
struct Node //节点,指链表的节点
{
int data; //当前数据
struct Node *pnext; //邻接指针
};
struct Node* head;
struct Node *GetPOS(int pos)
{
Node *pTemp = head;
for(int i=2;i<pos;++i)//从head后面开始,相当于从第二个开始,然后第二个位置,是在第一个位置之前的
{
pTemp = pTemp->pnext;
}
return pTemp;
}
void Insert(int pos,int x)
{
Node *p, *pTemp = GetPOS(pos);
p = (struct Node*)malloc(sizeof(struct Node));
p->data = x;//赋值
p->pnext = pTemp->pnext;//插入结点指向当前结点的后继
pTemp->pnext = p;//当前结点指向插入结点
pTemp = pTemp->pnext;
}
void Delete(int pos)
{
Node *p1 = GetPOS(pos),*p2 = GetPOS(pos+2);
p1->pnext = p2;
}
struct Node* creat()
{
struct Node* phead, * pend, * pnew;
pend = phead = pnew = (struct Node*)malloc(sizeof(struct Node));
printf("请输入数据,结束的时候输入0\n");
while (scanf("%d",&pnew->data) && pnew->data != 0)
{
pnew = (struct Node*)malloc(sizeof(struct Node));
if(phead == NULL) {phead = pnew;}
pend->pnext = pnew; //当前的尾指针指向新指针
pnew->pnext = NULL;
pend = pnew; //新指针顶替尾指针
}
pnew = (struct Node*)malloc(sizeof(struct Node));
free(pnew);
return phead;//返回头指针
}
void Print(struct Node* p)
{
struct Node* pTemp = p;
int iIndex = 1;
printf("\n");
while (pTemp->pnext != NULL)//这边应该是pTemp->pnext,不然它多执行一次
{
printf("the NO.%d member is:\n", iIndex);
printf("the number is: %d\n", pTemp->data);
printf("\n");
pTemp = pTemp->pnext;
++iIndex;
}
}
int main()
{
head = creat();
int m; scanf("%d",&m);
for(int i=1;i<=m;++i)
{
int type,pos,val;
scanf("%d%d",&type,&pos);
if(type == 1)
{
printf("%d",GetPOS(pos+1)->data );
}
else if(type == 2)
{
scanf("%d",&val);
Insert(pos,val);
}
else if(type == 3)
Delete(pos);
}
printf("输出\n");
Print(head);
return 0;
}
数组写法:
#include <bits/stdc++.h>
#define MAXN 10000
using namespace std;
int Head=0;int n;
int nxt[MAXN],value[MAXN];
int GETPOS(int pos)//获得位置
{
int hd=Head;
for(int i=1;i<=pos;++i)
{
hd=nxt[hd];
}
return hd;
}
void Insert_value(int pos,int val)//插入
{
int p=GETPOS(pos-1);
value[++n]=val;
nxt[n]=nxt[p];
nxt[p]=n;
}
void Delete_value(int pos)//删除
{
int p=GETPOS(pos-1);
nxt[p]=nxt[ nxt[p] ];
}
void Print()
{
int pos=Head;
for(int i=1;i<=n;++i)
{
pos=nxt[pos];
printf("%d ",value[pos]);
}
}
int main()
{
int m;
scanf("%d",&n);
//输入链表的长度n
for(int i=1;i<=n;++i)
{
scanf("%d",&value[i]);
//分别输入对应的值
nxt[i-1]=i;
}
scanf("%d",&m);
//输入操作的次数
for(int i=1;i<=m;++i)
{
int type,pos,val;
scanf("%d%d",&type,&pos);
if(type == 1) printf("%d\n",value[ GETPOS(pos) ]);
else if(type == 2)
{
scanf("%d",&val);
Insert_value(pos,val);
}
else if(type == 3)
Delete_value(pos);
}
Print();
return 0;
}
(手写了这么久感觉不如vector。)