1、从顺序表中删除具有最小值的元素(假设唯一)并由函数返回被删除元素的值。空出的位置由最后一个元素填补,若顺序表为空则显示出错信息并退出运行。
//表为空显示出错并退出。查找最小值元素,记住最小值的值和位序,删除最小值并用最后一个值填补
bool Del_Min(sqList &L,ElemType &value){
if(L.length==0)
return false;
value=L.data[0];
int pos=0;
for(int i=1;i<L.length;i++)
if(L.data[i]<value){
value=L.data[i];
pos=i;
}
L.data[pos]=L.data[L.length-1];
L.length--;
return true;
}
2、设计一个高效算法,将顺序表L的所有元素逆置,要求算法的空间复杂度为O(1)
//for循环遍历,扫描前半部分L.length/2,用L.data[L.length-1-i]替换L.length[i]
void Reverse(SqList &L){
Elemtype temp;
for(i=0;i<L.length/2;i++){
temp=L.data[i];
L.data[i]=L.data[L.length-1-i];
L.data[L.length-1-i]=temp;
}
}
3、对长度为n的顺序表L,编写一个时间复杂度为O(n)、空间复杂度为O(1)的算法,该算法删除线性表中所有值为x的数据元素。
解法一:循环遍历所有元素,统计不等于x的元素k,最后将不等于x的元素L.data[i]赋值于L.data[k]
void del_x_1(SqList &L,ElemType x){
int k=0;
for(i=0;i<L.length;i++)
if(L.data[i]!=x){
L.data[k]=L.data[i];
k++
}
L.length=k;
}
解法二:循环遍历与x相等的元素个数k,将不等于x的元素向前移动k个位置
void del_x_2(SqList &L,ElemType x){
int k=0,i=0;
while(i<L.length){
if(L.data[i]==x)
k++;
else
L.data[i-k]=L.data[i];
i++;
}
L.length=L.length-k;
}
4、从有序顺序表中删除其值在给定值s与t之间(要求s<t)的所有元素,如果s或t不合理或顺序表为空,则显示错误信息并退出运行。
4//检测s>t或顺序表为空,返回return false;
for循环遍历,寻找大于等于s的第一个元素,再寻找大于t的第一个元素(最后一个删除的元素的下一个元素)
将属于s与t之间元素删除,顺序表往前移动
bool Del_s_t2(SqList &L,ElemType s,ElemType t){
int i,j;
if(s>=t||L.length==0)
return false;
for(i=0;i<L.length&&L.data[i]<s;i++)//确定s之前的元素
if(i>=L.length)
return false;
for(j=i;j<L.length&&L.data[j]<=t;j++)//最后一个t
for(;j<L.length;i++,j++)
L.data[i]=L.data[j];//前移
L.length=i;
return true;
}
5、从顺序表中删除其值在给定值s与t之间(包含s和t,要求s<t)的所有元素,如果s或t不合理或顺序表为空,则显示出错信息并退出运行
如果s>=t或为空显示出错,扫描L,s与t之间元素为k个,不在s与t之间的元素前移k个位置,否则执行k++
bool Del_s_t(SqList &L,ElemType s,ElemType t){
int i,k=0;
if(L.length==0||s>=t)
return false;
for(i=0;i<L.length;i++){
if(L.data[i]>=s&&L.data[i]<=t)
k++;
else
L.data[i-k]=L.data[i];
}
L.length-=k;
return true;
}
6、从有序表中删除所有其值重复的元素,使表中所有元素的值均不同
是有序表,相同元素在连续的位置上,
bool Delete_Same(SeqList &L){
if(L.length==0)
return false;
int i,j;
for(i=0,j=1;j<L.length;j++)
if(L.data[i]!=L.data[j])
L.data[++i]=L.data[j];
L.length=i+1;
return true;
}
7、将两个有序顺序表合并成为一个新的有序顺序表,并由函数返回结果顺序表
//按顺序取下两个顺序表表头较小的结点存入新的顺序表,然后看哪个表还有剩余,将剩下的部分加到新的顺序表之后。
经典题
bool Merge(SeqList A,SeqList B,SeqList &C){
if(A.length+B.length>C.maxSize)
return false;
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++];
}
while(i<A.length)
C.data[k++]=A.data[i++];
while(j<B.length)
C.data[k++]=B.data[j++];
C.length=k;
return true;
}
8、
先将数组的全部元素逆置,再对前n个元素和后m个元素分别使用逆置算法
typedef int DataType;
void Reverse(DataType A[],int left,int right,int arraySize){
if(left>=rigth||rigth>=arraySize)
return;
int mid=(left+rigth/2);
for(int i=0;i<=mid-left;i++){
Datatype temp=A[left+i];
A[left+i]=A[rigth-1];
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);
Reverse(A,n,m+n-1,arraySize);
}
9、
折半查找,查找,交换,插入
void SearchExchangeInsert(ElemType A[],ElemType x){
int low=0,high=n-1,mid;
while(low<=high){
mid=(high+low)/2;
if(A[mid]==x)break;
else if(A[mid]<x)low=mid+1;
else high=mid-1;
}
if(A[mid]==x&&mid!=n-1){
t=A[mid];A[mid]=A[mid+1];A[mid+1]=t;
}
if(low>high){
for(i=n-1;i>high;i--)
A[i+1]=A[i];
A[i+1]=x;
}
}
10.设将n(n>1)个整数存放到一维数组R中,设计一个算法,将R中的序列循环左移P(0<P<n)个位置,即将R中的数据由{X0,X1,…,Xn-1}变换为{Xp,Xp+1,…,Xn-1,X0,X1,…,Xp-1}
void Reverse(int R[],int from,int to){
int i,temp;
for(i=0;i<(to-from+1)/2;i++){
temp=R[from+i];R[from+i]=R[to-i];R[to-i]=temp;
}
}
void Converse(int R[],int n,int p){
Reverse(R,0,p-1);
Reverse(R,p,n-1);
Reverse(R,0,n-1);
}
11、一个长度为L (L>=1)的升序序列S,处在第[L/2]个位置的数称为S的中位数。例如,若序列S1=(11, 13, 15, 17, 19),则S1的中位数是15,两个序列的中位数是含它们所有元素的升序序列的中位数。例如,若S2= (2, 4,6,8, 20),则S1和S2的中位数是11。现在有两个等长升序序列A和B,试设计一个在时间和空间两方面都尽可能高效的算法,找出两个序列A和B的中位数。
(次优)(次优是考研的优先选择,只扣一分且易懂)
//数列a,b元素个数len相同,比较len-1次
int findmid2 ( int* a, int* b, int len ) {
int i = 0, j = 0, k = 0;
for ( ; k < len-1; k++ ) {
if ( a[i] < b[j] ) {
i++;
}
else {
j++;
}
}
return (a[i] < b[j])? a[i]: b[j];
}
时间复杂度O(n),空间复杂度O(1)
12、
已知一个整数序列A=(a0,a1,…,an-1),其中0≤ai<n(0≤i<n)。若存在ap1=ap2=…=apm=x且m>n/2(0≤pk<n,1≤k≤m),则称x为A的主元素。例如A=(0,5,5,3,5,7,5,5),则5为主元素;又如A=(0,5,5,3,5,1,5,7),则A中没有主元素,假设A中的n个元素保存在一个一维数组中,请设计一个尽可能高效的算法,找出A的主元素。若存在主元素,则输出该元素;否则输出-1。
(次优)
#include"head.h";
int main(){
int n;
printf("请输入数组长度:");
scanf_s("%d", &n);
int counter[100];//申请一个计数的数组,该数组是计量每个数的重复次数
for (int i = 0; i < n; i++) {
counter[i] = 0;//初始化计数数组
}
int s[100];
printf("请输入数组元素:");
for(int j=0;j<n;j++){ //核心
scanf_s("%d",&s[j]);
counter[s[j]]++;
}
int p= 1;
for(int i=0;i<n;i++){
if (counter[i] > n / 2) {
p = 0;
printf("主元素为%d", i);
break;
}
}
if (p)
printf("-1\n");
return 0;
}
13、给定一个含n(n≥1)个整数的数组,请设计一个在时间上尽可能高效的算法,找出数组中未出现的最小正整数。例如,数组{-5, 3, 2, 3}中未出现的最小正整数是1;数组{1, 2, 3}中未出现的最小正整数是4。
int findMissMin(int A[],int n){
int i,*B;
B=(int *)malloc(sizeof(int)*n);
memset(B,0,sizeof(int)*n);
for(i=0;i<n;i++)
if(A[i]>0&&A[i]<=n)
B[A[i]-1]=1;
for(i=0;i<n;i++)
if(B[i]==0)break;
return i+1;
}