注:传统链表题目时间复杂度较高,一般只出现在面试题目中
相比传统链表,利用数组模拟链表,通常出现在考研机试和笔试中,相对来说耶更容易理解
建议大家在学好链表基础知识的前提下,尝试使用数组模拟链表练习题目。
下面给出pta题目中利用数组模拟链表的题目
7-1 顺序表的建立及遍历
读入n值及n个整数,建立顺序表并遍历输出。
输入格式:
读入n及n个整数
输出格式:
输出n个整数,以空格分隔(最后一个数的后面没有空格)。
输入样例:
在这里给出一组输入。例如:
4
-3 10 20 78
输出样例:
在这里给出相应的输出。例如:
-3 10 20 78
参考代码:
include<stdio.h>
int main()
{
int n;
int a[10086];
scanf("%d",&n);
int i;
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
for(i=0;i<n;i++)
{
if(i==n-1)
{
printf("%d",a[i]);
}
else
printf("%d ",a[i]);
}
}
7-2 递增有序顺序表的插入
实验目的:1、掌握线性表的基本知识 2、深入理解、掌握并灵活运用线性表。3、熟练掌握线性表的存储结构及主要运算的实现
已知顺序表L递增有序,将X插入到线性表的适当位置上,保证线性表有序。。
输入格式:
第1行输入顺序表长度,第2行输入递增有序的顺序表,第3行输入要插入的数据元素X。
输出格式:
对每一组输入,在一行中输出插入X后的递增的顺序表。
输入样例:
在这里给出一组输入。例如:
5
1 3 5 7 9
6
输出样例:
在这里给出相应的输出。例如:
1,3,5,6,7,9,
参考代码:
#include<stdio.h>
int main()
{
int n;
scanf("%d",&n);
int a[n+1];
int i,j,x,t;
for(i=0;i<n+1;i++)
{
scanf("%d",&a[i]);
}
for(i=0;i<n+1;i++)
{
for(j=0;j<n-i;j++)
{
if(a[j]>a[j+1])
{
t=a[j];
a[j]=a[j+1];
a[j+1]=t;
}
}
}
for(i=0;i<n+1;i++)
{
printf("%d,",a[i]);
}
return 0;
}
7-3 顺序表(删除)
已知一组数据,采用顺序存储结构存储,其中所有的元素为整数。设计一个算法,删除元素值在[x,y]之间的所有元素
输入格式:
输入包含三行数据,第一行是表中元素个数,第二行是顺序表的各个元素,第三行是区间x和y。
输出格式:
删除元素值在[x,y]之间的所有元素后,输出新的顺序表。(最后无空格)
输入样例:
在这里给出一组输入。例如:
10
55 11 9 15 67 12 18 33 6 22
10 20
输出样例:
在这里给出相应的输出。例如:
55 9 67 33 6 22
参考代码:
#include<stdio.h>
int main()
{
int n;
scanf("%d",&n);
int a[n];
int i,flag[n],x,y;
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);
flag[i]=0;
}
scanf("%d %d",&x,&y);
for(i=0;i<n;i++)
{
if(a[i]>=x&&a[i]<=y)
flag[i]=1;
}
int k=0,b[n];
for(i=0;i<n;i++)
{
if(flag[i]==0)
{
b[k]=a[i];
k++;
}
}
for(i=0;i<k;i++)
{
if(i==k-1)
printf("%d",b[i]);
else
printf("%d ",b[i]);
}
return 0;
}
7-4 数组元素循环右移n位
从键盘接收两个整数m和n,分别表示一维整型数组的元素个数,和要向移动的位数。已知0<m<=100,以及n>0。
在用户输入m和n后,第二行输入相应个数的数组元素。
程序要实现的功能是,让数组元素往右移动n位。
例如,数组的5个元素是:1,2,3,4,5。
往右移动1位后:5,1,2,3,4
往右移动2位后:4,5,1,2,3
输入格式:
第一行输入两个整数,第二行输入数组元素。
输出格式:
移动后,数组的每一个元素,注意每个数组元素后有且仅有一个空格。
输入样例:
第一行的数据5和2,表示数组容量为5,让数组元素往右移动2个位置。
第二行是数组的每一个元素的值。
5 2
1 2 3 4 5
输出样例:
输出移动后的数组元素值,注意每个元素后有且仅有一个空格。
4 5 1 2 3
参考代码:
#include<stdio.h>
void youyi(int a[],int m,int n)
{
int i,j,k,t;
for(i=0;i<m;i++)
{
scanf("%d",&a[i]);
}
for(j=0;j<n;j++)
{
t=a[m-1];
for(k=m-1;k>=0;k--)
{
a[k]=a[k-1];
}
a[0]=t;
}
}
int main()
{
int m,n,i;
int a[100];
scanf("%d %d",&m,&n);
youyi(a,m,n);
for(i=0;i<m;i++)
{
printf("%d ",a[i]);
}
return 0;
}
7-5 最大子列和问题
给定K个整数组成的序列{ N1, N2, ..., NK },“连续子列”被定义为{ Ni, Ni+1, ..., Nj },其中 1≤i≤j≤K。“最大子列和”则被定义为所有连续子列元素的和中最大者。例如给定序列{ -2, 11, -4, 13, -5, -2 },其连续子列{ 11, -4, 13 }有最大的和20。现要求你编写程序,计算给定整数序列的最大子列和。
本题旨在测试各种不同的算法在各种数据情况下的表现。各组测试数据特点如下:
- 数据1:与样例等价,测试基本正确性;
- 数据2:102个随机整数;
- 数据3:103个随机整数;
- 数据4:104个随机整数;
- 数据5:105个随机整数;
输入格式:
输入第1行给出正整数K (≤100000);第2行给出K个整数,其间以空格分隔。
输出格式:
在一行中输出最大子列和。如果序列中所有整数皆为负数,则输出0。
输入样例:
6
-2 11 -4 13 -5 -2
输出样例:
20
参考代码:
#include<stdio.h>
int main()
{
int maxsum,thissum,n,i;
int a[100001];
scanf("%d",&n);
maxsum=0,thissum=0;
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);
thissum=thissum+a[i];
if(thissum<0)
{
thissum=0;
}
if(thissum>maxsum)
{
maxsum=thissum;
}
}
printf("%d",maxsum);
return 0;
}
7-6 一元多项式的乘法与加法运算
输入格式:
输入分2行,每行分别先给出多项式非零项的个数,再以指数递降方式输入一个多项式非零项系数和指数(绝对值均为不超过1000的整数)。数字间以空格分隔。
输出格式:
输出分2行,分别以指数递降方式输出乘积多项式以及和多项式非零项的系数和指数。数字间以空格分隔,但结尾不能有多余空格。零多项式应输出0 0
。
输入样例:
4 3 4 -5 2 6 1 -2 0
3 5 20 -7 4 3 1
输出样例:
15 24 -25 22 30 21 -10 20 -21 8 35 6 -33 5 14 4 -15 3 18 2 -6 1
5 20 -4 4 -5 2 9 1 -2 0
参考代码:
# include <stdio.h>
# include <stdlib.h>
int main()
{
int n, m, i, j, k, td, tD, flag=0;
scanf("%d", &n);
//A存放指数,a存放系数
int *A = (int *)malloc(n * sizeof(int));
int *a = (int *)malloc(n * sizeof(int));
for(i=0; i<n; i++)
scanf("%d %d", &A[i], &a[i]);
scanf("%d", &m);
//B存放指数,b存放系数
int *B = (int *)malloc(m * sizeof(int));
int *b = (int *)malloc(m * sizeof(int));
for(i=0; i<m; i++)
scanf("%d %d", &B[i], &b[i]);
//存放加法计算后的结果 ,C存放指数,c存放系数
int *C = (int *)malloc((m+n) * sizeof(int));
int *c = (int *)malloc((m+n) * sizeof(int));
//存放乘法计算后的结果 ,D存放指数,d存放系数
int *D = (int *)malloc((m*n) * sizeof(int));
int *d = (int *)malloc((m*n) * sizeof(int));
//乘法运算
k = 0;
for(i=0; i<n; i++)
for(j=0; j<m; j++)
{
D[k] = A[i] * B[j];
d[k] = a[i] + b[j];
k++;
}
//排序 + 合并同类项
for(i=0; i<k; i++)
for(j=i+1; j<k; j++)
{
if(d[i] < d[j])//冒泡排序法
{
td = d[i];
d[i] = d[j];
d[j] = td;
tD = D[i];
D[i] = D[j];
D[j] = tD;
}
if(d[i] == d[j])//合并同类项
{
if(D[i]+D[j])
{
D[i] = D[i] + D[j];
D[j] = 0;
}
else
{
D[i] = 0;
D[j] = 0;
}
}
}
//输出
for(i=0; i<k; i++)
if(D[i])//系数!=0才能输出内容
{
if(flag)
printf(" ");
printf("%d %d", D[i], d[i]);
flag = 1;
}
if(!flag)//flag为零多项式的标识,当flag=0,说明运算的结果为零多项式
printf("0 0");
printf("\n");
//加法运算 两一元多项式进行对比
//如果有一个一元多项式全部比较完,则另一个的剩下的系数和指数直接追加在c和C后面
i = 0, j = 0, k = 0, flag = 0;
while(i<n && j<m)
{
if(a[i] > b[j])
{
c[k] = a[i];
C[k] = A[i];
k++;
i++;
}
else if(a[i] == b[j])
{
i++;
j++;
if(A[i-1]+B[j-1])
{
c[k] = a[i-1];
C[k] = (A[i-1] + B[j-1]);
}
else
{
c[k] = 0;
C[k] = 0;
}
k++;
}
else if(a[i] < b[j])
{
c[k] = b[j];
C[k] = B[j];
k++;
j++;
}
}
if(i == n)
while(j < m)
{
c[k] = b[j];
C[k] = B[j];
j++;
k++;
}
if(j == m)
while(i<n)
{
c[k] = a[i];
C[k] = A[i];
i++;
k++;
}
for(i=0; i<k; i++)
{
if(C[i])
{
if(flag)
printf(" ");
printf("%d %d", C[i], c[i]);
flag = 1;
}
}
if(!flag)
printf("0 0");
return 0;
}
7-7 一元多项式的加法
设计程序求两个一元多项式的和。
输入格式:
输入分2行,每行分别先给出多项式非零项的个数,再以指数递降方式输入一个多项式非零项系数和指数。数字间以空格分隔。
输出格式:
输出1行,以指数递降方式输出和多项式非零项的系数和指数(保证不超过整数的表示范围)。数字间以空格分隔,但结尾不能有多余空格。零多项式应输出0 0。
输入样例:
4 3 4 -5 2 6 1 -2 0
3 5 20 -7 4 3 1
输出样例:
5 20 -4 4 -5 2 9 1 -2 0
参考代码:
#include <stdio.h>
#include <stdlib.h>
struct Term {
int coefficient;
int exponent;
};
struct Term* addPolynomials(struct Term* poly1, int n1, struct Term* poly2, int n2, int* resultSize) {
// 计算两个多项式系数相加的和
int i = 0, j = 0, k = 0;
struct Term* sum = (struct Term*)malloc((n1 + n2) * sizeof(struct Term));
while (i < n1 && j < n2) {
if (poly1[i].exponent > poly2[j].exponent) {
sum[k++] = poly1[i++];
} else if (poly1[i].exponent < poly2[j].exponent) {
sum[k++] = poly2[j++];
} else {
int newCoefficient = poly1[i].coefficient + poly2[j].coefficient;
if (newCoefficient != 0) {
sum[k].coefficient = newCoefficient;
sum[k].exponent = poly1[i].exponent;
k++;
}
i++;
j++;
}
}
while (i < n1) {
sum[k++] = poly1[i++];
}
while (j < n2) {
sum[k++] = poly2[j++];
}
*resultSize = k;
return sum;
}
int main() {
int n1;
scanf("%d", &n1);
struct Term* poly1 = (struct Term*)malloc(n1 * sizeof(struct Term));
for (int i = 0; i < n1; i++) {
scanf("%d %d", &poly1[i].coefficient, &poly1[i].exponent);
}
int n2;
scanf("%d", &n2);
struct Term* poly2 = (struct Term*)malloc(n2 * sizeof(struct Term));
for (int i = 0; i < n2; i++) {
scanf("%d %d", &poly2[i].coefficient, &poly2[i].exponent);
}
int resultSize;
struct Term* sum = addPolynomials(poly1, n1, poly2, n2, &resultSize);
if (resultSize == 0) {
printf("0 0\n");
} else {
for (int i = 0; i < resultSize; i++) {
if(i==0)
{
printf("%d %d", sum[i].coefficient, sum[i].exponent);
}
else
{
printf(" %d %d", sum[i].coefficient, sum[i].exponent);
}
}
printf("\n");
}
free(poly1);
free(poly2);
free(sum);
return 0;
}
7-8 单词逆置
输入一个可能包含若干(至少1个)单词的句子(可以假设每个单词之间有且仅有一个空格,标点符号视为单词的组成部分),输出每个单词逆置后的英文句子(参看样例输出)。
输入格式:
首先输入一个正整数T,表示测试数据的组数,然后是T组测试数据。每组测试数据输入一个字符串(长度不超过80),表示英文句子。
输出格式:
对于每组测试,输出每个单词逆置后的英文句子。
输入样例:
1
emoclew era uoY
输出样例:
welcome are You
参考代码:
#include<stdio.h>
#include<string.h>
void swap(char a[],int l,int r)
{
int i,j;
char t;
int m=(l+r)/2;
for(i=l,j=r;i<m,j>m;i++,j--)
{
t=a[i];
a[i]=a[j];
a[j]=t;
}
}
int main()
{
int t;
scanf("%d",&t);
getchar();
while(t--)
{
int n;
char a[81];
gets(a);
n=strlen(a);
int i,begin=0;
for(i=0;i<n;i++)
{
if((a[i]==' ')&&i!=n-1)
{
swap(a,begin,i-1);
begin=i+1;
}
if(i==n-1)
{
swap(a,begin,i);
}
}
puts(a);
}
return 0;
}
7-9 合并有序数组
给定2个非降序序列,要求把他们合并成1个非降序序列。假设所有元素个数为N,要求算法的时间复杂度为O(N)。
输入格式:
输入有4行。
第1行是一个正整数m,表示第2行有m个整数,这些整数构成一个非降序序列,每个整数之间以空格隔开。第3行是一个正整数n,表示第4行有n个整数,这些整数也构成一个非降序序列,每个整数之间以空格隔开。
输出格式:
把第2行的m个整数和第4行的n个整数合并成一个非降序序列,输出这个整数序列。每个数之间隔1个空格。
输入样例:
6
1 3 6 6 8 9
4
2 4 5 7
输出样例:
1 2 3 4 5 6 6 7 8 9
参考代码:
#include <stdio.h>
#include <stdlib.h>
void mergeArrays(int* arr1, int m, int* arr2, int n, int* result)//int *arr1就是代表数组的意思
{
int i = 0, j = 0, k = 0;
while (i < m && j < n)//确保数组都没有越界
{
if (arr1[i] <= arr2[j]) //如果第一个数组中的数小于第二个中的数,那我们就把这个小的数先放进去result,这样小的数就放在了前面
{
result[k] = arr1[i];
k++;//此时就把k往后加1,准备存储下一个数
i++;//此时i也加1,准备比较下一个数
}
else
{
result[k] = arr2[j];
k++;
j++;
}
}
while (i < m) {
result[k] = arr1[i];
k++;
i++;
}//如果上述while循环中有一个不满足条件,也就是说有一个已经遍历完了,这个时候就直接把没遍历完的那一个直接写到result就可以
while (j < n) {
result[k] = arr2[j];
k++;
j++;
}
}
int main() {
int m;
scanf("%d", &m);
int arr1[m];
for (int i = 0; i < m; i++) {
scanf("%d", &arr1[i]);
}
int n;
scanf("%d", &n);
int arr2[n];
for (int i = 0; i < n; i++) {
scanf("%d", &arr2[i]);
}
int result[m+n];
mergeArrays(arr1, m, arr2, n, result);
for (int i = 0; i < m + n; i++) {
printf("%d ", result[i]);
}
printf("\n");
return 0;
}