顺序表
1. 从顺序表中是删除最小元素,并返回该元素的值空出位置由最后一位填充。
bool Delete_min(sqList &L, ElemType &value){
if(L.length<=0){
//表为空,直接返回
return false ;
}
value=L.data[0];
int pos=0;
for(int i=0;i<L.length;i++){
//找到最小值后,记录数据和位置
if(L.data[i]<value){
pos = i;
value = L.data[i];
}
}
L.data[pos]=L.data[L.length-1];
L.length--;//将最后一位填补到pos后,最后一位就不用了
return true;
}
2. 将顺序表L所有元素逆置,并要求算法空间复杂度为O(1)。
//由于限制了空间复杂度,所以不能创建新的线性表用来逆向存储
//直接设置起点和终点两个标志位,在原数组的基础上交换
void Reverse(sqList &L){
int i=0;
int j=L.length-1;
ElemType temp=0
for(;i>=j;i++,j++){
temp = L.data[i];
L.data[i] = L.data[j];
L.data[j] = temp;
//每次计算完后,i,j也要自增
}
/*只用一个变量
for(i=0;i<L.length/2;i++){
tmep = L.data[i];
L.data[i]=L.data[L.length-i-1];
L.data[L.length-i-1]=temp;
}
*/
}
3. 对长度为n的顺序表L,编写一个时间复杂度为O(n),空间复杂度为O(1)的算法,该算法删除线性表中所有的值为X的数据元素。
bool Delete_x(sqList &L, ElemType x){
//遍历每个元素,若之前无x则不动
//若前面有i个,移动i次
//移动的实现是通过差值实现的
int k=0;//通过k记录不等于x的个数,最后也是线性表的长度
for(int i=0;i<L.length;i++){
//每次i都会递增,如果x=data[i],k就不会递增,也就会产生差值,也就是x的个数
if(L.data[i!=x]){
//当前方无x时,i=k,相当于没有移动
//当前方有x时,i!=k,他们之间的差值,就是要移动的个数
L.data[k]=L.data[i];
k++;
}
L.length = k;
}
//方法二
void del_x_2(sqList &L){
int k=0,i=0;
while(i<L.length){
if(L.data[i]=x){
k++;//k为x的个数
}
else{
L.data[i-k]=L.data[i];//直接对每个元素向前位移k位
}
i++;
}
L.length=L.length-k;
}
4. 从有序顺序表中删除其给定值s与t之间的所有元素,如果s或t不合理则退出
//由于有序,因此删除s,t之间就是将t之后的元素移动到s之后
bool del_st(sqList &L,ElemType s,ElemType t){
if(s>t||L.length==0){
//违规范围直接返回
return false
}
int i,j;
//使用i记录大于t的第一个数的位置,
for(i;i<L.length&&L.data[i]<=t;i++);
//使用j记录大于等于s的第一个数的位置
for(j;j<L.length&&L.data[j]<s;j++)
while(i<L.lenght){
L.data[j++] = L.data[i++];
}
L.length = j;
return true
}
5. 从顺序表中删除给定的s到t之间的所有元素
//与删除所有的x类似,唯一不同是判断条件
bool del_st_h(sqList &L,ElemType s,ElemType t){
int i,k=0;
if(s>t||L.length==0){
return false;
}
while(i<L.length){
if(L.data[i]<t&&L.data[i]>s){
//计算出有多少个差值
//用于接下来的位移
k++;
}
else{
//类似于之前的删掉所有x
L.data[i-k]=L.data[i];
}
i++;
}
L.length -=k;
return true;
}
6. 从有序表中删除所有重复的元素
//审好题,是有序表,因此重复的都堆在一起了
//如果该表是无序的,就应使用散列表
bool delete_Same(sqList &L){
if(L.length==0){
return false;
}
for(i=0,j=1;j<L.length;j++){
if(L.data[i]!=L.data[j]){
L.data[++i]=L.data[j];
//++i也可在if内写成i++;总之重复的元素个数就是j-i
//通过i,j的差值来实现在遍历的同时移动到对应的位置
}
}
L.length = i+1;
return true;
}
7. 将两个有序顺序表合并为一个新的有序顺序表
bool Merge(sqList &A,sqList &B,sqList &C){
if(A.length+B.length>C.MaxSize){
return false;
}
//ABC三个顺序表各自使用自己的变量
int i=0,j=0,k=0;
while(i<A.length&&j<B.length){
if(A.data[i]<=B.data[j]){
C.data[k++]=A.data[i++];
}
else{
c.data[k++]=B.data[j++];
}
}
//当一个表都添加完后,剩余的直接全部加到c的末尾即可
while(i<A.length){
C.data[k++] = A.data[i++];
}
while(i<B.length){
C.data[k++] = B.data[j++];
}
C.length = k;
return true;
}
8. 将数组A[m+n] (a1,,,am,b1...bn)转换为(b1...bn,a1...am)
//三次逆置即可,先整体逆置,然后将b部分逆置,最后a部分逆置即可
//传参数注意不要出错即可
typedef int DataType;
void Reverse(DataType A[] ,int left,int right,int arraySize){
if(left>=right||right>=arraySize)
return ;
int mid = (left+right)/2;
for(int i=0;i<mid-left;i++){
DataType temp = A[left+i];
A[Left+i] = A[right-i];
A[right-i] = temp;
}
}
void Exchange(DataType A[],int m,int n,int arraySize){
Reverse(A,0,m+n-1,arraySize);
Reverse(A,0,n-1,arraySize);
}
9. 折半查找
//注意折半查找的条件是有序
void search(ElemType A[],ElemType x){
int low =0,high=n-1,mid;
while(low<high){
mid = (low+high)/2;
if(A[mid]==x){
break;
}
else{//折半
if(A[mid]<x){
low = mid+1;
}
else{
high=mid-1;
}
}
}
}