单链表解析Ⅰ

对链表某个节点的操作除第一个节点外,都需要找到该节点的前驱节点,这是关键。

1.不带头结点单链表:
①定义

typedef char ListData;
typedef struct node
{
    ListData data;
    struct node * link;
}ListNode;

typedef ListNode * LinkList;
LinkList first; //定义头指针
LinkList last;  //定义尾指针

②插入:没有头结点插入有三种情况
(1)在第一个节点前插入
在第一个节点前插入
(2)在链表中间插入
在链表中间插入
(3)在链表末尾插入
在链表末尾插入

/* 参数列表:
** LinkList & first:进行操作的链表头指针,
** x:插入的数据,
** i:插入的位置
*/
void Insert(LinkList & first,int x,int i)
{
    ListNode * p = first ;  //用指针p接收插入节点的上一个节点
    int k = 0;
    while(p!=NULL&&k<i-1)  //p节点不为空节点并且还为找到i的位置
    {
        p = p->link;  //遍历链表,找到第i-1个节点,用p指针接收
        k++;
    }
    if(p==NULL&&first!=NULL)  //不是空链表且遍历完链表没有找到第i-1个节点
    {
        printf("无效的插入位置\n");
        return 0;
    }

//找到了第i-1个节点
    //创建新节点 malloc返回值类型为(void *)强制转换为(LinkNode *)类型
    ListNode * newNode = (ListNode *)malloc(sizeof(ListNode));

    newNode->data = x;  //添加数据
    if(first==NULL||i=0)  //如果是空链表或者插入位置为头指针后
    {
        //新节点指针域指向头指针指向的节点(也就是第一个节点),或者空链表NULL,新节点也成为第一个节点。
        newNode->link = first;
        //如果为空链表,则新节点也是尾节点
        if(first==NULL) last = newNode;
        //头指针指向新的第一个节点
        first = newNode;
    }else{  //在中间或者末尾插入
        //新节点的指针域指向p节点的下一个节点
        newNode->link = p->link;
        //如果p是最后一个节点,尾指针指向新节点
        if(p->link==NULL) last = newNode;
        //p的指针域指向新节点
        p->link = newNode;
    }
    return 1;
}

③删除
删除节点

/*  参数链表
**  first:链表头指针
**  i:要删除的节点
*/  
int Delete(LinkList & first,int i)
{
    ListNode *p,*q;  //用q指针指向删除的节点,以便释放
    if(i==0)  //删除第一个结点
    {
        q = first;   //first指向的节点,即第一个节点 
        first = first->link;  //将first指向原节点的下一个节点
    }else{
        p = first;
        int k = 0;
        while(p!==NULL&&k<i-1)
        {
            p = p->link;  
            k++;   //遍历链表,直到p为空或是找到第i-1个节点
        }
        if(p==NULL||p->link==NULL)  //没找到第i-1个节点但是链表结束了
        {
            printf("无效的删除位置\n");
            return 0;
        }else{
            q = p->link;
            p->link= q->link;
        }
        if(q==last){   //如果p->link节点是尾节点
            last = p;  //尾指针指向p指针指向的节点
        }
        k = q->data;  //用k接收删除节点的数据域
        free(q);   //释放q指针指向的内存空间
        return k;  //返回删除的数据
    }
}

2.带头结点的单链表
①插入
插入节点
/* 参数列表
** first:链表头指针
** x:插入节点数据域
** i:插入的位置
*/

int Insert(LinkList first,ListData x,int i)
{
    ListNode * p;
    int k = 0;
    while(p!=NULL&&k< i-1)
    {
        p = p->link;
        k++;
    }
    if(p==NULL){
        printf("无效的插入位置\n");
        return 0;
    }
    ListNode * newNode = (ListNode *)malloc(sizeof(ListNode));
    newNode->data = x;
    newNode->link = p->link;  //新节点指针域指向p的后继
    p->link = newNode;   //p的后继为插入的节点
    return 1;
}

②删除
删除节点

int Delete(ListLink first,int i)
{
    ListNode * p ,*q;
    int k = 0;
    while(p!=NULL&&k< i-1)
    {
        p = p->link;
        k++;
    }
    if(p==NULL||p->link==NULL){
        printf("无效的删除节点\n");
        return 0;
    }
    q = p->link;  //找到第i-1个节点,将指针p指向该节点的后继
    p->link = q->link;  //将第i-1个节点的指针域指向原本后继的后继
    free(q);
    return 1;
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 1.(单选题,1.9 分) 以下关于线性表的叙述,正确的是( )。 Ⅰ 线性表中每个数据元素都有一个前驱和一个后继 Ⅱ 线性表中的所有元素必须按由小到大或由大到小的顺序排列 Ⅲ 线性表是由有限个相同类型的数据元素所构成的序列 Ⅳ 线性表基本操作的实现取决于采用哪一种存储结构,存储结构不同,实现的算法也不同 A.Ⅰ、Ⅱ、Ⅲ B.Ⅱ、Ⅲ、Ⅳ C.Ⅲ、Ⅳ D.Ⅲ 教师批阅 正确答案C, Ⅲ、Ⅳ; 我的答案:C :Ⅲ、Ⅳ; 得 1.9 分 答案解析: 本题主要用到的知识点是线性表的定义和线性表的逻辑结构特点。根据线性表的定义可知选项 Ⅱ 的叙述不正确,选项Ⅲ的叙述是正确的;根据线性表的逻辑结构特点中的"除开始结点和终端结点外,其他数据元素有且仅有一个前驱和一个后继"可知选项Ⅰ的叙述是不正确的。另外,线性表基本操作的实现方法取决于线性表所采用的存储结构,存储结构不同,实现的方法也是不同的,所以选项 Ⅳ 的叙述是正确的。 2.(单选题,1.9 分) 线性表是一个( )位置对数据元素进行入、删除操作的序列容器。 A.仅可在表头 B.仅可在表尾 C.可在任意 D.都是 教师批阅 正确答案C, 可在任意; 我的答案:C :可在任意; 得 1.9 分 答案解析: 线性表上的入、删除操作的位置是不受限制的,它是一个可在任意位置上进行入、删除操作的序列容器。 3.(单选题,1.9 分) 线性表是具有 n 个( )所构成的有限序列。 A.数据表 B.字符 C.数据元素 D.数据项 教师批阅 正确答案C, 数据元素; 我的答案:C :数据元素; 得 1.9 分 答案解析: 线性表由若干个数据元素组成,而数据元素又由若干个数据项组成。 4.(单选题,1.9 分) 以下( )是一个线性表。 A.由 n 个实数组成的集合 B.由100个字符组成的序列 C.所有整数组成的序列 D.邻接表 教师批阅 正确答案B, 由100个字符组成的序列; 我的答案:B :由100个字符组成的序列; 得 1.9 分 答案解析: 线性表定义的字句中特别要注意"有限序列"的要求,而选项 A 中指定的是集合,集合中的元素间不存在"序列"关系;选项 C 中指定的整数序列含有无穷多个数据元素,不满足"有限"的要求;选项 D 是一种存储结构。 5.(单选题,1.9 分) 在线性表中,除了开始结点外,每个元素( ) A.只有唯一的前驱 B.只有唯一的后继 C.有多个前驱 D.有多个后继 教师批阅 正确答案A, 只有唯一的前驱; 我的答案:A :只有唯一的前驱; 得 1.9 分 答案解析: 在线性表(,,...,,..., )中,除开始结点外,其他数据元素有且仅有一个前驱。对于线性表中的元素 (1≦i ≦ n -1),它的前驱是 ;除终端结点外,其他数据元素有且仅有一个后继,对于线性表中的元素 (0≦i ≦ n-2),它的后继是 。 6.(单选题,1.9 分) 设线性表有n个元素,以下操作中,( )在顺序表上实现比在链表上实现效率更高。 A.输出第i个(0≤ i ≤n-1)数据元素的值 B.交换第1个数据元素与第2个数据元素的值 C.顺序输出这n个数据元素的值 D.输出与给定值x相等的数据元素在线性表中的序号 教师批阅 正确答案A, 输出第i个(0≤ i ≤n-1)数据元素的值; 我的答案:A :输出第i个(0≤ i ≤n-1)数据元素的值; 得 1.9 分 答案解析: 由于顺序表具有随机存取的特性,所以在顺序表上按位序号读取元素的时间复杂度为O(1),而在链表上按位序号读取元素时的平均时间复杂度为O(n)。选项B、C、D中的操作,无论在顺序表,还是在链表上的实现,其时间复杂度都是相同的。 7.(单选题,1.9 分) 设线性表有n个元素,严格来说,以下操作中,( )在顺序表上实现比在链表上实现效率更高。 Ⅰ 输出第 i 个(0≤ i ≤n-1)数据元素的值 Ⅱ 交换第3个数据元素与第4个数据元素的值 Ⅲ 顺序输出这 n 个数据元素的值 A.Ⅰ B.Ⅰ、Ⅱ C.Ⅰ、Ⅲ D.Ⅱ、Ⅲ 教师批阅 正确答案B, Ⅰ、Ⅱ; 我的答案:B :Ⅰ、Ⅱ; 得 1.9 分 答案解析: 选项Ⅲ中顺序输出n个数据元素值无论是在顺序表上还是在链表上,都要依次访问每个结点,其时间复杂度是相同的,都是O(n)。还要注意:选项Ⅱ的操作在顺序表中只要直接读取到第3个和第4个数据元素值,因为顺序表具有随机存取的特性,而在链表上则要从链表的表头开始沿着后继指针依次找到第3个和第4个数据元素后,才能读取到它们的数据元素值,所以严格来讲,选项Ⅱ的操作在顺序表上的实现也要比在链表上的实现效率更高。 8.(单选题,1.9 分) 一个线性表最常用的操作是存取任意指定序号的数据元素和在最后进行入、删除操作,则用( )存储方式可以节省时间。 A.顺序表 B.双向链表 C.带头结点的双循环链表 D.单循环链表 教师批阅 正确答案A, 顺序表; 我的答案:A :顺序表; 得 1.9 分 答案解析: 由于只有顺序表具有随机存取的特性且在最后进行入、删除操作时不会引起数据元素的移动,所以其操作的时间复杂度都为O(1)。而链表是一种支持顺序存取的存储结构,在这种存储结构上按序号存取数据元素的平均时间复杂度是 O(n),所以选项B、C、D不正确的选项。 9.(单选题,1.9 分) 线性表的顺序存储结构是一种( )。 A.随机存取的存储结构 B.顺序存取的存储结构 C.索引存取的存储结构 D.散列存取的存储结构 教师批阅 正确答案A, 随机存取的存储结构; 我的答案:A :随机存取的存储结构; 得 1.9 分 答案解析: 顺序存储的线性表是顺序表。顺序表是一种支持随机存取的顺序存储结构。本题容易误选B,特别要注意随机存取和顺序存取是两个完全不同的概念。顺序存储是通过数组实现的,在数组中只要根据数组首地址和元素的序号值,就能很方便地访问任一元素,这就是随机存取的概念。而顺序存取是指只能按某种顺序依次去访问指定元素。 10.(单选题,1.9 分) 采用顺序存储结构的线性表的入操作中,当n个空间已满时,可申请再增加分配m个空间。若申请失败,则说明系统没有( )可分配的存储空间。 A.m个 B.m 个连续的 C.n+m 个 D.n+m 个连续的 教师批阅 正确答案D, n+m 个连续的; 我的答案:D :n+m 个连续的; 得 1.9 分 答案解析: 本题主要考查线性表的顺序存储的特点。线性表的顺序存储是指在内存中地址连续的一块存储空间依次存放线性表中的各个数据元素。 11.(单选题,1.9 分) 一个顺序表所占用的存储空间大小与( )无关。 A.表的长度 B.元素的存放顺序 C.元素的类型 D.元素中各字段的类型 教师批阅 正确答案B, 元素的存放顺序; 我的答案:B :元素的存放顺序; 得 1.9 分 答案解析一个顺序表所占用的存储空间的大小由表中的元素个数和每个元素所占的存储空间大小来决定。对于同一类型的顺序表,表越长,所占的存储空间就越大,而每个元素所占存储空间大小又是由元素的类型所决定的。所以,选项中只有元素的存放顺序与存储空间大小无关。 12.(单选题,1.9 分) 在n个元素的线性表的数组表示中,以下操作的时间复杂度为O(1)的操作是( )。 Ⅰ 访问第i个元素(0≤i ≤n-1)和求第i个元素的前驱 Ⅱ 在最后一个元素后入一新元素 Ⅲ 删除第一个元素 Ⅳ 在第i个结点后一个结点(0≤i≤n ) A.Ⅰ B.Ⅱ、Ⅲ C.Ⅰ、Ⅱ D.Ⅰ、Ⅱ、Ⅲ 教师批阅 正确答案C, Ⅰ、Ⅱ; 我的答案:C :Ⅰ、Ⅱ; 得 1.9 分 答案解析: Ⅰ中,根据顺序表支持随机存取,其操作的时间复杂度为 O (1);Ⅱ 中,在最后一个元素后一个新元素不会引起元素的移动,故时间复杂度也为 O (1); Ⅲ 中,删除第一个元素时,其后的所有元素都需要向前移动一位,时间复杂度为 O(n); Ⅳ 中,需要向后移动n-i个元素,时间复杂度为O(n)。 13.(单选题,1.9 分) 假设在顺序表{,,...,}中,每一个数据元素所占的存储单元的数目为4,且第0个数据元素的存储地址为100,则第7个数据元素的存储地址是( )。 A.106 B.107 C.124 D.128 教师批阅 正确答案D, 128; 我的答案:D :128; 得 1.9 分 答案解析: 根据顺序表中数据元素的地址计算公式: Loc ()= Loc ()+ i×c ,可得:Loc ()= Loc ()+7×4=100+28=128。本题特別要注意题目中i的取值范围,本题指明线性表是{,,...,},这说明 i 的范围是0≤i ≤n-1。如果题目中指明1≤ i≤n ,则地址公式应为 Loc ()= Loc ()+(i-1)×c 。 14.(单选题,1.9 分) 在线性表中,若经常要存取第i个数据元素及其前趋,则宜采用( )存储方式。 A.顺序表 B.带头结点的单链表 C.不带头结点的单链表 D.循环单链表 教师批阅 正确答案A, 顺序表; 我的答案:A :顺序表; 得 1.9 分 答案解析: 只有顺序表具有随机存取的特性。 15.(单选题,1.9 分) 要将一个顺序表{ , ,..., }中的第i个数据元素 (0≤i≤n-1)删除,需要移动( )个数据元素。 A.i B.n-i-1 C.n-i D.n-i+1 教师批阅 正确答案B, n-i-1; 我的答案:B :n-i-1; 得 1.9 分 答案解析: 要删除第i个数据元素 (0≤ i ≤ n-1)会引起至的所有元素前移一位。这种类型的题目也要特别注意题目中给定的i的取值范围,若 i 范围为1≤i≤n,则移动次数是 n-i。 16.(单选题,1.9 分) 关于线性表的顺序存储结构和链式存储结构,描述正确的是( )。 Ⅰ 线性表的顺序存储结构优于其链式存储结构 Ⅱ 链式存储结构比顺序存储结构能更方便地表示各种逻辑结构 Ⅲ 如频繁进行入、删除结点操作,顺序存储结构更优于链式存储结构 Ⅳ 顺序存储结构和链式存储结构都可以进行顺序存取 A.Ⅰ、Ⅱ、Ⅲ B.Ⅱ、Ⅳ C.Ⅱ、Ⅲ D.Ⅲ、Ⅳ 教师批阅 正确答案B, Ⅱ、Ⅳ; 我的答案:B :Ⅱ、Ⅳ; 得 1.9 分 答案解析: 两种存储结构有不同的适用场合,不能简单地说哪种好与哪种坏,故Ⅰ错误。链式存储结构是用指针来描述逻辑结构,而指针的设置是任意的,故可以很方便地表示各种逻辑结构;而顺序存储结构只能用物理上的相邻关系来表示逻辑结构,所以Ⅱ正确。在顺序存储结构中,入、删除结点会引起大量数据元素的移动,而在链式存储结构上则不会,故Ⅲ错误。顺序存储结构既可以随机存取,也能按顺序存取;而链式存储结构只可以顺序存取,所以Ⅳ正确。 17.(单选题,1.9 分) 在单链表中,增加一个头结点的目的是为了( )。 A.使单链表至少有一个结点 B.标识表结点中首结点的位置 C.方便运算的实现 D.说明单链表是线性表的链式存储 教师批阅 正确答案C, 方便运算的实现; 我的答案:C :方便运算的实现; 得 1.9 分 答案解析: 为单链表设置头结点的目的是为了方便运算的实现。主要好处体现在:一方面,有了头结点后,在单链表上实现入、删除操作无论是在什么位置上进行,其算法都是相同的,不需要针对是否在第一个结点之前入、删除结点做另外的处理;另一方面,无论链表是否为空,链表的表指针始终都指向链表的头结点。 18.(单选题,1.9 分) 在链表中,若经常要删除表中最后一个结点或在最后一个结点之后一个新结点,则宜采用( )存储方式。 A.顺序表 B.用头指针标识的单循环链表 C.用尾指针标识的单循环链表 D.双向链表 教师批阅 正确答案D, 双向链表; 我的答案:D :双向链表; 得 1.9 分 答案解析: 题干中已指明了是"在链表中",故排除了选项 A 。对于选项 B 中的链表,访问最后一个结点的时间复杂度为 O(n)。对于选项 C 中的链表,要删除最后一个结点,需要找到这个结点的前驱,其时间复杂度为 O(n)。而对于选项 D 中的链表,它未指明是循环链表,还是非循环链表,所以不能否定它不是循环链表;而对于双向循环链表,要删除表中量后一个结点或在最后一个结点之后一个新结点的时间复杂度都为 O (1)。所以,排除了两个时间复杂度为 O(1)的选项 B 和选项 C 。 19.(单选题,1.9 分) 如果对含有 n ( n >1)个元素的线性表的运算只有4种,即删除第一个元素,删除最后一个元素,在第一个元素前面入新元素,在最后一个元素的后面入新元素,最好使用( )。 A.只有表尾指针没有表头指针的单循环链表 B.既有表尾指针又有表头指针的单循环链表 C.只有表尾指针没有表头指针的非循环双向链表 D.只有表头指针没有表尾指针的循环双向链表 教师批阅 正确答案D, 只有表头指针没有表尾指针的循环双向链表; 我的答案:D :只有表头指针没有表尾指针的循环双向链表; 得 1.9 分 答案解析: 只有在选项D的链表中实现题目的4种运算,其时间复杂度都为O(1)。 20.(单选题,1.9 分) 将长度为 n 的单链表链接在长度为 m 的单链表后面,其算法的时间复杂度为( )。 A.O (1) B.O(n) C.O ( m) D.O ( m + n ) 教师批阅 正确答案C, O ( m); 我的答案:C :O ( m); 得 1.9 分 答案解析: 方法是先在长度为 m 的单链表中找到尾结点,其时间复杂度为 O(m),然后再将此尾结点的 next 域置为另一个单链表的首结点的地址值。 21.(单选题,1.9 分) 设线性表中有 n 个元素,( )在单链表上实现要比在顺序表上实现效率更高。 A.删除所有值为 x 的元素 B.在最后一个元素的后面一个新元素 C.顺序输入 k 个元素 D.交换第 i 个元素和第 n-i-1个元素的值( i =0,…, n-1) 教师批阅 正确答案A, 删除所有值为 x 的元素; 我的答案:A :删除所有值为 x 的元素; 得 1.9 分 答案解析: A 中对于单链表和顺序表上实现的时间复杂度都为 O ( n ),但在顺序表上要移动很多元素,所以在单链表上实现效率更高。 B 和 D 效率刚好相反, C 无区别。 22.(单选题,1.9 分) 在双向链表存储结构中,删除 p 所指结点时修改链的 Java 语句序列是( )。 A.p.getPrior ( ). setNext ( p.getNext ( ) ); p.getNext.setPrior ( p.getPrior ( ) ); B. p.setPrior ( p.getPrior ( ). getPrior ( ) ); p.getPrior ( ). setNext ( p ); C.p.getNext ( ).setPrior ( p ); p.setNext ( p.getNext ( ). getNext ( ) ); D. p.setNext ( p.getPrior ( ). getPrior ( ) ); p.setPrior ( p.getNext ( ). getNext ( ) ); 教师批阅 正确答案A, p.getPrior ( ). setNext ( p.getNext ( ) ); p.getNext.setPrior ( p.getPrior ( ) );; 我的答案:A :p.getPrior ( ). setNext ( p.getNext ( ) ); p.getNext.setPrior ( p.getPrior ( ) );; 得 1.9 分 答案解析: 删除 p 结点之后,则 p 的前驱的后继就不再是 p ,而是 p 的后继; p 后继的前驱也不再是 p,而是 p 的前驱。选项 A 满足此条件。 23.(单选题,1.9 分) 在一个单链表中的 p 和 q 两个结点之间一个新结点,假设新结点为 s,则修改链的 Java 语句序列是( )。 A. s.setNext ( p ); q.setNext ( s ); B. p.setNext ( s.getNext ( ) ); s.setNext ( p ); C.q.setNext ( s.getNext ( ) ); s.setNext ( p ); D. p.setNext ( s ); s.setNext ( q ); 教师批阅 正确答案D, p.setNext ( s ); s.setNext ( q );; 我的答案:D : p.setNext ( s ); s.setNext ( q );; 得 1.9 分 答案解析: s 入后, p 成为 s 的前驱, q 成为 s 的后继,选项 D 满足此条件。 24.(单选题,1.9 分) 在一个含有 n 个结点的有序单链表一个新结点,使单链表仍然保持有序的算法的时间复杂度是( )。 A.O(1) B.O() C.O(n) D.O() 教师批阅 正确答案C, O(n); 我的答案:C :O(n); 得 1.9 分 答案解析: 要实现题目中的入操作,首先要在有序单链表中查找到入的位置,然后再将新结点循入到查找到的位置上。其中查找操作的时间复杂度为 O ( n )。 25.(单选题,1.9 分) 在带头结点的双向循环链表中的 p 结点之后一个新结点 s ,其修改链的 Java 语句序列是( )。 A.p.setNext ( s ); s.setPrior ( p ); p.getNext ( ). setPrior ( s ); s.setNext ( p.getPrior ( ) ); B. p.setNext ( s ); p.getNext ( ). setPrior ( s ); s.setPrior (p); s.setNext ( p.getNext( ) ); C. s.setPrior ( p ); s.setNext ( p.getNext ( ) ); p.setNext ( s ); p.getNext ( ). setPrior ( s ); D. s.setNext ( p.getNext ( ) ); s.setPrior ( p ); p.getNext ( ). setPrior ( s ); p.setNext ( s ); 教师批阅 正确答案D, s.setNext ( p.getNext ( ) ); s.setPrior ( p ); p.getNext ( ). setPrior ( s ); p.setNext ( s );; 我的答案:D : s.setNext ( p.getNext ( ) ); s.setPrior ( p ); p.getNext ( ). setPrior ( s ); p.setNext ( s );; 得 1.9 分 答案解析: 结点 s 到 p 的后面之后, s 的后继是 p 的后继; s 的前驱就是 p ; p 的后继的前驱是 s ; p的后继是 s 。只有 D 满足此条件。 26.(单选题,1.9 分) 对于图2.9所示的单链表,下列表达式值为真的是( )。 A. head.getNext ( ). getData( ) ==' C ' B.head.getData ( )==' B ' C..getData( )==' D ' D..getNext()== null 教师批阅 正确答案D, .getNext()== null ; 我的答案:D :.getNext()== null ; 得 1.9 分 答案解析: 选项 A 指明 head 的后继是数据域值为' C '的结点,错误;选项 B 指明 head 所指的结点数据域值为' B '的结点,错误;选项 C 指明 所指的结点是数据域值为' D '的结点,错误; 选项 D 指明所指结点的后继为空,正确。 27.(填空题, 1.9 分) 当线性表的长度是基本稳定的,且很少进行入、删除操作时,则该线性表宜采用________存储结构。 顺序 教师批阅 得 1.9 分 正确答案: (1) 顺序 28.(填空题, 1.9 分) 在表长为 n 的顺序表中一个数据元素,需要平均移动________个元素;在顺序表中删除一个数据元素,需要平均移动________个数据元素。 (1) n/2 (2) (n-1)/2 教师批阅 得 1.9 分 正确答案: (1) n/2 (2) (n-1)/2 29.(填空题, 1.9 分) 在表长为n的顺序表中查找值为 x 的数据元素时,查找成功时需与元素比较的平均次数是________。 (n+1)/2 教师批阅 得 1.9 分 正确答案: (1) (n+1)/2 30.(填空题, 1.9 分) 线性表由 n ( n ≥0)个数据元素构成,其中 n 为数据元素的个数,称为线性表的________, n=0的线性表称为________。 (1) 长度 (2) 空表 教师批阅 得 1.9 分 正确答案: (1) 长度 (2) 空表 31.(填空题, 1.9 分) 线性表中有且仅有一个开始结点和终端结点,除开始结点和终端结点之外,其他每一个数据元素有且仅有一个________,有且仅有一个________。 (1) 前驱 (2) 后继 教师批阅 得 1.9 分 正确答案: (1) 前驱 (2) 后继 32.(填空题, 1.9 分) 线性表通常采用________和________两种存储结构。若线性表的长度确定或变化不大,则适合采用_________结构进行存储。 (1) 顺序存储 (2) 链式存储 (3) 顺序存储 教师批阅 得 1.9 分 正确答案: (1) 顺序存储;链式存储 (2) 顺序存储;链式存储 (3) 顺序存储 33.(填空题, 1.9 分) 在顺序表{ ,,..., }中的第 i ( 0 ≤ i ≤ n-1)个位置之前一个新的数据元素,会引起________个数据元素的移动操作。 n-i 教师批阅 得 1.9 分 正确答案: (1) n-i 34.(填空题, 1.9 分) 在一个单链表中 p 所指结点之前一个 s 所指结点时,可执行如下操作: s.setNext (____①____); p.setNext ( s ); t = p.getData( ); p.setData (____②____); s.setData (____③____); (1) p.getNext() (2) s.getData() (3) t 教师批阅 得 1.9 分 正确答案: (1) p.getNext() (2) s.getData() (3) t 答案解析: 采用的方法是先将 s 所指结点入 p 所指结点的后面,然后再将 p 所指结点和 s 所指结点的数据域进行交换。 35.(填空题, 1.9 分) 在一个单链表中删除 p 所指结点时,可执行如下操作: q = p.getNext( ); p.setData ( q . getData ( ) ); p.setNext (________); q.getNext() 教师批阅 得 1.9 分 正确答案: (1) q.getNext();p.getNext().getNext() 答案解析: 答案是q.getNext() 或者 p.getNext().getNext(),采用的方法是将 p 所指结点与其后继结点的数据域进行交换,再删除 p 所指结点的后继结点。 36.(填空题, 1.9 分) 在一个含有 n 个结点的有序单链表一个新结点并使之仍然保持有序的操作,其时间复杂度为________。 O(n) 教师批阅 得 1.9 分 正确答案: (1) O(n) 37.(填空题, 1.9 分) 带头结点的双向循环链表 head 为空的条件是________。 head.getNext()==head.getPrior()==null 教师批阅 得 1.9 分 正确答案: (1) head.getNext ()==head.getPrior()==null 38.(填空题, 1.9 分) 在双向链表的指定结点 p 之前一个新结点 s ,需执行的修改链的 Java 语句序列分别是________;________;________;________。 (1) p.getPrior().setNext(s) (2) s.setPrior(p.getPrior()) (3) s.setNext(p) (4) p.setPrior(s) 教师批阅 得 1.9 分 正确答案: (1) p.getPrior().setNext(s); (2) s.setPrior(p.getPrior()); (3) s.setNext(p); (4) p.setPrior(s); 39.(填空题, 1.9 分) 在线性表的单链表存储结构中,每一个结点有两个域,一个是数据域,用于存储数据元素值本身,另一个是_________,用于存储后继节点的地址。 指针域 教师批阅 得 1.9 分 正确答案: (1) 指针域 40.(填空题, 1.9 分) 在线性表的顺序存储结构中可实现快速的随机存取,而在链式存储结构中则只能进行________存取。 顺序 教师批阅 得 1.9 分 正确答案: (1) 顺序 41.(填空题, 2 分) 顺序表中逻辑上相邻的数据元素,其物理位置________相邻,而在单链表中逻辑上相邻的数据元素,其物理位置________相邻。 (1) 一定 (2) 不一定 教师批阅 得 2 分 正确答案: (1) 一定 (2) 不一定 42.(填空题, 2 分) 在仅设置了尾指针的循环链表中,访问第一个结点的时间复杂度是________。 O(1) 教师批阅 得 2 分 正确答案: (1) O(1) 43.(填空题, 2 分) 若将单链表中的最后一个结点的指针域值改为单链表中头结点的地址值,则这个链表就构成了________。 循环单链表 教师批阅 得 2 分 正确答案: (1) 循环单链表 44.(填空题, 2 分) 对于一个头指针为 head 的带头结点的单链表,判定该表为空表的条件是__①____;对于不带表头结点的单链表,则判定空表的条件为____②____。 (填选项大写字母) A . head == null B . head . getNext( )== null C . head . getNext( )== head D . head != null (1) B (2) A 教师批阅 得 2 分 正确答案: (1) B (2) A 答案解析: 在带头结点的单链表中, head 指向头结点,由头结点的 next 域指向首结点(第1个元素结点),则 head.getNext ()== null 表示该单链表为空。在不带头结点的单链表中, head 直接指向首结点,所以 head == null 表示单链表为空。 45.(填空题, 2 分) 顺序表的存储密度是_____①_____,而单链表的存储密度是______②______。(填选项大写字母) A.小于1 B.等于1 C.大于1 D.不能确定 (1) B (2) A 教师批阅 得 2 分 正确答案: (1) B (2) A 答案解析: 因为顺序表中只存放数据元素值本身,所以存储密度为1,而在单链表中,每个结点除了存储数据元素值本身之外,还要存放其后继结点的存储地址,所以存储密度小于1。 46.(填空题, 2 分) 线性表的顺序存储结构类描述如下: public class SqList{ private Object[]listElem; //线性表存储空间 private int curLen;//线性表的当前长度 …… } 下面的核心算法实现了在当前顺序表上的入操作,请将算法补充完整 void insert(int i, object x)throws Exception{ if ( ________ ) //判断顺序表是否已满 throw new Exception("顺序表已满"); //抛出异常 if ( ________ ) //i不合法 throw new Exception("入位置不合法");//抛出异常 for(int j = curLen; j > i; ________ ){ ________ ; //入位置及其之后的所有元素后移一位 } ________; //入x ________;//表长加1 } (1) curLen==listElem.length (2) i<0||i>curLen (3) j-- (4) listElem[j]=listElem[j-1] (5) listElem[i]=x (6) curLen++ 教师批阅 得 2 分 正确答案: (1) curLen==listElem.length (2) i<0||i>curLen (3) j-- (4) listElem[j]=listElem[j-1] (5) listElem[i]=x (6) curLen++ 47.(填空题, 2 分) 线性表的顺序存储结构类描述如下: public class SqList{ private Object[]listElem; //线性表存储空间 private int curLen;//线性表的当前长度 …… } 下面的核心算法实现了在当前顺序表上的删除操作,请将算法补充完整 void remove(int i) throws Exception{ if ( ________ ) //i不合法 throw new Exception(”删除位置不合法");//抛出异常 for( ________ ; ________ ; j++){ ________ = ________; //被删除元素及其之后的元素左移一个存储位置 } ________; //表长减1 } (1) i<0||i>curLen-1 (2) int j=i (3) j<curLen-1 (4) listElem[j] (5) listElem[j+1] (6) curLen-- 教师批阅 得 2 分 正确答案: (1) i<0 || i>curLen-1 (2) int j=i (3) j<curLen-1 (4) listElem[j] (5) listElem[j+1] (6) curLen-- 48.(填空题, 2 分) 线性表的顺序存储结构类描述如下: public class SqList{ private Object[]listElem; //线性表存储空间 private int curLen;//线性表的当前长度 } 下面的核心算法实现了在当前顺序表上的查找操作,请将算法补充完整 int indexof(Object x){ int j = 0;//j指示顺序表中待比较的元素,其初始值指示顺序表中的第0个元素 while( ________ && ! listElem[j].equals(x))//依次比较 j++; if (j < curLen)//判断j的位置是否位于顺序表中 ________ ;//返回×元素在顺序表中的位置 else ________ ;//×元素在顺序表中不存在 } (1) j<curLen (2) return j (3) return -1 教师批阅 得 2 分 正确答案: (1) j<curLen (2) return j (3) return -1 49.(填空题, 2 分) //单链表节点类描述如下 class Node{ private Object data;//存放结点值 private Node next;//后继结点的引用 //无参数构造方法 public Node(){ this(null, null); } //带一个参数的构造方法 public Node(Object data){ this(data, null); } //带两个参数的构造方法 public Node(Object data, Node next) { this.data = data; this.next = next; } //... } //下面是用头法创建带头结点的单链表L的操作,请将算法补充完整 class LinkList{ //用头法实现创建带头结点的单链表L的操作算法 public static void creat(LinkList L) throws Exception{ Scanner sc = new Scanner(System.in); //构造用于输入的对象 System.out.println("请输入链表中的各个元素值(0为结束)"); for(int x = sc.nextInt(); x != 0; x = ___(1)_____ ) //输入n个元素的值 ___(2)_____;//将x结点入到链表L的表头 } (1) sc.nextint() (2) L.insert(0,x) 教师批阅 得 2 分 正确答案: (1) sc.nextInt() (2) L.insert(0,x) 50.(填空题, 2 分) //下面是在当前带头结点的单链表上实现查找操作的算法,请将算法补充完整 Object get(int i) throws Exception{ Node p = ____(1)____ ;//初始化,p指向首结点,j为计数器 int j = 0; while(p != null && j < i){//从首节点开始向后查找,直到p指向第i个结点或p为空 p = ____(2)____ ;//指向后继结点 _____(3)___ ;//计数器的值增加1 } if(j >i || p == null){//i小于0或者大于表长减1 throw new Exception("第" + i + "个元素不存在"); //抛出异常 } return ___(4)_____ ;//返回结点p的数据域的值 } (1) head.getNext() (2) p.getNext() (3) ++j (4) p.getData() 教师批阅 得 2 分 正确答案: (1) head.getNext() (2) p.getNext() (3) ++j (4) p.getData() 51.(填空题, 2 分) //下面是在当前带头结点的单链表上实现入操作的算法,请将算法补充完整 void insert(int i, Object x) throws Exception{ Node p = ____(1)____ ;//初始化p为头结点,j为计数器 int j = -1; while(p !=null && j < i - 1){//寻找待入的位置,即第i个结点的前驱结点 p = ____(2)____ ;//指针p向后移动一位 ____(3)____ ;//计数器加1 } if (j > i - 1 || p == null){//i不合法 throw new Exception("入位置不合理");//抛出异常 } Node s = ____(4)____ ;//生成新的待入结点s //将结点s单链表中 s.setNext( ____(5)____ ); p.setNext( ____(6)____ ); } (1) head (2) p.getNext() (3) ++j (4) new Node(x) (5) p.getNext() (6) s 教师批阅 得 2 分 正确答案: (1) head (2) p.getNext() (3) ++j (4) new Node(x) (5) p.getNext() (6) s 52.(填空题, 2 分) //下面是在当前带头结点的单链表上实现删除操作的算法,请将算法补充完整 void remove (int i) throws Exception{ Node p = head;//初始化p为头结点,j为计数器 int j = -1; while( ________ && j < i - 1){ //寻找待删除的位置,即第i个结点的前驱结点 p = p.getNext();//指针p向后移动一位 ++j;//计数器加1 } if ( ________ || p.getNext() == null){//i小于0或者大于表长减1 throw new Exception("删除位置不合理");//抛出异常 } p.setNext( ________ );//删除结点 } (1) p.getNext()!=null (2) j>i-1 (3) p.getNext().getNext() 教师批阅 得 2 分 正确答案: (1) p.getNext() != null (2) j>i-1 (3) p.getNext().getNext() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 1.(单选题,1.9 分) 以下关于线性表的叙述,正确的是( )。 Ⅰ 线性表中每个数据元素都有一个前驱和一个后继 Ⅱ 线性表中的所有元素必须按由小到大或由大到小的顺序排列 Ⅲ 线性表是由有限个相同类型的数据元素所构成的序列 Ⅳ 线性表基本操作的实现取决于采用哪一种存储结构,存储结构不同,实现的算法也不同 A.Ⅰ、Ⅱ、Ⅲ B.Ⅱ、Ⅲ、Ⅳ C.Ⅲ、Ⅳ D.Ⅲ 教师批阅 正确答案C, Ⅲ、Ⅳ; 我的答案:C :Ⅲ、Ⅳ; 得 1.9 分 答案解析: 本题主要用到的知识点是线性表的定义和线性表的逻辑结构特点。根据线性表的定义可知选项 Ⅱ 的叙述不正确,选项Ⅲ的叙述是正确的;根据线性表的逻辑结构特点中的"除开始结点和终端结点外,其他数据元素有且仅有一个前驱和一个后继"可知选项Ⅰ的叙述是不正确的。另外,线性表基本操作的实现方法取决于线性表所采用的存储结构,存储结构不同,实现的方法也是不同的,所以选项 Ⅳ 的叙述是正确的。 2.(单选题,1.9 分) 线性表是一个( )位置对数据元素进行入、删除操作的序列容器。 A.仅可在表头 B.仅可在表尾 C.可在任意 D.都是 教师批阅 正确答案C, 可在任意; 我的答案:C :可在任意; 得 1.9 分 答案解析: 线性表上的入、删除操作的位置是不受限制的,它是一个可在任意位置上进行入、删除操作的序列容器。 3.(单选题,1.9 分) 线性表是具有 n 个( )所构成的有限序列。 A.数据表 B.字符 C.数据元素 D.数据项 教师批阅 正确答案C, 数据元素; 我的答案:C :数据元素; 得 1.9 分 答案解析: 线性表由若干个数据元素组成,而数据元素又由若干个数据项组成。 4.(单选题,1.9 分) 以下( )是一个线性表。 A.由 n 个实数组成的集合 B.由100个字符组成的序列 C.所有整数组成的序列 D.邻接表 教师批阅 正确答案B, 由100个字符组成的序列; 我的答案:B :由100个字符组成的序列; 得 1.9 分 答案解析: 线性表定义的字句中特别要注意"有限序列"的要求,而选项 A 中指定的是集合,集合中的元素间不存在"序列"关系;选项 C 中指定的整数序列含有无穷多个数据元素,不满足"有限"的要求;选项 D 是一种存储结构。 5.(单选题,1.9 分) 在线性表中,除了开始结点外,每个元素( ) A.只有唯一的前驱 B.只有唯一的后继 C.有多个前驱 D.有多个后继 教师批阅 正确答案A, 只有唯一的前驱; 我的答案:A :只有唯一的前驱; 得 1.9 分 答案解析: 在线性表(,,...,,..., )中,除开始结点外,其他数据元素有且仅有一个前驱。对于线性表中的元素 (1≦i ≦ n -1),它的前驱是 ;除终端结点外,其他数据元素有且仅有一个后继,对于线性表中的元素 (0≦i ≦ n-2),它的后继是 。 6.(单选题,1.9 分) 设线性表有n个元素,以下操作中,( )在顺序表上实现比在链表上实现效率更高。 A.输出第i个(0≤ i ≤n-1)数据元素的值 B.交换第1个数据元素与第2个数据元素的值 C.顺序输出这n个数据元素的值 D.输出与给定值x相等的数据元素在线性表中的序号 教师批阅 正确答案A, 输出第i个(0≤ i ≤n-1)数据元素的值; 我的答案:A :输出第i个(0≤ i ≤n-1)数据元素的值; 得 1.9 分 答案解析: 由于顺序表具有随机存取的特性,所以在顺序表上按位序号读取元素的时间复杂度为O(1),而在链表上按位序号读取元素时的平均时间复杂度为O(n)。选项B、C、D中的操作,无论在顺序表,还是在链表上的实现,其时间复杂度都是相同的。 7.(单选题,1.9 分) 设线性表有n个元素,严格来说,以下操作中,( )在顺序表上实现比在链表上实现效率更高。 Ⅰ 输出第 i 个(0≤ i ≤n-1)数据元素的值 Ⅱ 交换第3个数据元素与第4个数据元素的值 Ⅲ 顺序输出这 n 个数据元素的值 A.Ⅰ B.Ⅰ、Ⅱ C.Ⅰ、Ⅲ D.Ⅱ、Ⅲ 教师批阅 正确答案B, Ⅰ、Ⅱ; 我的答案:B :Ⅰ、Ⅱ; 得 1.9 分 答案解析: 选项Ⅲ中顺序输出n个数据元素值无论是在顺序表上还是在链表上,都要依次访问每个结点,其时间复杂度是相同的,都是O(n)。还要注意:选项Ⅱ的操作在顺序表中只要直接读取到第3个和第4个数据元素值,因为顺序表具有随机存取的特性,而在链表上则要从链表的表头开始沿着后继指针依次找到第3个和第4个数据元素后,才能读取到它们的数据元素值,所以严格来讲,选项Ⅱ的操作在顺序表上的实现也要比在链表上的实现效率更高。 8.(单选题,1.9 分) 一个线性表最常用的操作是存取任意指定序号的数据元素和在最后进行入、删除操作,则用( )存储方式可以节省时间。 A.顺序表 B.双向链表 C.带头结点的双循环链表 D.单循环链表 教师批阅 正确答案A, 顺序表; 我的答案:A :顺序表; 得 1.9 分 答案解析: 由于只有顺序表具有随机存取的特性且在最后进行入、删除操作时不会引起数据元素的移动,所以其操作的时间复杂度都为O(1)。而链表是一种支持顺序存取的存储结构,在这种存储结构上按序号存取数据元素的平均时间复杂度是 O(n),所以选项B、C、D不正确的选项。 9.(单选题,1.9 分) 线性表的顺序存储结构是一种( )。 A.随机存取的存储结构 B.顺序存取的存储结构 C.索引存取的存储结构 D.散列存取的存储结构 教师批阅 正确答案A, 随机存取的存储结构; 我的答案:A :随机存取的存储结构; 得 1.9 分 答案解析: 顺序存储的线性表是顺序表。顺序表是一种支持随机存取的顺序存储结构。本题容易误选B,特别要注意随机存取和顺序存取是两个完全不同的概念。顺序存储是通过数组实现的,在数组中只要根据数组首地址和元素的序号值,就能很方便地访问任一元素,这就是随机存取的概念。而顺序存取是指只能按某种顺序依次去访问指定元素。 10.(单选题,1.9 分) 采用顺序存储结构的线性表的入操作中,当n个空间已满时,可申请再增加分配m个空间。若申请失败,则说明系统没有( )可分配的存储空间。 A.m个 B.m 个连续的 C.n+m 个 D.n+m 个连续的 教师批阅 正确答案D, n+m 个连续的; 我的答案:D :n+m 个连续的; 得 1.9 分 答案解析: 本题主要考查线性表的顺序存储的特点。线性表的顺序存储是指在内存中地址连续的一块存储空间依次存放线性表中的各个数据元素。 11.(单选题,1.9 分) 一个顺序表所占用的存储空间大小与( )无关。 A.表的长度 B.元素的存放顺序 C.元素的类型 D.元素中各字段的类型 教师批阅 正确答案B, 元素的存放顺序; 我的答案:B :元素的存放顺序; 得 1.9 分 答案解析一个顺序表所占用的存储空间的大小由表中的元素个数和每个元素所占的存储空间大小来决定。对于同一类型的顺序表,表越长,所占的存储空间就越大,而每个元素所占存储空间大小又是由元素的类型所决定的。所以,选项中只有元素的存放顺序与存储空间大小无关。 12.(单选题,1.9 分) 在n个元素的线性表的数组表示中,以下操作的时间复杂度为O(1)的操作是( )。 Ⅰ 访问第i个元素(0≤i ≤n-1)和求第i个元素的前驱 Ⅱ 在最后一个元素后入一新元素 Ⅲ 删除第一个元素 Ⅳ 在第i个结点后一个结点(0≤i≤n ) A.Ⅰ B.Ⅱ、Ⅲ C.Ⅰ、Ⅱ D.Ⅰ、Ⅱ、Ⅲ 教师批阅 正确答案C, Ⅰ、Ⅱ; 我的答案:C :Ⅰ、Ⅱ; 得 1.9 分 答案解析: Ⅰ中,根据顺序表支持随机存取,其操作的时间复杂度为 O (1);Ⅱ 中,在最后一个元素后一个新元素不会引起元素的移动,故时间复杂度也为 O (1); Ⅲ 中,删除第一个元素时,其后的所有元素都需要向前移动一位,时间复杂度为 O(n); Ⅳ 中,需要向后移动n-i个元素,时间复杂度为O(n)。 13.(单选题,1.9 分) 假设在顺序表{,,...,}中,每一个数据元素所占的存储单元的数目为4,且第0个数据元素的存储地址为100,则第7个数据元素的存储地址是( )。 A.106 B.107 C.124 D.128 教师批阅 正确答案D, 128; 我的答案:D :128; 得 1.9 分 答案解析: 根据顺序表中数据元素的地址计算公式: Loc ()= Loc ()+ i×c ,可得:Loc ()= Loc ()+7×4=100+28=128。本题特別要注意题目中i的取值范围,本题指明线性表是{,,...,},这说明 i 的范围是0≤i ≤n-1。如果题目中指明1≤ i≤n ,则地址公式应为 Loc ()= Loc ()+(i-1)×c 。 14.(单选题,1.9 分) 在线性表中,若经常要存取第i个数据元素及其前趋,则宜采用( )存储方式。 A.顺序表 B.带头结点的单链表 C.不带头结点的单链表 D.循环单链表 教师批阅 正确答案A, 顺序表; 我的答案:A :顺序表; 得 1.9 分 答案解析: 只有顺序表具有随机存取的特性。 15.(单选题,1.9 分) 要将一个顺序表{ , ,..., }中的第i个数据元素 (0≤i≤n-1)删除,需要移动( )个数据元素。 A.i B.n-i-1 C.n-i D.n-i+1 教师批阅 正确答案B, n-i-1; 我的答案:B :n-i-1; 得 1.9 分 答案解析: 要删除第i个数据元素 (0≤ i ≤ n-1)会引起至的所有元素前移一位。这种类型的题目也要特别注意题目中给定的i的取值范围,若 i 范围为1≤i≤n,则移动次数是 n-i。 16.(单选题,1.9 分) 关于线性表的顺序存储结构和链式存储结构,描述正确的是( )。 Ⅰ 线性表的顺序存储结构优于其链式存储结构 Ⅱ 链式存储结构比顺序存储结构能更方便地表示各种逻辑结构 Ⅲ 如频繁进行入、删除结点操作,顺序存储结构更优于链式存储结构 Ⅳ 顺序存储结构和链式存储结构都可以进行顺序存取 A.Ⅰ、Ⅱ、Ⅲ B.Ⅱ、Ⅳ C.Ⅱ、Ⅲ D.Ⅲ、Ⅳ 教师批阅 正确答案B, Ⅱ、Ⅳ; 我的答案:B :Ⅱ、Ⅳ; 得 1.9 分 答案解析: 两种存储结构有不同的适用场合,不能简单地说哪种好与哪种坏,故Ⅰ错误。链式存储结构是用指针来描述逻辑结构,而指针的设置是任意的,故可以很方便地表示各种逻辑结构;而顺序存储结构只能用物理上的相邻关系来表示逻辑结构,所以Ⅱ正确。在顺序存储结构中,入、删除结点会引起大量数据元素的移动,而在链式存储结构上则不会,故Ⅲ错误。顺序存储结构既可以随机存取,也能按顺序存取;而链式存储结构只可以顺序存取,所以Ⅳ正确。 17.(单选题,1.9 分) 在单链表中,增加一个头结点的目的是为了( )。 A.使单链表至少有一个结点 B.标识表结点中首结点的位置 C.方便运算的实现 D.说明单链表是线性表的链式存储 教师批阅 正确答案C, 方便运算的实现; 我的答案:C :方便运算的实现; 得 1.9 分 答案解析: 为单链表设置头结点的目的是为了方便运算的实现。主要好处体现在:一方面,有了头结点后,在单链表上实现入、删除操作无论是在什么位置上进行,其算法都是相同的,不需要针对是否在第一个结点之前入、删除结点做另外的处理;另一方面,无论链表是否为空,链表的表指针始终都指向链表的头结点。 18.(单选题,1.9 分) 在链表中,若经常要删除表中最后一个结点或在最后一个结点之后一个新结点,则宜采用( )存储方式。 A.顺序表 B.用头指针标识的单循环链表 C.用尾指针标识的单循环链表 D.双向链表 教师批阅 正确答案D, 双向链表; 我的答案:D :双向链表; 得 1.9 分 答案解析: 题干中已指明了是"在链表中",故排除了选项 A 。对于选项 B 中的链表,访问最后一个结点的时间复杂度为 O(n)。对于选项 C 中的链表,要删除最后一个结点,需要找到这个结点的前驱,其时间复杂度为 O(n)。而对于选项 D 中的链表,它未指明是循环链表,还是非循环链表,所以不能否定它不是循环链表;而对于双向循环链表,要删除表中量后一个结点或在最后一个结点之后一个新结点的时间复杂度都为 O (1)。所以,排除了两个时间复杂度为 O(1)的选项 B 和选项 C 。 19.(单选题,1.9 分) 如果对含有 n ( n >1)个元素的线性表的运算只有4种,即删除第一个元素,删除最后一个元素,在第一个元素前面入新元素,在最后一个元素的后面入新元素,最好使用( )。 A.只有表尾指针没有表头指针的单循环链表 B.既有表尾指针又有表头指针的单循环链表 C.只有表尾指针没有表头指针的非循环双向链表 D.只有表头指针没有表尾指针的循环双向链表 教师批阅 正确答案D, 只有表头指针没有表尾指针的循环双向链表; 我的答案:D :只有表头指针没有表尾指针的循环双向链表; 得 1.9 分 答案解析: 只有在选项D的链表中实现题目的4种运算,其时间复杂度都为O(1)。 20.(单选题,1.9 分) 将长度为 n 的单链表链接在长度为 m 的单链表后面,其算法的时间复杂度为( )。 A.O (1) B.O(n) C.O ( m) D.O ( m + n ) 教师批阅 正确答案C, O ( m); 我的答案:C :O ( m); 得 1.9 分 答案解析: 方法是先在长度为 m 的单链表中找到尾结点,其时间复杂度为 O(m),然后再将此尾结点的 next 域置为另一个单链表的首结点的地址值。 21.(单选题,1.9 分) 设线性表中有 n 个元素,( )在单链表上实现要比在顺序表上实现效率更高。 A.删除所有值为 x 的元素 B.在最后一个元素的后面一个新元素 C.顺序输入 k 个元素 D.交换第 i 个元素和第 n-i-1个元素的值( i =0,…, n-1) 教师批阅 正确答案A, 删除所有值为 x 的元素; 我的答案:A :删除所有值为 x 的元素; 得 1.9 分 答案解析: A 中对于单链表和顺序表上实现的时间复杂度都为 O ( n ),但在顺序表上要移动很多元素,所以在单链表上实现效率更高。 B 和 D 效率刚好相反, C 无区别。 22.(单选题,1.9 分) 在双向链表存储结构中,删除 p 所指结点时修改链的 Java 语句序列是( )。 A.p.getPrior ( ). setNext ( p.getNext ( ) ); p.getNext.setPrior ( p.getPrior ( ) ); B. p.setPrior ( p.getPrior ( ). getPrior ( ) ); p.getPrior ( ). setNext ( p ); C.p.getNext ( ).setPrior ( p ); p.setNext ( p.getNext ( ). getNext ( ) ); D. p.setNext ( p.getPrior ( ). getPrior ( ) ); p.setPrior ( p.getNext ( ). getNext ( ) ); 教师批阅 正确答案A, p.getPrior ( ). setNext ( p.getNext ( ) ); p.getNext.setPrior ( p.getPrior ( ) );; 我的答案:A :p.getPrior ( ). setNext ( p.getNext ( ) ); p.getNext.setPrior ( p.getPrior ( ) );; 得 1.9 分 答案解析: 删除 p 结点之后,则 p 的前驱的后继就不再是 p ,而是 p 的后继; p 后继的前驱也不再是 p,而是 p 的前驱。选项 A 满足此条件。 23.(单选题,1.9 分) 在一个单链表中的 p 和 q 两个结点之间一个新结点,假设新结点为 s,则修改链的 Java 语句序列是( )。 A. s.setNext ( p ); q.setNext ( s ); B. p.setNext ( s.getNext ( ) ); s.setNext ( p ); C.q.setNext ( s.getNext ( ) ); s.setNext ( p ); D. p.setNext ( s ); s.setNext ( q ); 教师批阅 正确答案D, p.setNext ( s ); s.setNext ( q );; 我的答案:D : p.setNext ( s ); s.setNext ( q );; 得 1.9 分 答案解析: s 入后, p 成为 s 的前驱, q 成为 s 的后继,选项 D 满足此条件。 24.(单选题,1.9 分) 在一个含有 n 个结点的有序单链表一个新结点,使单链表仍然保持有序的算法的时间复杂度是( )。 A.O(1) B.O() C.O(n) D.O() 教师批阅 正确答案C, O(n); 我的答案:C :O(n); 得 1.9 分 答案解析: 要实现题目中的入操作,首先要在有序单链表中查找到入的位置,然后再将新结点循入到查找到的位置上。其中查找操作的时间复杂度为 O ( n )。 25.(单选题,1.9 分) 在带头结点的双向循环链表中的 p 结点之后一个新结点 s ,其修改链的 Java 语句序列是( )。 A.p.setNext ( s ); s.setPrior ( p ); p.getNext ( ). setPrior ( s ); s.setNext ( p.getPrior ( ) ); B. p.setNext ( s ); p.getNext ( ). setPrior ( s ); s.setPrior (p); s.setNext ( p.getNext( ) ); C. s.setPrior ( p ); s.setNext ( p.getNext ( ) ); p.setNext ( s ); p.getNext ( ). setPrior ( s ); D. s.setNext ( p.getNext ( ) ); s.setPrior ( p ); p.getNext ( ). setPrior ( s ); p.setNext ( s ); 教师批阅 正确答案D, s.setNext ( p.getNext ( ) ); s.setPrior ( p ); p.getNext ( ). setPrior ( s ); p.setNext ( s );; 我的答案:D : s.setNext ( p.getNext ( ) ); s.setPrior ( p ); p.getNext ( ). setPrior ( s ); p.setNext ( s );; 得 1.9 分 答案解析: 结点 s 到 p 的后面之后, s 的后继是 p 的后继; s 的前驱就是 p ; p 的后继的前驱是 s ; p的后继是 s 。只有 D 满足此条件。 26.(单选题,1.9 分) 对于图2.9所示的单链表,下列表达式值为真的是( )。 A. head.getNext ( ). getData( ) ==' C ' B.head.getData ( )==' B ' C..getData( )==' D ' D..getNext()== null 教师批阅 正确答案D, .getNext()== null ; 我的答案:D :.getNext()== null ; 得 1.9 分 答案解析: 选项 A 指明 head 的后继是数据域值为' C '的结点,错误;选项 B 指明 head 所指的结点数据域值为' B '的结点,错误;选项 C 指明 所指的结点是数据域值为' D '的结点,错误; 选项 D 指明所指结点的后继为空,正确。 27.(填空题, 1.9 分) 当线性表的长度是基本稳定的,且很少进行入、删除操作时,则该线性表宜采用________存储结构。 顺序 教师批阅 得 1.9 分 正确答案: (1) 顺序 28.(填空题, 1.9 分) 在表长为 n 的顺序表中一个数据元素,需要平均移动________个元素;在顺序表中删除一个数据元素,需要平均移动________个数据元素。 (1) n/2 (2) (n-1)/2 教师批阅 得 1.9 分 正确答案: (1) n/2 (2) (n-1)/2 29.(填空题, 1.9 分) 在表长为n的顺序表中查找值为 x 的数据元素时,查找成功时需与元素比较的平均次数是________。 (n+1)/2 教师批阅 得 1.9 分 正确答案: (1) (n+1)/2 30.(填空题, 1.9 分) 线性表由 n ( n ≥0)个数据元素构成,其中 n 为数据元素的个数,称为线性表的________, n=0的线性表称为________。 (1) 长度 (2) 空表 教师批阅 得 1.9 分 正确答案: (1) 长度 (2) 空表 31.(填空题, 1.9 分) 线性表中有且仅有一个开始结点和终端结点,除开始结点和终端结点之外,其他每一个数据元素有且仅有一个________,有且仅有一个________。 (1) 前驱 (2) 后继 教师批阅 得 1.9 分 正确答案: (1) 前驱 (2) 后继 32.(填空题, 1.9 分) 线性表通常采用________和________两种存储结构。若线性表的长度确定或变化不大,则适合采用_________结构进行存储。 (1) 顺序存储 (2) 链式存储 (3) 顺序存储 教师批阅 得 1.9 分 正确答案: (1) 顺序存储;链式存储 (2) 顺序存储;链式存储 (3) 顺序存储 33.(填空题, 1.9 分) 在顺序表{ ,,..., }中的第 i ( 0 ≤ i ≤ n-1)个位置之前一个新的数据元素,会引起________个数据元素的移动操作。 n-i 教师批阅 得 1.9 分 正确答案: (1) n-i 34.(填空题, 1.9 分) 在一个单链表中 p 所指结点之前一个 s 所指结点时,可执行如下操作: s.setNext (____①____); p.setNext ( s ); t = p.getData( ); p.setData (____②____); s.setData (____③____); (1) p.getNext() (2) s.getData() (3) t 教师批阅 得 1.9 分 正确答案: (1) p.getNext() (2) s.getData() (3) t 答案解析: 采用的方法是先将 s 所指结点入 p 所指结点的后面,然后再将 p 所指结点和 s 所指结点的数据域进行交换。 35.(填空题, 1.9 分) 在一个单链表中删除 p 所指结点时,可执行如下操作: q = p.getNext( ); p.setData ( q . getData ( ) ); p.setNext (________); q.getNext() 教师批阅 得 1.9 分 正确答案: (1) q.getNext();p.getNext().getNext() 答案解析: 答案是q.getNext() 或者 p.getNext().getNext(),采用的方法是将 p 所指结点与其后继结点的数据域进行交换,再删除 p 所指结点的后继结点。 36.(填空题, 1.9 分) 在一个含有 n 个结点的有序单链表一个新结点并使之仍然保持有序的操作,其时间复杂度为________。 O(n) 教师批阅 得 1.9 分 正确答案: (1) O(n) 37.(填空题, 1.9 分) 带头结点的双向循环链表 head 为空的条件是________。 head.getNext()==head.getPrior()==null 教师批阅 得 1.9 分 正确答案: (1) head.getNext ()==head.getPrior()==null 38.(填空题, 1.9 分) 在双向链表的指定结点 p 之前一个新结点 s ,需执行的修改链的 Java 语句序列分别是________;________;________;________。 (1) p.getPrior().setNext(s) (2) s.setPrior(p.getPrior()) (3) s.setNext(p) (4) p.setPrior(s) 教师批阅 得 1.9 分 正确答案: (1) p.getPrior().setNext(s); (2) s.setPrior(p.getPrior()); (3) s.setNext(p); (4) p.setPrior(s); 39.(填空题, 1.9 分) 在线性表的单链表存储结构中,每一个结点有两个域,一个是数据域,用于存储数据元素值本身,另一个是_________,用于存储后继节点的地址。 指针域 教师批阅 得 1.9 分 正确答案: (1) 指针域 40.(填空题, 1.9 分) 在线性表的顺序存储结构中可实现快速的随机存取,而在链式存储结构中则只能进行________存取。 顺序 教师批阅 得 1.9 分 正确答案: (1) 顺序 41.(填空题, 2 分) 顺序表中逻辑上相邻的数据元素,其物理位置________相邻,而在单链表中逻辑上相邻的数据元素,其物理位置________相邻。 (1) 一定 (2) 不一定 教师批阅 得 2 分 正确答案: (1) 一定 (2) 不一定 42.(填空题, 2 分) 在仅设置了尾指针的循环链表中,访问第一个结点的时间复杂度是________。 O(1) 教师批阅 得 2 分 正确答案: (1) O(1) 43.(填空题, 2 分) 若将单链表中的最后一个结点的指针域值改为单链表中头结点的地址值,则这个链表就构成了________。 循环单链表 教师批阅 得 2 分 正确答案: (1) 循环单链表 44.(填空题, 2 分) 对于一个头指针为 head 的带头结点的单链表,判定该表为空表的条件是__①____;对于不带表头结点的单链表,则判定空表的条件为____②____。 (填选项大写字母) A . head == null B . head . getNext( )== null C . head . getNext( )== head D . head != null (1) B (2) A 教师批阅 得 2 分 正确答案: (1) B (2) A 答案解析: 在带头结点的单链表中, head 指向头结点,由头结点的 next 域指向首结点(第1个元素结点),则 head.getNext ()== null 表示该单链表为空。在不带头结点的单链表中, head 直接指向首结点,所以 head == null 表示单链表为空。 45.(填空题, 2 分) 顺序表的存储密度是_____①_____,而单链表的存储密度是______②______。(填选项大写字母) A.小于1 B.等于1 C.大于1 D.不能确定 (1) B (2) A 教师批阅 得 2 分 正确答案: (1) B (2) A 答案解析: 因为顺序表中只存放数据元素值本身,所以存储密度为1,而在单链表中,每个结点除了存储数据元素值本身之外,还要存放其后继结点的存储地址,所以存储密度小于1。 46.(填空题, 2 分) 线性表的顺序存储结构类描述如下: public class SqList{ private Object[]listElem; //线性表存储空间 private int curLen;//线性表的当前长度 …… } 下面的核心算法实现了在当前顺序表上的入操作,请将算法补充完整 void insert(int i, object x)throws Exception{ if ( ________ ) //判断顺序表是否已满 throw new Exception("顺序表已满"); //抛出异常 if ( ________ ) //i不合法 throw new Exception("入位置不合法");//抛出异常 for(int j = curLen; j > i; ________ ){ ________ ; //入位置及其之后的所有元素后移一位 } ________; //入x ________;//表长加1 } (1) curLen==listElem.length (2) i<0||i>curLen (3) j-- (4) listElem[j]=listElem[j-1] (5) listElem[i]=x (6) curLen++ 教师批阅 得 2 分 正确答案: (1) curLen==listElem.length (2) i<0||i>curLen (3) j-- (4) listElem[j]=listElem[j-1] (5) listElem[i]=x (6) curLen++ 47.(填空题, 2 分) 线性表的顺序存储结构类描述如下: public class SqList{ private Object[]listElem; //线性表存储空间 private int curLen;//线性表的当前长度 …… } 下面的核心算法实现了在当前顺序表上的删除操作,请将算法补充完整 void remove(int i) throws Exception{ if ( ________ ) //i不合法 throw new Exception(”删除位置不合法");//抛出异常 for( ________ ; ________ ; j++){ ________ = ________; //被删除元素及其之后的元素左移一个存储位置 } ________; //表长减1 } (1) i<0||i>curLen-1 (2) int j=i (3) j<curLen-1 (4) listElem[j] (5) listElem[j+1] (6) curLen-- 教师批阅 得 2 分 正确答案: (1) i<0 || i>curLen-1 (2) int j=i (3) j<curLen-1 (4) listElem[j] (5) listElem[j+1] (6) curLen-- 48.(填空题, 2 分) 线性表的顺序存储结构类描述如下: public class SqList{ private Object[]listElem; //线性表存储空间 private int curLen;//线性表的当前长度 } 下面的核心算法实现了在当前顺序表上的查找操作,请将算法补充完整 int indexof(Object x){ int j = 0;//j指示顺序表中待比较的元素,其初始值指示顺序表中的第0个元素 while( ________ && ! listElem[j].equals(x))//依次比较 j++; if (j < curLen)//判断j的位置是否位于顺序表中 ________ ;//返回×元素在顺序表中的位置 else ________ ;//×元素在顺序表中不存在 } (1) j<curLen (2) return j (3) return -1 教师批阅 得 2 分 正确答案: (1) j<curLen (2) return j (3) return -1 49.(填空题, 2 分) //单链表节点类描述如下 class Node{ private Object data;//存放结点值 private Node next;//后继结点的引用 //无参数构造方法 public Node(){ this(null, null); } //带一个参数的构造方法 public Node(Object data){ this(data, null); } //带两个参数的构造方法 public Node(Object data, Node next) { this.data = data; this.next = next; } //... } //下面是用头法创建带头结点的单链表L的操作,请将算法补充完整 class LinkList{ //用头法实现创建带头结点的单链表L的操作算法 public static void creat(LinkList L) throws Exception{ Scanner sc = new Scanner(System.in); //构造用于输入的对象 System.out.println("请输入链表中的各个元素值(0为结束)"); for(int x = sc.nextInt(); x != 0; x = ___(1)_____ ) //输入n个元素的值 ___(2)_____;//将x结点入到链表L的表头 } (1) sc.nextint() (2) L.insert(0,x) 教师批阅 得 2 分 正确答案: (1) sc.nextInt() (2) L.insert(0,x) 50.(填空题, 2 分) //下面是在当前带头结点的单链表上实现查找操作的算法,请将算法补充完整 Object get(int i) throws Exception{ Node p = ____(1)____ ;//初始化,p指向首结点,j为计数器 int j = 0; while(p != null && j < i){//从首节点开始向后查找,直到p指向第i个结点或p为空 p = ____(2)____ ;//指向后继结点 _____(3)___ ;//计数器的值增加1 } if(j >i || p == null){//i小于0或者大于表长减1 throw new Exception("第" + i + "个元素不存在"); //抛出异常 } return ___(4)_____ ;//返回结点p的数据域的值 } (1) head.getNext() (2) p.getNext() (3) ++j (4) p.getData() 教师批阅 得 2 分 正确答案: (1) head.getNext() (2) p.getNext() (3) ++j (4) p.getData() 51.(填空题, 2 分) //下面是在当前带头结点的单链表上实现入操作的算法,请将算法补充完整 void insert(int i, Object x) throws Exception{ Node p = ____(1)____ ;//初始化p为头结点,j为计数器 int j = -1; while(p !=null && j < i - 1){//寻找待入的位置,即第i个结点的前驱结点 p = ____(2)____ ;//指针p向后移动一位 ____(3)____ ;//计数器加1 } if (j > i - 1 || p == null){//i不合法 throw new Exception("入位置不合理");//抛出异常 } Node s = ____(4)____ ;//生成新的待入结点s //将结点s单链表中 s.setNext( ____(5)____ ); p.setNext( ____(6)____ ); } (1) head (2) p.getNext() (3) ++j (4) new Node(x) (5) p.getNext() (6) s 教师批阅 得 2 分 正确答案: (1) head (2) p.getNext() (3) ++j (4) new Node(x) (5) p.getNext() (6) s 52.(填空题, 2 分) //下面是在当前带头结点的单链表上实现删除操作的算法,请将算法补充完整 void remove (int i) throws Exception{ Node p = head;//初始化p为头结点,j为计数器 int j = -1; while( ________ && j < i - 1){ //寻找待删除的位置,即第i个结点的前驱结点 p = p.getNext();//指针p向后移动一位 ++j;//计数器加1 } if ( ________ || p.getNext() == null){//i小于0或者大于表长减1 throw new Exception("删除位置不合理");//抛出异常 } p.setNext( ________ );//删除结点 } (1) p.getNext()!=null (2) j>i-1 (3) p.getNext().getNext() 教师批阅 得 2 分 正确答案: (1) p.getNext() != null (2) j>i-1 (3) p.getNext().getNext()
最新发布
09-04
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值