问题描述:已知长度为n的线性表A采用顺序存储结构,设计一时间复杂度为0(n)、空间复杂度为0(1)的算法,该算法删除线性表中所有值为item的数据元素。要求:线性表元素个数n很大,而值为item的数据元素个数很少,要求移动元素个数尽量少;删除后的数组元素与原数组元素不必保持顺序一致。
话不多说,直接上代码,代码中有注释。
#include<iostream>
#include<vector>
#include<algorithm>
#include<sstream>
using namespace std;
template<class ElemType>
void getData(vector<ElemType> &vec);
template<class ElemType>
void deleteItem(vector<ElemType> &vec,ElemType &Item);
template<class ElemType>
void printProcess(vector<ElemType> const &vec);
int main(){
int num;
cin>>num;//输入顺序表大小
vector<string> vec(num);//这里姑且认为数据为字符串型,可以更改为其他类型
getData(vec);
string item;
cin>>item;
printProcess(vec);
cout<<endl<<endl;
deleteItem(vec,item);
printProcess(vec);
return 0;
}
//读入数据
template<class ElemType>
void getData(vector<ElemType> &vec){
int len=vec.size();
for(int i=0;i<len;++i){
cin>>vec[i];
}
}
//核心代码,用双指针法
template<class ElemType>
void deleteItem(vector<ElemType> &vec,ElemType &item){
int len=vec.size();
//i和j分别从前和后遍历i指针找等于item的元素的下标,j找不等于item的元素的下标
int i=0,j=len;
for(i=0;i<len;++i){
if(vec[i]==item){
j=j-1;
while(vec[j]==item){//从后往前找不等于item的元素的下标
--j;
}
if(j<=i)//如果j和i相遇说明已经将所有值为item的元素移动到顺序表末端
break;
swap(vec[i],vec[j]);//交换i和j所指元素的值
}
}
vec.resize(i);//更新删除完毕的顺序表的大小
}
//打印结果
template<class ElemType>
void printProcess(vector<ElemType> const &vec){
int len=vec.size(),i;
for(i=0;i<len;++i){
cout<<vec[i]<<' ';
}
if(len==0)cout<<"empty";
}
利用双指针法,分别从两端遍历顺序表,控制时间复杂度为O(n),空间复杂度为O(1)。