目录
1.删顺序表中的最小值(最小值唯一,返回被删元素值,空位由最后一个位置的元素填补)
3.删除长度为n的顺序表中所有值为x的元素 空间复杂O1,时间复杂O1
4.在有序顺序表中删除s-t之间(包括s,t)要求s的所有元素,不合理的范围返回错误信息<>
5.在顺序表中删除值s-t之间(包含s,t)且s的所有元素,不合理的范围返回错误信息<>
7.将两个有序顺序表合并为一个新的有序顺序表,并由函数返回结果顺序表
8.已知在一维数组A[m+n]中依次存放两个线性表。试编写函数将两个顺序表位置互换。
9.线性表(a1..an)中元素递增有序且顺序存储,请查找值为x的元素,找到后与其后继交换位置,若找不到则将其插入表中并使表中元素仍递增有序
1.删顺序表中的最小值(最小值唯一,返回被删元素值,空位由最后一个位置的元素填补)
- 搜索整个顺序表,查找最小元素并记住其位置,搜索结束后用最后一个元素补空出的原最小值元素的位置
/*从顺序表中删除最小值(假设唯一),并返回被删元素值,空出的位置由最后一个元素填补*/
int minValue(sqlist &l,int &x){
if(l.length==0) return false;
int pos=0;
int min=L.data[0];
for(int i=0;i<L.length;i++) {
if(L.data[i]<min) {
min=L.data[i];
pos=i;
}
}
data[pos]=data[l.length-1];
L.length--;
return min;
}
2.顺序表元素逆置 要求空间复杂度O1
- 扫描顺序表的前半部 分,对于l.data[i] (0<=i<=length/2),将其与后半部分的对应元素交换,l.data[l.length-i-1]
void reverse(sqlist &l){
int i,temp;
for(i=0;i<l.length/2;i++){
temp=l.data[i];
l.data[i]=l.data[l.length-i-1];
l.data[l.length-i-1]=temp;
}
}
3.删除长度为n的顺序表中所有值为x的元素 空间复杂O1,时间复杂O1
- 用size记录顺序表中不等于x的元素个数(即需要保存的元素个数),边扫描L边统计size
- 并将不等于x的元素向前移动size个位置,最后修改l的长度
void dele_x(sqlist &l,int x){
int size=0;
for(int i=0;i<l.length;i++){
if(l.data[i]!=x) l.data[size++]=l.data[i];
}
l.length=size;
}
4.在有序顺序表中删除s-t之间(包括s,t)要求s<t的所有元素,不合理的范围返回错误信息
- 寻找值大于等于s的第一个元素(第一个删除的元素)
- 然后寻找值大于t的第一个元素(最后一个删除的元素的下一个元素)
- 要将这段元素删除,只需将后面的元素前移。
bool Delete(sqlist &l,int s,int t){
if(l.length==0||s>=t) return false;
int i,j;
for(i=0;i<l.length&&l.data[i]<s;i++);
if(i>=l.length) return flase; //>=,i找到表外面去了表长只有length-1
for(j=i;j<l.length&&l.data[j]<=t;j++);
for(;j<l.length;j++,i++){ //i++
l.data[i]=l.data[j];
}
l.length=i+1; //i+1
return true;
}
5.在顺序表中删除值s-t之间(包含s,t)且s<t的所有元素,不合理的范围返回错误信息
- 从前向后扫描顺序表L
- 用k记录下元素值在s-t之间元素的个数(初始k=0)
- 对于当前扫描的元素,若其值不再s-t之间,则前移k个位置,否则k++
bool dele_st(sqlist &l,int s,int t){
if(s>=t||l.length==0) return false;
int k=0;
for(int i=0;i<l.length;i++){
if(l.data[i]>=s||l.data[i]<=t) k++;
else l.data[i-k]=l.data[i]; //i-k,只有不再范围内的值才做赋值,不存在i<k的情况
}
l.length-=k;
return ture;
}
6.在有序表中删除所有重复值的元素(双指针)
- 有序顺序表值相同的元素一定在连续的位置上,用类似于直接插入排序的思想
- 初始时将第一个元素视为非重复的有序表,之后依次判断后面的元素是否与前面非重复有序表的最后一个元素相同
- 若相同则继续向后判断,若不同则插入到前面的非重复有序表的最后,直至判断到表尾为止
void dele_copy(sqlist &l){
int i=0,j;
for(j=i+1;j<l.length;j++){
if(l.data[j]!=l.data[i])
l.data[++i]=l.data[j]; //++i,用例子分析可以知道
}
l.length=i+1; //i+1,i是数组下标
}
7.将两个有序顺序表合并为一个新的有序顺序表,并由函数返回结果顺序表
- 首先,按顺序表不断取下两个顺序表表头较小的节点存入新的顺序表中。
- 然后,看哪个表还有剩余,将剩下的部分加到新表后面。
bool Merge(sqlist &l1,sqlist &l2,sqlist &l){ //用新表的引用就省去了定义新表的过程,也不用判断两个表的情况(一空一满)
if(l1.length+l2.length>l.length) return false; //如果新表不够装,要返回错误
int i=0,j=0,k=0; //K 必须有新变量来标记新表中的位置,i和j都在变化的不能用
while(i<l1.length&&j<l2.length){ //用while ,变量变化都在表达式里
if(l1.data[i]<=l2.data[j]) //<=,在两数相等时,也加入新表因为是不断比较的
l.data[k++]=l1.data[i++];
else l.data[k++]=l1.data[j++]; //前面已经<=了,else就是>了,不用特殊说明
}
while(i<l1.length) l.data[k++]=l1.data[i++]; //如果有剩余的就直接放进新表
while(j<l2.length) l.data[k++]=l2.data[j++];
c.length=k+1;
return true;
}
8.已知在一维数组A[m+n]中依次存放两个线性表。试编写函数将两个顺序表位置互换。
- 首先将数组的全部元素原地逆置,再对前n个元素和后m个元素分别使用逆置算法,从而实现顺序表位置互换。
- 整体求逆:(AB)逆=B逆A逆 各部分分别求逆:(B逆)逆(A逆)逆=BA
typedef int datatype; //下标都是int,只有数组中的内容可能是数字也可能是字符所以另写类型为了更好修改
void reverse(datatype A[],int left,int right,int arraysize){
if(left>=right||right>=arraysize)
return;//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,m-1,arraysize); //先总体求逆,再分别求逆
reverse(A,n,m+n-1,arraysize);
}
9.线性表(a1..an)中元素递增有序且顺序存储,请查找值为x的元素,找到后与其后继交换位置,若找不到则将其插入表中并使表中元素仍递增有序
折半查找最快
void SearchExchangeInsert(ElemType a[],int n,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;
}
if(mid!=n-1&&a[mid]==x){ //查找成功,则与后继交换
int temp=a[mid+1];
a[mid+1]=a[mid];
a[mid]=temp;
}
if(low>high){ //查找,则插入元素
for(int i=n-1;i>high;i--) a[i+1]=a[i];
a[i+1]=x;
}
}