您的位置:首页 > 其它

数组和链表之间的比较

2018-02-05 19:28 239 查看
数组,就是平常的a[i]什么的,相信这很简单吧.
让我们看看这个东西的效率如何.
修改1个元素,例如给第x个元素加上1:
void add(int x){
a[x]++;
}时间复杂度O(1).
查找一个元素,例如查找第x个元素:
int look(int x){
return a[x];
}时间复杂度也是O(1).
插入一个元素,例如在第x个元素后面插入y:
void ins(int x,int y){
for (int i=n+1;i>=x+2;i--) a[i]=a[i-1]; //将x后的数全部往后移一位
a[x+1]=y; //往x+1位置加入y
}时间复杂度最多O(n).
其实是O(n-x).
删除一个元素,例如删除第x个元素:
void del(int x){
for (int i=x;i<n;i++) a[i]=a[i+1]; //将x后面往前移一位,直接覆盖a[x]
}时间复杂度最多O(n).
其实是O(n-x).
接下来就是另一个线性数据结构——链表.
其实很简单,这里我们直接用数组模拟静态链表,毕竟指针容易出问题.
也就是用数组下表代替指针.
也就是说这个链表是一个数组,但e[x]的下一个元素并不是e[x+1].
e[x]的下一个元素的坐标是e[x]记录着的.
所以,e是个结构体数组...
然后又有一个e[0]永远是一个没有实际意义的开头,永远不动.
于是这是代码:
struct node{
int x; //这是数值
int next; //这是下一个元素的下标
}e[maxn];初始化怎么办,这么办:
memset(e,0,sizeof(e));接下来怎么输入元素:
void into(){
scanf("%d",&n);
for (int i=1;i<=n;i++){
scanf("%d",&e[i].x); //输入元素
e[i-1].next=i; //一开始i的下一个都是i+1
}
}真简单,真简单!
接下来是各个操作代码.
首先,查找元素数值,例如查找第x个元素:
int look(int x){
int p=0; //从开头开始扫
for (i=1;i<=x;i++) p=e[p].next; //寻找下一个元素
return e[p].x; //输出第x个元素的数值
}时间复杂度最多O(n).
其实是O(x).
接下来是查找第x个元素在e中的位置:
int look(int x){
int p=0; //从开头开始扫
for (i=1;i<=x;i++) p=e[p].next; //寻找下一个元素
return p; //输出第x个元素的位置
}其实跟查找元素的数值没什么区别,时间复杂度跟上面的一样.
不过这是下面很多东西的基础.
接下来,是给修改第x个元素,例如给第x个元素加上1:
int add(int x){
int p=0; //从开头开始扫
for (i=1;i<=x;i++) p=e[p].next; //寻找下一个元素
e[p].x++; //给数值加1
}跟上面的代码基本一样,所以时间复杂度就差不多了.
还有插入一个元素,例如在第x个元素后面加上一个数y.
思想就是给这个数y在开一个位置,然后将这个元素的下一个位置变成原来的第x个位置的元素的下一个元素的位置,然后将第x个元素的下一个位置变成给数y开的位置.
就像这样:
int ins(int x,int y){
int p=0;
for (i=1;i<=x;i++) p=e[p].next; //查找第x个元素的位置
e[++t].x=y; //给数y新开一个位置
e[t].next=e[q].next; //将y的下一个位置变成q的下一个位置
e[q].next=t; //将q的下一个位置变成y的位置
}但是不能先将q的下一个位置变成y的位置,不然会使y找不到q原来的下一个位置的.
时间复杂度不包括查找的话是常数级别的,不过一般是省略常数的,所以是O(1).
不过查找花了O(x)的时间.
接下来是删除,例如删除第x元素.
那么我们可以先找到第x-1个元素的位置,将它的next变成第x+1个元素的位置.
大概这么实现:
int ins(int x){
int p=0;
for (i=1;i<x;i++) p=e[p].next; //查找第x-1个元素的位置
e[p].next=e[e[p].next].next; //将第x-1个位置的下一个位置变成第x+1个元素的位置,e[p].next是第x个元素的位置,e[e[p].next].next就是第x+1个位置的元素
}简单吧,虽然代码有些玄学.
时间复杂度不包括查找省略常数后是O(1)的.
不过有查找还是很慢啊...
比起来,数组与链表比起来,数组查找,修改数比较快,而链表插入删除比较快.
但是链表一般是在开头插入是才用的,因为毕竟还要查找...
看起来,数组与链表各有所长啊.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: