数组仿真链表的优化
2018-03-15 10:48
351 查看
数组仿真链表的优化
在最初数组仿真链表的优化中,每次加入一个新值都要在数组当中寻找一个空位来储存数据,这样会有一个问题,就是当链表中加入n个元素时,每一次都会用线性的时间复杂度去寻找空位,造成了很大时间上的浪费,因此需要进行优化。
用一个堆栈记录所有没有被加入到链表中的数组元素下标,栈的元素可以初始化为1...MAXN-1,以方便使用。每次对链表进行删除操作时,再将删除的数组元素所对应的数组下标入栈,下次再添加新元素进链表时,只需去处栈顶的数组下标即可,因为这个下标对应的数组显然是空的。
这个优化方法将O(n)寻找空位的过程直接变成了O(1)。#include<iostream>
#define MAXN 100001
using namespace std;
int linklst_data[MAXN];
int linklst_point[MAXN];
int stack[MAXN]; //用于记录没有加入链表的数组下标的栈
int head=-1; //链表的头指针
int stack_head=0; //栈顶指针
void del_by_data(int del_data) //删除一个含有del_data的元素
{
int p=head,pre=-1; //从头开始遍历链表
while(p!=-1)
{
if(linklst_data[p]==del_data) //找到要删除的值,进行删除操作
{
if(p==head) //如果删除的是头指针,则更新头指针
head=linklst_point[head];
else //这个else等同于if(pre!=1),因为当P!=head时p前面已经有元素了
linklst_point[pre]=linklst_point[p];
linklst_data[p]=-1; //删除p指向元素的值
linklst_point[p]=-1;
stack[--stack_head]=p; //将删除元素的下标入栈
return ;
}
pre=p;
p=linklst_point[p];
}
return ;
}
void add_front(int add_data) //在链表前段加入元素
{
int p=1;
p=stack[stack_head++]; //直接取出栈中的空位
linklst_data[p]=add_data; //将要加入的结点选好的空位赋值
linklst_point[p]=head; //将当前加入的指针指向head
head=p; //使当前的元素成为链表头指针
}
void add_rear(int add_data)
{
int p=1,pre;
p=stack[stack_head++]; //直接取出栈中的空位
linklst_data[p]=add_data; //对要加入的节点的空位进行赋值
if(head!=-1) //链表不为-1
{
pre=head; //找到链表中最后一个元素
while(linklst_point[pre]!=1)
pre=linklst_point[pre];
linklst_point[pre]=p; //当当前链表的最后一个指针指向要加入的元素
}
else //否则直接对head所指的元素赋值
head=p;
}
void output()
{
int p=head;
while(p!=-1)
{
cout<<linklst_data[p]<<" ";
p=linklst_point[p];
}
cout<<"\n";
return ;
}
void init() //初始化数组指针
{
for(int i=0; i<MAXN; i++)
{
linklst_point[i]=-1;
linklst_data[i]=-1;
stack[i]=i+1; //从1到MAXN给栈加入数组下标
}
return ;
}
int main() //演示链表的操作
{
int ins,data;
init();
while(1)
{
cout<<"1.Insert a value in front \n";
cout<<"2.Insert a value in rear \n";
cout<<"3.Delete a value \n";
cout<<"4.Quit \n";
cin>>ins;
switch(ins)
{
case 1:
cout<<"Please insert a value:";
cin>>data;
add_front(data);
break;
case 2:
cout<<"Please insert a value:";
cin>>data;
add_rear(data);
break;
case 3:
cout<<"Please insert a value:";
cin>>data;
del_by_data(data);
return 0;
}
output();
}
return 0;
}
在最初数组仿真链表的优化中,每次加入一个新值都要在数组当中寻找一个空位来储存数据,这样会有一个问题,就是当链表中加入n个元素时,每一次都会用线性的时间复杂度去寻找空位,造成了很大时间上的浪费,因此需要进行优化。
用一个堆栈记录所有没有被加入到链表中的数组元素下标,栈的元素可以初始化为1...MAXN-1,以方便使用。每次对链表进行删除操作时,再将删除的数组元素所对应的数组下标入栈,下次再添加新元素进链表时,只需去处栈顶的数组下标即可,因为这个下标对应的数组显然是空的。
这个优化方法将O(n)寻找空位的过程直接变成了O(1)。#include<iostream>
#define MAXN 100001
using namespace std;
int linklst_data[MAXN];
int linklst_point[MAXN];
int stack[MAXN]; //用于记录没有加入链表的数组下标的栈
int head=-1; //链表的头指针
int stack_head=0; //栈顶指针
void del_by_data(int del_data) //删除一个含有del_data的元素
{
int p=head,pre=-1; //从头开始遍历链表
while(p!=-1)
{
if(linklst_data[p]==del_data) //找到要删除的值,进行删除操作
{
if(p==head) //如果删除的是头指针,则更新头指针
head=linklst_point[head];
else //这个else等同于if(pre!=1),因为当P!=head时p前面已经有元素了
linklst_point[pre]=linklst_point[p];
linklst_data[p]=-1; //删除p指向元素的值
linklst_point[p]=-1;
stack[--stack_head]=p; //将删除元素的下标入栈
return ;
}
pre=p;
p=linklst_point[p];
}
return ;
}
void add_front(int add_data) //在链表前段加入元素
{
int p=1;
p=stack[stack_head++]; //直接取出栈中的空位
linklst_data[p]=add_data; //将要加入的结点选好的空位赋值
linklst_point[p]=head; //将当前加入的指针指向head
head=p; //使当前的元素成为链表头指针
}
void add_rear(int add_data)
{
int p=1,pre;
p=stack[stack_head++]; //直接取出栈中的空位
linklst_data[p]=add_data; //对要加入的节点的空位进行赋值
if(head!=-1) //链表不为-1
{
pre=head; //找到链表中最后一个元素
while(linklst_point[pre]!=1)
pre=linklst_point[pre];
linklst_point[pre]=p; //当当前链表的最后一个指针指向要加入的元素
}
else //否则直接对head所指的元素赋值
head=p;
}
void output()
{
int p=head;
while(p!=-1)
{
cout<<linklst_data[p]<<" ";
p=linklst_point[p];
}
cout<<"\n";
return ;
}
void init() //初始化数组指针
{
for(int i=0; i<MAXN; i++)
{
linklst_point[i]=-1;
linklst_data[i]=-1;
stack[i]=i+1; //从1到MAXN给栈加入数组下标
}
return ;
}
int main() //演示链表的操作
{
int ins,data;
init();
while(1)
{
cout<<"1.Insert a value in front \n";
cout<<"2.Insert a value in rear \n";
cout<<"3.Delete a value \n";
cout<<"4.Quit \n";
cin>>ins;
switch(ins)
{
case 1:
cout<<"Please insert a value:";
cin>>data;
add_front(data);
break;
case 2:
cout<<"Please insert a value:";
cin>>data;
add_rear(data);
break;
case 3:
cout<<"Please insert a value:";
cin>>data;
del_by_data(data);
return 0;
}
output();
}
return 0;
}
相关文章推荐
- 巧用CPU缓存优化代码:数组 vs. 链表(转)
- 巧用CPU缓存优化代码:数组 vs. 链表(转)
- [编程技巧] 巧用CPU缓存优化代码:数组 vs. 链表
- [编程技巧] 巧用CPU缓存优化代码:数组 vs. 链表
- [编程技巧] 巧用CPU缓存优化代码:数组 vs. 链表
- 巧用CPU缓存优化代码: 数组VS链表
- 巧用CPU缓存优化代码:数组 vs. 链表
- 【转载】利用CPU缓存的特性优化数据存储---数组vs链表
- 一道简单的acm题的三种解决方案(数组、单向链表、容器vector)与代码优化
- 【算法学习笔记】66. 模拟法 数组链表 报数优化 SJTU OJ 4010 谁最有耐心
- 数组仿真堆栈与链表仿真堆栈(内含数组与链表的差别)
- 数组仿真链表
- 【转】巧用CPU缓存优化代码:数组 vs. 链表
- 简单hash就是数组加链表
- 数据结构与算法(Java描述)-5、循环链表仿真链表以及循环链表应用
- 丢手帕问题(环形链表)---Java 待优化
- 紫书章六例题四 悲剧文本 UVA 11988 (用数组模拟单向链表/递归)
- C++实现队列--数组实现和链表实现
- 理解数组和链表的最基本特性
- 关于队列(数组队列,链表队列,循环队列)