判断题
1、数据的逻辑结构是指数据的各数据项之间的逻辑关系。 F
数据的逻辑结构是指数据的各数据元素之间的逻辑关系。
2、顺序表中逻辑上相邻的元素,其物理位置也一定相邻。 T
线性表的顺序表示指的是用一组地址连续的存储单元依次存储线性表的数据元素,这种表示也称作线性表的顺序存储结构或顺序映像。通常,称这种存储结构的线性表为顺序表。
其特点是,逻辑上相邻的元素,其物理位置也是相邻的。
3、顺序表是一种随机存取的存储结构。 T
随机存取通俗点说就是,想存取哪个位置就能存取哪个位置,而且不需要访问其之前的数据,换种说法就是直接存取。而顺序表是逻辑上相邻,物理位置上连续的,因此,只需要知道顺序表的起始位置,就能对它任意位置进行存取。
4、链表中逻辑上相邻的元素,其物理位置也一定相邻。 F
线性表链式存储结构的特点是:用一组任意的存储单元存储线性表的数据元素(这组存储单元可以是连续的,也可以是不连续的)。
5、顺序存储设计时,存储单元的地址一定连续。 T
线性表的顺序表示指的是用一组地址连续的存储单元依次存储线性表的数据元素,这种表示也称作线性表的顺序存储结构或顺序映像。通常,称这种存储结构的线性表为顺序表。
其特点是,逻辑上相邻的元素,其物理位置也是相邻的。
6、在N个结点的顺序表中访问第i(1<=i<=N)个结点和求第i(2<=i<=N)个结点直接前驱的算法时间复杂度均为O(1)。 T
顺序表可以对结点直接存取,不需要访问其之前的结点,所以与顺序表的长度N无关,因此算法时间复杂度为O(1)。
7、线性表采用链式存储结构时,各个数据元素的存储单元地址一定是不连续的。 F
链式存储用的是任意的存储单元,可以连续,也可以不连续,所以不一定。
8、线性表L如果需要频繁地进行不同下标元素的插入、删除操作,此时选择顺序存储结构更好。 F
顺序表每次插入和删除的算法时间复杂度是O(N),因为在每次插入或删除时,需要让后边的所有结点移动,而链式存储的算法时间复杂度是O(1),只需要两次首尾链接或者一次首位链接。
9、非空线性表可以有多个开始结点。 F
10、非空线性表中每个结点都有一个前驱结点。 F
11、非空线性表除终端结点外,每个结点都有唯一的后继结点。 T
12、非空线性表中每个结点都有一个后继结点。 F
对于非空的线性表或线性结构,其特点是:
1)存在唯一的一个被称作“第一个”的数据元素。(其实就是只有一个开始结点)
2)存在唯一的一个被称作“最后一个”的数据元素。
3)除第一个元素之外,结构中的每个数据元素均只有一个前驱。
4)除最后一个元素之外,结构中的每个数据元素均只有一个后继。
前驱,后继,即为跟它相连的前边的一个或者后边的一个。
13、对于顺序存储的长度为N的线性表,访问结点和增加结点的时间复杂度分别对应为O(1)和O(N)。 T
14、若某线性表最常用的操作是存取任一指定序号的元素和在最后进行插入和删除运算,则利用顺序表存储最节省时间。 T
链式表需要从头开始访问到指定位置或者最后来进行插入和删除,而顺序表不用。
15、对于顺序存储的长度为N的线性表,删除第一个元素和插入最后一个元素的时间复杂度分别对应为O(1)和O(N)。 F
删除第一个是O(N),插入最后一个是O(1).
16、在线性表的顺序存储结构中,插入和删除元素时,移动元素的个数与该元素的位置有关。 T
17、顺序存储方式只能用于存储线性结构。 F
顺序存储方式不仅能用于存储线性结构,还可以用来存放非线性结构,例如完全二叉树是属于非线性结构,但其最佳存储方式是顺序存储方式。
数据的逻辑结构包括线性结构、树、图、集合这四种,在线性结构里面又有线性表、栈、队列等等。而数据的存储结构只有两种:顺序存储结构和链式存储结构,这两种存储结构,前面一个是利用数据元素在存储器中的相对位置表示其逻辑结构,另外一个是用指针来表示其逻辑关系。
18、顺序存储的线性表可以随机存取。 T
19、顺序存储结构的主要缺点是不利于插入或删除操作。 T
20、在顺序表中逻辑上相邻的元素,其对应的物理位置也是相邻的。 T
选择题
1、对于顺序存储的长度为N的线性表,访问结点和增加结点的时间复杂度为:
A | O(1),O(1) |
B | O(1),O(N) |
C | O(N),O(1) |
D | O(N),O(N) |
顺序表中,访问节点的时间复杂度是O(1),插入和删除的时间复杂度是O(N).
2、在N个结点的顺序表中,算法的时间复杂度为O(1)的操作是:
A | 访问第i个结点(1≤i≤N)和求第i个结点的直接前驱(2≤i≤N) |
B | 在第i个结点后插入一个新结点(1≤i≤N) |
C | 删除第i个结点(1≤i≤N) |
D | 将N个结点从小到大排序 |
顺序表中,访问节点的时间复杂度是O(1),插入和删除的时间复杂度是O(N).
3、若某线性表最常用的操作是存取任一指定序号的元素和在最后进行插入和删除运算,则利用哪种存储方式最节省时间?
A | 双链表 |
B | 单循环链表 |
C | 带头结点的双循环链表 |
D | 顺序表 |
存取任一指定序号的元素的时候是顺序表O(1)比链表O(N)快,插入和删除是链表O(1)比顺序表O(N)快,然而本题是在最后插入和删除,顺序表和链表都是O(1),所以选择顺序表。
4、顺序表中第一个元素的存储地址是100,每个元素的长度为2,则第5个元素的地址是( )。
A | 100 |
B | 105 |
C | 108 |
D | 110 |
100+2*4=108
因为第一个是100,第五个就是往后第四个。0 2 4 6 8
5、用数组表示线性表的优点是()。
A | 便于插入和删除操作 |
B | 便于随机存取 |
C | 可以动态地分配存储空间 |
D | 不需要占用一片相邻的存储空间 |
6、若长度为n的线性表采用顺序结构,在第i个数据元素之前插入一个元素,需要它依次向后移动()个元素。
A | n-i |
B | n-i+1 |
C | n-i-1 |
D | i |
在第i个之前插入,i后边有n-i个,再加上第i个本身,就是n-i+1
7、顺序存储表示中数据元素之间的逻辑关系是由( )表示的。
A | 指针 |
B | 逻辑顺序 |
C | 存储位置 |
D | 问题上下文 |
顺序存储结构是借助元素在存储器中的相对位置来表示数据元素之间的逻辑关系的。
8、在以下有关顺序表的叙述中正确的是( )。
A | 顺序表的优点是存储密度高,且插入与删除运算的时间效率高 |
B | 集合与顺序表的区别在于集合中的元素不能相等 |
C | 线性表就是顺序存储的表 |
D | 取顺序表第i个元素的时间与i的大小有关 |
A、插入与删除运算的时间效率低
C、由n(n>=0)个数据特性相同的元素构成的有限序列,称为线性表。
D、无关
9、阅读下列程序,其功能是()。
typedef struct {
ElemType *list;
int size;
intMaxSize;
}SeqList;
void fun1(SeqList&L) {
inti, j;
ElemType temp;
for (i=0, j= L.sise-1; i<j; i++, j--) {
temp=L.list[i];
L.list[i]=L.list[j];
L.list[j]=temp;
}
}
A | 将顺序表原地逆置 |
B | 将链表原地逆置 |
C | 将顺序表首尾元素对换 |
D | 将链表首尾元素对换 |
i从左往右,j从右往左,两端开始互相交换。
10、已知线性表中的元素以值递增有序排列,阅读下列程序,该算法的功能是()。
typedef struct {
ElemType *list;
int size;
intMaxSize;
}SeqList;
void fun3(SeqList&L, ElemType min, ElemType max){
inti=0, j, k, d;
while(i<L.size&&L.list[i]<=min)
i++;
j = i;
while (j<L.size&&L.list[j]<max)
j++;
d = j-i;
if ( d==0) return;
for (k=j; k<L.size; k++) L.list[k-d] = L.list[k];
size = L.size - d;
}
A | 删除顺序表中所有值小于min或大于max的元素 |
B | 将顺序表中值大于min且小于max的元素向前移动 |
C | 将顺序表中值大于max的元素向前移动min个位置 |
D | 删除顺序表中所有值大于min且小于max的元素 |
i计数到小于min的最大值的下一个,即大于min的最小值
j计数到小于max的最大值的下一个,即大于max的最小值
然后将大于max的值全部往前移j-i的距离d,将大于min且小于max的覆盖,剩下的因为长度减d被截掉。
11、已知A、B和C为3个元素递增有序的顺序表,且同一个表中元素值各不相同,下列算法对A做如下操作:删除那些既在表B又在表C中出现的元素。请将该算法补充完整。
typedef struct {
ElemType *list;
int size;
intMaxSize;
}SeqList;
void deletesame(SeqList&A, SeqList B, SeqList C) {
inti=0, j=0, k=0, m;
ElemType same;
while (i<A.size&& j<B.size&& k<C.size) {
if (C.list[k] <B.list[j])
k++;
else if (C.list[k] >B.list[j])
j++;
else {
same=B.list[j];
while (i<A.size&&A.list[i]<same) i++;
if (i<A.size&&A.list[i]==same) {
m=i+1;
while (m<A.size) {
________________
}
A.size--;
j++;k++;
}
}
}
}
A | A.list[m]=A.list[m-1]; m++; |
B | A.list[m-1]=A.list[m]; m++; |
C | A.list[m++]=A.list[k++]; |
D | A.list[m++]=A.list[j++]; |
将后一个赋值给前一个,覆盖掉同时出现的就删除掉了,整个循环将要删除的元素后方的元素整体往前移了。(其实说移动似乎不严谨)
12、在包含 n个数据元素的顺序表中,▁▁▁▁▁ 的时间复杂度为 O(1)。
A | 访问第 i 个数据元素 |
B | 在第 i(1≤i≤n) 个结点后插入一个新结点 |
C | 删除第 i(1≤i≤n) 个结点 |
D | 将 n 个元素按升序排序 |
13、在一个长度为n的顺序表中,删除第i个元素(1≤i≤n)时需要移动( )个元素。
A | n-i |
B | n-i+1 |
C | n-i-1 |
D | i |
14、将两个各有n个元素的递增有序顺序表归并成一个有序顺序表,其最少的比较次数是( )
A | n |
B | 2n-1 |
C | 2n |
D | n-1 |
其中一个顺序表最小元素比另一个顺序表最大元素还大,就是n次比较。
15、等概率情况下,在表长为n的顺序表中插入一个元素所需移动的元素平均个数为( )
A | (n-1)/2 |
B | n/2 |
C | (n+1)/2 |
D | n-i |
从头插入到在尾部插入,需要移动n个到0个共n+1种情况,n*(n+1)/2(n+1)=n/2
16、( )结构中的结点最多只有一个前驱和一个后继。
A | 二叉树 |
B | 图 |
C | 线性表 |
D | 以上都不是 |
17、线性表L=(a1,a2,…,an),下列说法正确的是( )
A | 每个元素都有一个直接前驱和一个直接后继 |
B | 表中至少有一个元素 |
C | 表中元素需有序 |
D | 除第一个和最后一个元素外,其他元素都有且仅有一个直接前驱和一个直接后继 |
18、在n个数据元素的顺序表中,算法时间复杂度为O(1)的操作是( ) (1) 访问第i个结点(1≤i≤n) (2) 求第i个结点的直接前驱(2≤i≤n) (3) 求第i个结点的直接后继(1≤i≤n-1) (4) 在第i个结点后插入一个新结点(1≤i≤n) (5) 删除第i个结点(1≤i≤n) (6) 排序
A | (1)(2)(3)(4)(5) |
B | (1)(2)(3) |
C | (4)(5) |
D | (6) |
19、线性表(a1,a2,…,an)以顺序存储结构存储时,访问第i位置元素的时间复杂度为( )
A | O(1) |
B | O(n) |
C | O(i) |
D | O(i-1) |
20、顺序表中第1个元素的存储地址是2000,每个元素的长度为4,则第5个元素的地址是( )
A | 2020 |
B | 2016 |
C | 2024 |
D | 2012 |
2000+4*4=2016
编程题
7-1 查找整数 (12 分)
本题要求从输入的N个整数中查找给定的X。如果找到,输出X的位置(从0开始数);如果没有找到,输出“Not Found”。
输入格式:
输入在第一行中给出两个正整数N(≤20)和X,第二行给出N个整数。数字均不超过长整型,其间以空格分隔。
输出格式:
在一行中输出X的位置,或者“Not Found”。
输入样例1:
5 7
3 5 7 1 9
输出样例1:
2
输入样例2:
5 7
3 5 8 1 9
输出样例2:
Not Found
#include <iostream>
using namespace std;
int main()
{
int N, X;
cin >> N >> X;
int* n = new int[N];
int i;
for (i = 0; i < N; i++)
{
cin >> n[i];
if (n[i] == X)
{
cout << i;
return 0;
}
else if (i == N - 1 && n[i] != X)
{
cout << "Not Found";
return 0;
}
}
}
7-2 jmu-ds-顺序表区间元素删除 (14 分)
若一个线性表L采用顺序存储结构存储,其中所有的元素为整数。设计一个算法,删除元素值在[x,y]之间的所有元素,要求算法的时间复杂度为O(n),空间复杂度为O(1)。
输入格式:
三行数据,第一行是顺序表的元素个数,第二行是顺序表的元素,第三行是x和y。
输出格式:
删除元素值在[x,y]之间的所有元素后的顺序表。
输入样例:
10
5 1 9 10 67 12 8 33 6 2
3 10
输出样例:
1 67 12 33 2
#include <iostream>
using namespace std;
#define MAX_SIZE_OF_LIST 10000
typedef struct
{
int data[MAX_SIZE_OF_LIST];
int lenth;
}SqList;
void DelElemOfList(SqList* List, int x, int y)
{
int n = List->lenth;
for (int i = 0, j = 0; i < n; ++i)
{
if (x <= List->data[i] && List->data[i] <= y)
{
List->lenth--;
}
else
{
List->data[j] = List->data[i];
j++;
}
}
}
int main()
{
int x, y;
SqList list;
cin >> list.lenth;
for (int i = 0; i < list.lenth; ++i)
{
cin >> list.data[i];
}
cin >> x >> y;
DelElemOfList(&list, x, y);
for (int i = 0; i < list.lenth; i++)
{
cout << list.data[i];
if (i != list.lenth - 1)
{
cout << " ";
}
}
return 0;
}
7-3 合并有序数组 (14 分)
给定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>
int main()
{
int a, b;
scanf("%d",&a);
int A[a];
for (int i = 0; i < a; i++)
{
scanf("%d", &A[i]);
}
scanf("%d",&b);
int B[b];
for (int i = 0; i < b; i++)
{
scanf("%d",&B[i]);
}
int j = 0;
int i = 0;
while (j < b && i < a)
{
if (A[i] >= B[j])
{
printf("%d ",B[j++]);
}
else
{
printf("%d ",A[i++]);
}
}
while (i<a)
{
printf("%d ",A[i++]);
}
while (j<b)
{
printf("%d ",B[j++]);
}
}