数据结构 第二章 线性表
2.2 线性表的顺序表示
1.从顺序表中删除具有最小值的元素。由函数返回被删元素的值。空出的位置由最后一个元素填补。若顺序表为空,则显示出错信息并退出运行。
#include<stdio.h>
#define maxsize 50
typedef struct{
int data[maxsize];
int length;
}SqList;
//从顺序表中删除具有最小值的元素。由函数返回被删元素的值。空出的位置由最后一个元素填补。若顺序表为空,则显示出错信息并退出运行。
bool del_min(SqList &a,int &min){
if(a.length==0) return false;
int pos=0;
min=a.data[0];
for(int i=0;i<a.length;++i){
if(a.data[i]<min){
min=a.data[i];
pos=i;
}
}
a.data[pos]=a.data[a.length-1];
a.length--;
return true;
}
int main(){
SqList a;
int min=0;
a.length=0;
for(int i=0;i<maxsize;++i){
scanf("%d",&a.data[i]);
if(a.data[i]==-1) break;
a.length++;
}
del_min(a,min);
printf("%d\n",min);
for(int i=0;i<a.length;++i){
printf("%d ",a.data[i]);
}
return 0;
}
2.设计一个高效算法将顺序表l的所有元素逆置。要求算法的空间复杂度为O(1).
#include<stdio.h>
#define maxsize 50
typedef struct{
int data[maxsize];
int length;
}SqList;
void swap(int &c,int &d){
int temp=0;
temp=c;
c=d;
d=temp;
}
bool Inverse(SqList &a){
if(a.length==0) return false;
int i=0,j=a.length-1;
while(i<j){
swap(a.data[i++],a.data[j--]);
}
return true;
}
int main(){
SqList a;
for(int i=0;i<maxsize;++i){
scanf("%d",&a.data[i]);
if(a.data[i]==-1) break;
a.length++;
}
Inverse(a);
for(int i=0;i<a.length;++i){
printf("%d ",a.data[i]);
}
return 0;
}
3.长度为n的顺序表l编写一个时间复杂度为o(n)空间复杂度为o(1)的算法。该算法删除线性表中所有值为x的数据元素。
#include<stdio.h>
#define maxsize 50
typedef struct{
int data[maxsize];
int length;
}SqList;
void del_x(SqList &a,int x){
int k=0;
for(int i=0;i<a.length;i++){
if(a.data[i]!=x){
a.data[k]=a.data[i];
k++;
}
}
a.length=k;
}
int main(){
SqList a;
int x=19;
a.length=0;
for(int i=0;i<maxsize;++i){
scanf("%d",&a.data[i]);
if(a.data[i]==-1) break;
a.length++;
}
del_x(a,x);
for(int i=0;i<a.length;++i){
printf("%d ",a.data[i]);
}
return 0;
}
- 5.从有序(无序也可以)顺序表中删除,其值在给定值s与t之间要求s小于t的所有元素。若s或t取值不合理或顺序表为空。则显示出错信息并退出运行。
测试数据:107 26 32 23 64 78 96 -1
#include<stdio.h>
#define maxsize 50
typedef struct{
int data[maxsize];
int length;
}SqList;
bool del_s_t(SqList &a,int s,int t){
if(s>=t||a.length==0) return false;
int k=0;
for(int i=0;i<a.length;i++){
if(a.data[i]<s||a.data[i]>t){
a.data[k]=a.data[i];
k++;
}
}
a.length=k;
}
int main(){
SqList a;
a.length=0;
for(int i=0;i<maxsize;++i){
scanf("%d",&a.data[i]);
if(a.data[i]==-1) break;
a.length++;
}
int s=20,t=65;
del_s_t(a,s,t);
for(int i=0;i<a.length;++i){
printf("%d ",a.data[i]);
}
return 0;
}
6.从有序顺序表中删除所有其值重复的元素。使表中所有元素的值均不同。
//我的代码对无序表同样适用
测试数据:65 65 19 32 32 32 65 23 64 3 19 9 3 -1
include<stdio.h>
#define maxsize 50
typedef struct{
int data[maxsize];
int length;
}SqList;
void del_same(SqList &a){
int k=0;
for(int j=0;j<a.length;j++){
k=j+1;
for(int i=j+1;i<a.length;i++){
if(a.data[i]!=a.data[j]){
a.data[k]=a.data[i];
k++;
}
}
a.length=k;
}
}
int main(){
SqList a;
a.length=0;
for(int i=0;i<maxsize;++i){
scanf("%d",&a.data[i]);
if(a.data[i]==-1) break;
a.length++;
}
del_same(a);
for(int i=0;i<a.length;++i){
printf("%d ",a.data[i]);
}
return 0;
}
7.将两个有序顺序表。合并为一个新的有序顺序表。并由函数返回结果顺序表。
//测试数据:2 4 6 8 10 14 16 19 20 -1
// 1 3 5 7 9 10 16 -1
#include<stdio.h>
#define maxsize 50
typedef struct{
int data[maxsize];
int length;
}SqList;
void merge(SqList a,SqList b,SqList &c){
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 if(a.data[i]==b.data[j]){
c.data[k++]=a.data[i++];
c.data[k++]=b.data[j++];
}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;
}
int main(){
SqList a,b,c;
a.length=0;
b.length=0;
for(int i=0;i<maxsize;++i){
scanf("%d",&a.data[i]);
if(a.data[i]==-1) break;
a.length++;
}
for(int i=0;i<maxsize;++i){
scanf("%d",&b.data[i]);
if(b.data[i]==-1) break;
b.length++;
}
merge(a,b,c);
for(int i=0;i<c.length;++i){
printf("%d ",c.data[i]);
}
return 0;
}
8.已知在一维数组A[m+n]中存放两个线性表(a1,a2,a3…,am)和(b1,b2,b3,b4…,bn)。试编写一个函数。将数组中两个顺序表的位置互换。
即将 (b1,b2,b3,b4…,bn)放在 (a1,a2,a3…,am)的前面。
//测试数据: 2 4 6 8 10 14 16 19 20 -1
#include<stdio.h>
#define maxsize 50
typedef struct{
int data[maxsize];
int length;
}SqList;
void swap(int &a,int &b){
int temp=a;
a=b;
b=temp;
}
bool reverse(SqList &a,int s,int t){
if(a.length==0||s>t) return false;
int i=s,j=t;
while(i<j){
swap(a.data[i++],a.data[j--]);
}
return true;
}
int main(){
SqList a;
a.length=0;
for(int i=0;i<maxsize;++i){
scanf("%d",&a.data[i]);
if(a.data[i]==-1) break;
a.length++;
}
int m=3,n=6;
reverse(a,0,m+n-1);
reverse(a,0,n-1);
reverse(a,n,m+n-1);
for(int i=0;i<a.length;++i){
printf("%d ",a.data[i]);
}
return 0;
}
9.线性表(a1,a2,a3…,an)中的元素递增有序写,按顺序存储于计算机内,要求设计一个算法完成,用最少时间在表中查找数值为x的元素。若找到则将其与后继元素位置相交换。若找不到,则将其插入。表中,并将表中元素仍递增有序。
//测试数据:2 4 6 8 10 14 16 19 20 -1 插入10
#include<stdio.h>
#define maxsize 50
typedef struct{
int data[maxsize];
int length;
}SqList;
int binary_search(SqList a,int x){ //折半查找,时间最短
int low=0,high=a.length-1,mid;
while(low<=high){
mid=(low+high)/2;
if(a.data[mid]==x) return mid;
else if(a.data[mid]>x){
high=mid-1;
}else{
low=mid+1;
}
}
return -1;
}
void ExchangeInsert(SqList &a,int x){
int t=binary_search(a,x),temp,i;
if(t!=-1&&t!=a.length-1){
temp=a.data[t];
a.data[t]=a.data[t+1];
a.data[t+1]=temp;
}
if(t==-1){
for(i=a.length-1;a.data[i]>x;i--){
a.data[i+1]=a.data[i];
}
a.data[i+1]=x;
a.length++;
}
}
int main(){
SqList a;
a.length=0;
for(int i=0;i<maxsize;++i){
scanf("%d",&a.data[i]);
if(a.data[i]==-1) break;
a.length++;
}
ExchangeInsert(a,10);
for(int i=0;i<a.length;++i){
printf("%d ",a.data[i]);
}
return 0;
}
10.和第八题算法一致
11.【2011统考真题】一个长度为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的中位数,要求:
1.给出算法的基本设计思想。
2.根据设计思想,采用C,C++,或java语言描述算法。关键之处给出注释。
3.说明你所设计算法的时间复杂度和空间复杂度。
#include<stdio.h>
#define maxsize 50
typedef struct{
int data[maxsize];
int length;
}SqList;
//这个算法有瑕疵,只适用于没有相同元素的两个序列 改正的方法很简单
int mid_num(SqList a,SqList b){
if(a.length!=b.length) return -1;
int i=0,j=0,k=0,mid;
while(i<a.length&&j<b.length&&k!=a.length){
if(a.data[i]<=b.data[j]){ //改正 把相等情况单领出来再改下判别条件
mid=a.data[i++];
k++;
}else{
mid=a.data[j++];
k++;
}
}
while(i<a.length&&k!=a.length){
mid=a.data[i++];
k++;
}
while(j<b.length&&k!=a.length){
mid=a.data[j++];
k++;
}
return mid;
}
int main(){
SqList a,b;
a.length=0;
b.length=0;
for(int i=0;i<maxsize;++i){
scanf("%d",&a.data[i]);
if(a.data[i]==-1) break;
a.length++;
}
for(int i=0;i<maxsize;++i){
scanf("%d",&b.data[i]);
if(b.data[i]==-1) break;
b.length++;
}
printf("%d ",mid_num(a,b));
return 0;
}
12.【2013年统考真题】已知一个整数序列A=(a0,a1,…an-1)其中,0<=ai<n,若存在ap1=ap2=ap3=…=apm=x且m>n/2,则称x为a的主元素。例如a=(0,5,5,3,5,7,5,5)。则5为主元素.又如a=(0,5,5,3,5,1,5,7),则A中没有主元素.
#include<stdio.h>
#define maxsize 50
typedef struct{
int data[maxsize];
int length;
}SqList;
int majority(SqList a){
int i=0;
int b[a.length]={0};
while(i<a.length){
b[a.data[i++]]++;
}
int m=b[0],maj=0;
for(int j=1;j<a.length;j++){
if(b[j]>m){
m=b[j];
maj=j;
}
}
if(m> a.length/2){
return maj;
}
return -1;
}
int main(){
SqList a;
a.length=0;
for(int i=0;i<maxsize;++i){
scanf("%d",&a.data[i]);
if(a.data[i]==-1) break;
a.length++;
}
printf("%d\n",majority(a));
return 0;
}
该算法时间复杂度为O(n),加了一个辅助数组b,空间复杂度为O(n);
13.给定一个含n个整数的数组。请设计一个在时间上尽可能高效的算法。找出数组中未出现的最小正整数。例如,数组{-5,3,2,3}中未出现的最小正整数是1。数组{1,2,3}中未出现的最小正整数是4.要求:
1。给出算法的基本设计思想。
2。根据设计思想,采用C或C++语言描述算法。关键之处给出注释。
3。说明你所设计算法的时间复杂度和空间复杂度。
算法设计思想和上一题类似
#include<stdio.h>
#define maxsize 50
typedef struct{
int data[maxsize];
int length;
}SqList;
int min_z(SqList a){
int i=0;
int b[maxsize]={0};
while(i<a.length){
if(a.data[i]>0){
b[a.data[i]]++;
}
i++;
}
for(int j=1;j<maxsize;j++){
if(b[j]==0){
return j;
}
}
return -1;
}
int main(){
SqList a;
a.length=0;
for(int i=0;i<maxsize;++i){
scanf("%d",&a.data[i]);
if(a.data[i]==-1) break;
a.length++;
}
printf("%d\n",min_z(a));
return 0;
}
该算法时间复杂度为O(n),加了一个辅助数组b,空间复杂度为O(n);
14.定义域三元组(a,b,c)的距离D=|a-b|+|b-c|+|c-a|。给定3个非空整数集合S1,S2和S3。按升序分别存储在三个数组中。请设计一个尽可能高效的算法。计算并输出所有可能的三元组(a,b,c)中的最小距离。要求:
1给出算法的基本设计思想。
2.根据设计思想,采用c语言或c加加语言描述算法。关键之处给出注释。
3.说明你所设计算法的时间复杂度和空间复杂度。
#include<stdio.h>
#include<math.h>
#define maxsize 50
typedef struct{
int data[maxsize];
int length;
}SqList;
void min_dis(SqList a,SqList b,SqList c){
int i=0,j=0,k=0,d,min=65536,min_a,min_b,min_c;
while(i<a.length&&j<b.length&&k<c.length){
d=abs(a.data[i]-b.data[j])+abs(b.data[j]-c.data[k])+abs(c.data[k]-a.data[i]);
if(d<min){
min=d;
min_a=a.data[i];
min_b=b.data[j];
min_c=c.data[k];
}
if(a.data[i]<b.data[j]&&a.data[i]<c.data[k]){
i++;
}else if(b.data[j]<a.data[i]&&b.data[j]<c.data[k]){
j++;
}else{
k++;
}
}
printf("%d (%d,%d,%d)\n",min,min_a,min_b,min_c);
}
最好时间复杂度为O(min(l,m,n));最坏时间复杂度为O(l+m+n);
空间复杂度为O(1);