1.从顺序表中删除具有最小值的元素(假设唯一)并有函数返回被删元素的值。空出的位置由最后一个元素填补,若顺序表为空则显示出错信息并退出运行。
struct ll
{
int nums[10]= {1,3,4,9,7,5,2,6,8,0};
int length=10;
int max_size=10;
int del_min()
{
if(length==0)
{
cout<<"顺序表为空"<<endl;
return -1;
}
int m = nums[0];
int p = 0;
for(int i=1; i<length; i++)
{
if(m>nums[i])
{
m=nums[i];
p=i;
}
}
nums[p]=nums[length-1];
length--;
return m;
}
} l;
3.对长度为n的顺序表L,编写一个时间复杂度为O(n)、空间复杂度为O(1)的算法,该算法删除线性表所有值为x的数据元素
int del_x(int n)
{
int k=0;
for(int i=0;i<length;i++)
{
if(nums[i]!=n)
{
nums[k]=nums[i];
k++;
}
}
length=k;
show();
}
4(5).从(有序)顺序表中删除其值在给定值s与t之间(要求s<t)的所有元素,如果s或t不合理或顺序表为空,则显示出错信息并退出运行。
void del_s_t(int s,int t)
{
if(s>=t||length==0)
cout<<"error"<<endl;
else{
int k=0;
for(int i=0;i<length;i++)
{
if(nums[i]<s||nums[i]>t)
{
nums[k]=nums[i];
k++;
}
}
length=k;
show();
}
}
6.从有序顺序表中删除所有其值重复的元素,使表中所有元素的值均为不同
void del_repeat()
{
if(length==0)
{
cout<<"顺序表为空"<<endl;
return;
}
int k=1;
int n=nums[0];
for(int i=1;i<length;i++)
{
if(nums[i]!=n)
{
n=nums[i];
nums[k]=n;
k++;
}
}
length=k;
show();
}
7.将两个有序顺序表合并为一个新的有序顺序表,并由函数返回的结果顺序表
ll union_l(ll l)
{
int temp[100];
int k=0;
int l1=0;
int l2=0;
while(l1<length&&l2<l.length)
{
if(nums[l1]<l.nums[l2])
{
temp[k]=nums[l1];
k++;
l1++;
}
else
{
temp[k]=l.nums[l2];
k++;
l2++;
}
}
if(l1<length)
{
for(int q=l1; q<length; q++)
{
temp[k]=nums[q];
k++;
}
}
if(l2<l.length)
{
for(int q=l2; q<l.length; q++)
{
temp[k]=l.nums[q];
k++;
}
}
maxsize=max(length,maxsize);
for(int i=0;i<k;i++)
{
nums[i]=temp[i];
}
length=k;
show();
return l;
}
8.已知在一维数组A[m+n]中依次存放两个线性表(a1,a2,a3,...,am)和(b1,b2,b3,...,bn)。试编写一个函数,将数组中两个顺序表的位置互换,即将(b1,b2,b3,...,bn)放在(a1,a2,a3,...,am)的前面
思路:现将整个数组倒置,再将前面长度为n的元素单独倒置,再讲后面长度为m的元素单独倒置。
灵活使用倒置很重要
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);
Reverse(A,n,m+n-1,arraySize);
}
9.线性表(a1,a2,a3,...,an)中的元素递增有序且按顺序存储与计算机内。要求设计一算法,完成用最少时间在表中查找数值为x的元素,若找到则将其与后继元素位置想交换
void insert_x(int x)
{
int l=0;
int r=length-1;
int mid;
while(l<=r)
{
mid = (l+r)/2;
if(nums[mid]==x)
{
int temp = nums[mid];
nums[mid]=nums[mid+1];
nums[mid+1]=temp;
show();
return;
}
if(nums[mid]>x)
{
r=mid-1;
}else{
l=mid+1;
}
}
if(length==maxsize){
cout<<"error"<<endl;
return;
}
for(int i=length;i>l;i--)
{
nums[i]=nums[i-1];
}
nums[l]=x;
length++;
show();
return;
}
10.设将n(n>1)个整数存放在一维数组R中。设计一个时间和空间两方面都尽可能高效的算法。将R中保存的序列循环左移p(0<p<n)个位置,即将R中的数据由(X0,X1,...,Xn-1)变换为(Xp,Xp+1,...,Xn-1,X0,X1,...,Xp-1)。要求
1)给出算法的基本设计思想
先将所有数倒置,然后从尾部起往前的p个数单独倒置,剩余的数单独倒置
时间复杂度O(n),空间复杂度O(1)
#include <iostream>
using namespace std;
int n[10]={0,1,2,3,4,5,6,7,8,9};
void reverse_array(int n[10],int b,int p)
{
int mid = (b+p)/2;
for(int i=b;i<mid;i++)
{
int temp;
temp=n[i];
n[i]=n[p-i+b];
n[p-i+b]=temp;
}
}
int main()
{
int p;
cin>>p;
reverse_array(n,0,9);
reverse_array(n,0,p-1);
reverse_array(n,p,9);
for(int i=0;i<10;i++)
cout<<n[i]<<' ';
return 0;
}
11.一个长度为L(L>=1)的升序序列S,处在第[L/2]个位置的数称为S的中位数。例如,若序列S1=(11,13,15,17,19),则S1的中位数是15,两个序列的中位数是含它们所有元素的升序序列的中位数。例如,若S2=中位数是15,两个序列的中位数是含它们所有元素的升序序列A和B,试设计一个在时间和空间两方面都尽可能高效的算法,找出两序列的A和B的中位数
设计思想:
分别求两个升序序列A、B的中位数,设为a和b,求序列A,B的中位数过程如下
- 若a=b,则a或b即为所求中位数,算法结束。
- 若a<b,则舍弃序列A中较小的一半,同时舍弃序列B中较大的一半,要求两次舍弃的长度相等
- 若a>b,则舍弃序列A中较大的一半,同时舍弃序列B中较小的一半,要求两次舍弃的长度相等
时间复杂度为O(logn),空间复杂度为O(1)
void M_Search(int A[],int B[],int n)
{
int s1=0,d1=n-1,m1,s2=0,d2=n-1,m2;
//分别表示序列A和B的首位数
while(s1!=d1||s2!=d2)
{
m1=(s1+d1)/2;
m2=(s2+d2)/2;
if(A[m1]==B[m2])
return A[m1];
if(A[m1]<B[m2])
{
if((s1+d1)%2==0)
{
s1=m1;
d2=m2;
}
else
{
s1=m1+1;
d2=m2;
}
}else{
if((s2+d2)%2==0)
{
d1=m1;
s2=m2;
}else{
d1=m1;
s2=m2+1;
}
}
return A[s1]<B[s2]?A[s1]:B[s2];
}
}
12.已知一个整数序列A=(a0,a1,...,an),其中0<=ai<n(0<=i<n)。存在ap1=ap2=...=apm=x且m>n/2(0<=pk<n,1<=k<=m),则称x为A的主元素。找出主元素
时间复杂度为O(n),空间复杂度为O(1)
int Majority(int A[],int n){
int i,c,count=1;
c=A[0];
for(i=1; i<n; i++)
{
if(A[i]==c)
{
count++;
}
else
{
if(count>0)
count--;
else
{
c=A[i];
count=1;
}
}
}
count=0;
for(int i=0; i<n; i++)
{
if(c==A[i])
count++;
}
if(count>n/2) return c;
else return -1;
}
13.给定一个含n(n>=1)个整数的数组,请设计一个在时间上尽可能高效的算法,找出数组中未出现的最小整数。
算法的时间复杂度O(n),空间复杂度O(1)
int findmin(int A[],int n)
{
int i,*B;
B=(int *)malloc(sizeof(int) *n);
memset(B,0,sizeof(B));
for(int 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;
}