#include
#include
#define Max 100
typedef struct{
int data[Max];
int length;
}SqList;
typedef struct{
int *data;
int MaxSize,length;
}SeqList;
//2.2.3
/*
01从顺序表中删除具有最小值的元素(假设唯一)并由函数返回被删元素的值。
空出的位置由最后一个元素填补,若顺序表为空,则显示出错信息并退出运行。
*/
int Delete(SqList &l,int &e){
if(l.length == 0){
printf("顺序表为空,退出运行!!");
exit(0);
}
int min = l.data[0],k = 0;
for(int i = 1;i < l.length;i++){
if(min > l.data[i]) {
min = l.data[i];
k = i;
}
}
e = min;
for(int i = k + 1;i < l.length; i++){
l.data[i - 1] = l.data[i];
}
l.length--;
return e;
}
//02设计一个高效算法,将顺序表L的所有元素逆置,要求算法的空间复杂度为O(1).
void Reverse(SqList &l){
for(int i = 0; i < l.length/2; i++){
int t = l.data[i];
l.data[i] = l.data[l.length - i - 1];
l.data[l.length - i - 1] = t;
}
}
//03对长度为n的顺序表L,编写一个时间复杂度为O(n)、空间复杂度为0(1)的算法,该算法删除线性表中所有值为x的数据元素。
bool Deletes(SqList &l,int x){
int k = 0;
if(l.length == 0) return false;
for(int i = 0; i < l.length; i++){
if(x != l.data[i]){
l.data[k++] = l.data[i];
}
}
l.length = k;
return true;
}
//04从有序顺序表中删除其值在给定值s与t之间(要求s
if(s >= t) return false;
if(l.length == 0) return false;
int a = -1,b = -1,k = 0;
for(int i = 0; i < l.length; i++){
if(l.data[i] > s){
a = i;
break;
}
}
for(int i = l.length - 1; i >= 0; i--){
if(l.data[i] < t){
b = i;
break;
}
}
k = b - a;
for(int i = a + 1; i < l.length; i++){
l.data[i - 1] = l.data[i - 1 + k];
}
l.length -= k;
return true;
}
//05从顺序表中删除其值在给定值s与t之间(包含s和t,要求s 中的数据由(X0, X1,..., Xn-1)变换为(Xp, Xp+1,...,Xn-1, X0,X1,...,Xp-1). 要求: void Round(SqList &l,int p){
if(s >= t) return false;
if(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){
l.data[k++] = l.data[i];
}
}
l.length = k;
return true;
}
//06从有序顺序表中删除所有其值重复的元素,使表中所有元素的值均不同。
bool Deletessss(SqList &l){
if(l.length == 0) return false;
int k = 1;
for(int i = 1;i < l.length;i++){
if(l.data[i - 1] != l.data[i]){
l.data[k++] = l.data[i];
}
}
l.length = k;
return true;
}
//07将两个有序顺序表合并为一-个新的有序顺序表,并由函数返回结果顺序表。
void hb(SqList l1,SqList l2,SqList &l){
int i = 0,j = 0,k = 0;
while(i < l1.length && j < l2.length){
if(l1.data[i] <= l2.data[j]){
l.data[k++] = l1.data[i];
i++;
}else{
l.data[k++] = l2.data[j];
j++;
}
}
while(i < l1.length){
l.data[k++] = l1.data[i];
i++;
}
while(j < l2.length){
l.data[k++] = l2.data[j];
j++;
}
l.length = k;
}
//08已知在一维数组A[m + n]中依次存放两个线性表(a1, a2, a3... am)和(b1, b2, b3...,bn,).编写一个函数,将数组中两个顺序表的位置互换,即将(b, b2, b3,... bn,)放在(a, a2, a3,... am)的前面。
void Change(SqList &l,int m,int n){
int a[m],b[n],j = 0,k = 0;
for(int i = 0;i < m; i++){
a[i] = l.data[i];
}
for(int i = m; i < m + n; i++){
b[j++] = l.data[i];
}
for(int i = 0; i < n; i++){
l.data[i] = b[i];
}
for(int i = n; i < m + n;i++){
l.data[i] = a[k++];
}
}
/*09
线性表(a1, a2, a3,... an)中的元素递增有序且按顺序存储于计算机内。要求设计一个算法
完成用最少时间在表中查找数值为x的元素,若找到,则将其与后继元素位置相交换,
若找不到,则将其插入表中并使表中元素仍递增有序。
*/
void Search(SqList &l,int x){
if(x >= l.data[l.length - 1]) {
l.length++;
l.data[l.length - 1] = x;
return;
}
int ll = 0,r = l.length - 1,k = -1,mid;
while(ll <= r){
mid = (ll + r)/2;
if(l.data[mid] < x){
ll = mid + 1;
}else if(l.data[mid] > x){
r = mid - 1;
}else{
break;
}
}
if(l.data[mid] == x && mid != l.length - 1){
int t = l.data[mid];
l.data[mid] = l.data[mid + 1];
l.data[mid + 1] = t;
}
if(ll > r){
for(int i = l.length - 1;i > r;i--){
l.data[i + 1] = l.data[i];
}
l.data[r] = x;
l.length++;
}
}
/*10
[2010统考真题]设将n(n> 1)个整数存放到一维数组R中。设计一个在时间和空间
两方面都尽可能高效的算法。将R中保存的序列循环左移p(0
1)给出算法的基本设计思想。
2)根据设计思想,采用C或C++或Java语言描述算法,关键之处给出注释。
3)说明你所设计算法的时间复杂度和空间复杂度。
*/
void Circle(SqList &l){
int t = l.data[0];
for(int i = 1;i < l.length; i++){
l.data[i - 1] = l.data[i];
}
l.data[l.length - 1] = t;
}
for(int i = 0; i < p; i++){ //循环p次,每次左移一位
Circle(l);
}
}
/*11
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)说明你所设计算法的时间复杂度和空间复杂度。
*/
int Find(SqList l1,SqList l2){
SqList l;
int i = 0,j = 0,k = 0;
while(i < l1.length && j < l2.length){
if(l1.data[i] <= l2.data[j]){
l.data[k++] = l1.data[i];
i++;
}else{
l.data[k++] = l2.data[j];
j++;
}
}
while(i < l1.length){
l.data[k++] = l1.data[i];
i++;
}
while(j < l2.length){
l.data[k++] = l2.data[j];
j++;
}
l.length = k;
return l.data[l.length/2];
}
/*12
[2013统考真题]已知一个整数序列A = (a0,a1,...,an-1),其中0≤ai
元素。假设A中的n个元素保存在一个一维数组中,请设计一个尽可能高效的算法,找
出A的主元素。若存在主元素,则输出该元素;否则输出-1.要求:
1)给出算法的基本设计思想。
2)根据设计思想,采用C或C++或Java语言描述算法,关键之处给出注释。
3)说明你所设计算法的时间复杂度和空间复杂度。
*/
int More(SqList l){
int k = 0;
for(int i = 0; i < l.length;i++){
for(int j = 0;j < l.length - i - 1;j++){
if(l.data[i] > l.data[j]){
int t = l.data[i];
l.data[i] = l.data[j];
l.data[j] = t;
}
}
}
for(int i = 0;i < l.length;i++){
if(l.data[l.length/2] == l.data[i]) k++;
}
if(k > l.length/2) return l.data[l.length/2];
return -1;
}
/*13
[2018统考真题]给定一个含n (n≥1)个整数的数组,请设计一个在时间上尽可能高
效的算法,找出数组中未出现的最小正整数。例如,数组{-5,3,2, 3}中未出现的最小正
整数是1;数组{1,2,3}中 未出现的最小正整数是4.要求:
1)给出算法的基本设计思想。
2)根据设计思想,采用C或C++或Java语言描述算法,关键之处给出注释。
3)说明你所设计算法的时间复杂度和空间复杂度。
*/
int Finds(SqList l){
for(int i = 0; i < l.length;i++){
for(int j = 0;j < l.length - i - 1;j++){
if(l.data[i] > l.data[j]){
int t = l.data[i];
l.data[i] = l.data[j];
l.data[j] = t;
}
}
}
}
/*14
[2020统考真题]定义三元组(a, b, c) (a、b、c均为正数)的距离D=|a-b| + |b-c| +
|c-a|。给定3个非空整数集合S1、S2和S3;,按升序分别存储在3个数组中。请设计-一个
尽可能高效的算法,计算并输出所有可能的三元组(a, b,c) (a∈S1, b∈S2, c∈S3) 中的
最小距离。例如S1= {-1,0,9},S2={ -25,-10, 10,11}, S3= {2, 9, 17,30, 41},则最小
距离为2,相应的三元组为(9, 10, 9)。要求:
1)给出算法的基本设计思想。
2)根据设计思想,采用C或C++或Java语言描述算法,关键之处给出注释。
3)说明你所设计算法的时间复杂度和空间复杂度。
*/
//初始化(静态)
void InitList(SqList &l){
for(int i = 0; i < Max; i++){
l.data[i] = 0;
}
l.length = 0;
}
//初始化(动态)
void InitLists(SeqList &l){
l.data = (int *)malloc(sizeof(int) * Max);
l.length = 0;
l.MaxSize = Max;
}
//插入
bool InsertList(SqList &l,int pos,int e){
if(pos < 1 || pos > l.length + 1) return false;
if(l.length >= Max) return false;
for(int i = l.length; i >= pos;i--){
l.data[i] = l.data[i - 1];
}
l.length++;
l.data[pos - 1] = e;
}
//删除
bool DeleteList(SqList &l,int pos,int &e){
if(l.length == 0) return false;
if(pos < 1 || pos > l.length + 1) return false;
e = l.data[pos - 1];
for(int i = pos;i < l.length;i++){
l.data[i - 1] = l.data[i];
}
l.length--;
}
//遍历
void TraveList(SqList l){
for(int i = 0;i < l.length;i++){
printf("%d ",l.data[i]);
}
}
int ListDelete(SqList &l, int &e){
e = l.data[0];
for(int i = 0;i < l.length - 1; i++){
l.data[i] = l.data[i + 1];
}
l.length--;
return e;
}
int main(){
int a[10] = {1,2,3,4,5,6,7,8,9,10};
int b[5] = {1,2,3,4,5};
int e = -1;
SqList l;
InitList(l);
for(int i = 0;i < 10;i++){
InsertList(l,i + 1,a[i]);
}
TraveList(l);
//DeleteList(l,5,e);
printf("\n");
//01--printf("%d",Delete(l,e));
//02--Reverse(l);
//03--Deletes(l,5);
//04--Deletess(l,3,8);
//05--Deletesss(l,3,7);
//06--Deletessss(l);
/*07--
SqList l1,l2,l;
InitList(l1);
InitList(l2);
InitList(l);
for(int i = 0;i < 5;i++){
InsertList(l2,i + 1,b[i]);
}
TraveList(l2);
hb(l1,l2,l);
*/
//08--Change(l,5,5);
//09--Search(l,3);
//10--Round(l,3);
/*11--
InitList(l2);
for(int i = 0;i < 5;i++){
InsertList(l2,i + 1,b[i]);
}
printf("%d\n",Find(l1,l2));
*/
//12--printf("%d\n",More(l));
printf("\n");
TraveList(l);
return 0;
}