第二章 线性表

在线性表的两种主要存储结构——顺序存储结构和链式存储结构中,它们确实在存取方式上有所不同。

  1. 顺序存储结构(如数组):
    • 在顺序存储结构中,数据元素在物理位置上是相邻的,即它们存储在连续的内存空间中。
    • 由于数据元素的物理位置相邻,因此可以通过计算元素的偏移量来直接访问任意位置的元素,这就是所谓的“随机存取”。具体来说,如果知道数组的首地址和每个元素所占用的字节数,就可以通过索引(或位置)和元素大小计算出任意元素的地址,并在O(1)时间内访问到它。
  2. 链式存储结构(如链表):
    • 在链式存储结构中,数据元素在物理位置上不一定相邻,每个元素都包含数据部分和指向下一个元素的指针(或引用)。
    • 由于数据元素在物理上不是连续的,因此不能通过计算偏移量来直接访问任意位置的元素。相反,只能从头节点开始,通过指针或引用顺序地遍历链表,直到找到所需的元素。这种存取方式被称为“顺序存取”其时间复杂度与链表的长度成正比,即O(n)。

对于顺序存储的长度为N的线性表,访问结点和增加结点的时间复杂度分别对应为O(1)和O(N)。T

对于顺序存储的线性表(如数组),访问任意一个结点的时间复杂度是O(1)。这是因为你可以直接通过索引(或下标)来访问元素,而不需要遍历整个数组。但在插入、删除以及按内容查找操作需要线性的时间代价O(n).

对于顺序存储的长度为N的线性表,删除第一个元素和插入最后一个元素的时间复杂度分别对应为O(1)和O(N)。F

删除第一个元素通常需要将数组中剩余的所有元素向前移动一个位置,这个操作需要遍历并移动N-1个元素,因此时间复杂度是O(N)。如果线性表有足够的空间来存储新元素(即不需要重新分配内存),那么插入最后一个元素的时间复杂度是O(1)。

(neuDS)所谓随机存取,就是通过首地址和元素的位序号值可以在O(1)的时间内找到指定的元素。T

随机存取意味着,一旦我们知道了数据结构的首地址(或基地址,即第一个元素的存储位置)以及我们想要访问的元素的索引(或位序号),我们就可以在常数时间O(1)内直接访问到该元素,而不需要遍历数据结构中的其他元素。链表(Linked List)等数据结构也允许我们访问其元素,但它们不支持随机存取。在链表中,我们需要从头节点开始遍历链表,直到找到我们想要的元素,这个过程的时间复杂度与链表的长度成正比,即O(n)。因此,链表等结构不是随机存取数据结构。

(neuDS)在顺序表上进行插入、删除操作时需要移动元素的个数与待插入或待删除元素的位置无关。T

在顺序表(如数组)上进行插入或删除操作时,需要移动元素的个数与待插入或待删除元素的位置是密切相关的

(neuDS)在线性表的顺序存储结构中可实现快速的随机存取,而在链式存储结构中则只能进行顺序存取。T

在顺序表中取出第i个元素所花费的时间与i成正比。F

线性表采用链式存储表示时,所有结点之间的存储单元地址可以连续也可以不连续。T

将长度分别为m,n的两个单链表合并为一个单链表的时间复杂度为O(m+n)。T

在具有头结点的链式存储结构中,头指针指向链表中的第一个元素结点。F

具有头结点的链式存储结构中,头指针(或称为头指针变量)并不直接指向链表中的第一个数据元素结点,而是指向头结点。

若用链表来表示一个线性表,则表中元素的地址一定是连续的。F

循环链表不是线性表。F

下列函数试图求链式存储的线性表的表长,是否正确?F

int  Length ( List  *PtrL )
{    List  *p = PtrL;      
     int  j = 0;
     while ( p ) { 
           p++; 
           j++;                 
     }   
     return  j;
}

在链式存储结构中,链表中的节点是通过指针连接起来的,而不是像数组那样通过索引(或地址连续)来访问。因此,你不能通过简单地增加指针p的值(即p++)来遍历链表中的下一个节点。

在链表中,每个节点通常包含一个指向下一个节点的指针(对于单向链表)或两个指针(一个指向前一个节点,一个指向后一个节点,对于双向链表)。为了遍历链表并计算其长度,你需要通过节点的指针域来访问下一个节点。

int Length(List *PtrL) {  
    List *p = PtrL->next; // 假设PtrL是头指针,并且头节点不存储有效数据(或有一个标志位表示头节点)  
    int j = 0;  
    while (p != NULL) {  
        p = p->next; // 通过节点的next指针移动到下一个节点  
        j++;  
    }  
    return j;  
}

若某线性表最常用的操作是存取任一指定序号的元素和在最后进行插入和删除运算,则利用顺序表存储最节省时间。T

(neuDS)线性表的唯一存储形式是链表。F

线性表中每个元素都有一个直接前趋和一个直接后继。F

线性表的插入、删除总是伴随着大量数据的移动。F

线性表中的所有数据元素的数据类型必须相同。T

线性表是一种线性结构,它要求线性表中的元素具有相同的数据类型,以便进行统一的操作和管理。在线性表中,每个元素都是数据的一个单元,这些数据单元可以是数、字符、记录等,但同一线性表中的元素应具有相同的数据类型,以保证线性表操作的正确性和一致性。

线性表是表示多对一关系的数据结构。F

线性表是表示多对多关系的数据结构。F

带头结点的单循环链表中,任一结点的后继结点的指针域均不空。T

带头结点的单链表h为空的判定条件是:B

A.h == NULL;

B.h->next == NULL;

C.h->next == h;

D.h != NULL;

对于带头结点的单链表,空链表的判定条件并不是简单地看头指针h是否为NULL,因为即使链表为空,头结点(哑结点或哨兵结点)本身仍然是存在的,且其指针域(通常命名为next)用于指向链表的第一个实际数据节点。当链表为空时,头结点的next指针将不指向任何数据节点,即指向NULL

链表不具有的特点是:B

A.插入、删除不需要移动元素

B.方便随机访问任一元素

C.不必事先估计存储空间

D.所需空间与线性长度成正比

所需空间与线性长度成正比:链表的存储空间主要由节点组成,每个节点包含数据域和指针域(或引用)。在链表中,节点的数量与链表的长度(即元素的数量)成正比。因此,链表所需的存储空间也与链表的线性长度成正比。所以D选项是链表的一个特点。

据结构反映了数据元素之间的结构关系。单链表是一种(D )。

A.顺序存储线性表

B.非顺序存储非线性表

C.顺序存储非线性表

D.非顺序存储线性表

  • 顺序存储:指的是数据元素在物理内存中的存储位置是连续的,即数据元素之间的相对位置关系与它们在逻辑结构中的顺序是一致的。数组是顺序存储结构的典型代表。

  • 非顺序存储:指的是数据元素在物理内存中的存储位置不一定是连续的,数据元素之间的相对位置关系是通过指针(或引用)来建立的。链表是非顺序存储结构的典型代表。

  • 线性表:是一种线性结构,其中的元素是一对一的关系,即除了第一个元素和最后一个元素外,每个元素都有一个前驱和一个后继。

  • 非线性表:元素之间不是一对一的关系,而是可以存在一对多、多对一或多对多的关系,如树和图。


在具有N个结点的单链表中,实现下列哪个操作,其算法的时间复杂度是O(N)?C

A.在地址为p的结点之后插入一个结点

B.删除开始结点

C.遍历链表和求链表的第i个结点

D.删除地址为p的结点的后继结点

A. 在地址为p的结点之后插入一个结点

  • 这个操作的时间复杂度是O(1),前提是已经找到了地址为p的结点。一旦找到了该结点,插入新结点只需要修改几个指针即可,不依赖于链表中结点的总数N。

B. 删除开始结点

  • 这个操作的时间复杂度也是O(1),因为只需要修改头指针(即链表的开始结点指针)即可。它同样不依赖于链表中结点的总数N。

C. 遍历链表和求链表的第i个结点

  • 这个操作的时间复杂度是O(N),因为无论i的值是多少(假设i是有效的,即1 ≤ i ≤ N),都需要从头结点开始遍历链表,直到找到第i个结点。在最坏的情况下(即i=N时),需要遍历整个链表。

D. 删除地址为p的结点的后继结点

  • 这个操作的时间复杂度是O(1),前提是已经找到了地址为p的结点。一旦找到了该结点,删除其后继结点只需要修改几个指针即可,不依赖于链表中结点的总数N。

 

对于一个具有N个结点的单链表,在给定值为x的结点后插入一个新结点的时间复杂度为:C

A.O(1)

B.O(N/2)

C.O(N)

D.O(N2)

将长度为n的单链表链接在长度为m的单链表之后的算法的时间复杂度为()。

A.O(1)    B.O(n)    C.O(m)    D.O(m+n)

理论上,如果你已经有了两个链表的头指针,并且想要将第一个链表(长度为n)的末尾连接到第二个链表(长度为m)的开头,那么这个过程本身只需要修改第一个链表末尾节点的指针,使其指向第二个链表的头节点。这个操作是O(1)的,因为它只涉及到常数次数的指针操作

然而,如果题目是指“遍历第一个链表以找到其末尾,然后将它连接到第二个链表”,那么这个过程的时间复杂度将是O(n),因为你需要遍历整个第一个链表来找到其末尾。

但根据题目的直接描述“将长度为n的单链表链接在长度为m的单链表之后”,并且假设我们已经有了两个链表的头指针,那么这个操作应该是O(1)的,因为我们只是简单地修改了一个指针的指向,而没有进行任何遍历。

因此,最符合题目描述的答案是A. O(1)。但请注意,这个答案依赖于你如何解释“链接”这个动作——是直接修改指针还是包括遍历链表以找到末尾。在大多数上下文中,当提到“链接”两个链表时,我们指的是直接修改指针,从而使得第一个链表的末尾连接到第二个链表的开头,这是一个O(1)的操作。

h为不带头结点的单向链表。在h的头上插入一个新结点t的语句是:

A.h=t; t->next=h->next;

B.t->next=h->next; h=t;

C.h=t; t->next=h;

D.t->next=h; h=t;

A. h=t; t->next=h->next;

  • 这个选项首先让h指向t,这是正确的第一步(但此时h->next是未定义的,因为t是刚分配的结点,其next还未被初始化)。
  • 然后尝试t->next=h->next;但此时h->nextt(因为h已经被赋值为t),这会导致tnext指向自己,形成循环链表,并且丢失了原链表的所有节点。因此,这是错误的。

B. t->next=h->next; h=t;

  • 这个选项首先尝试t->next=h->next;,但在执行这一步之前,如果hNULL(即链表为空),这将导致空指针解引用错误。
  • 即便h不是NULL,虽然这一步本身正确地将tnext指向了原链表的头结点,但它在修改h之前执行,如果后续步骤(修改h)未能正确执行(例如,由于某种原因程序崩溃或h的赋值被意外覆盖),则链表将不可恢复地丢失。然而,仅从这一行代码本身来看,如果h不是NULL,它是正确的。但通常我们更希望看到先安全地更新头指针,再处理其他。

C. h=t; t->next=h;

  • 这个选项首先让h指向t,这是正确的第一步。
  • 但随后它将t->next设置为h,即t指向自己,这会导致循环链表,并且丢失了原链表的所有节点。因此,这是错误的。

D. t->next=h; h=t;

  • 这个选项首先正确地设置了新结点tnext指针,指向原链表的头结点h(如果h不是NULL)。
  • 然后,它更新头指针h,使其指向新结点t。这是正确的插入操作。

因此,正确答案是D。

在单链表中,要删除某一指定结点,必须先找到该结点的(A)。

A.直接前驱

B.自身位置

C.直接后继

D.直接后继的后继

在单链表中,要删除某一指定结点,必须先找到该结点的A. 直接前驱

这是因为单链表中的每个节点只存储了指向下一个节点的指针(next指针),而没有直接存储指向前一个节点的指针(即没有prev指针)。当我们想要删除某个节点时,需要做的操作是将该节点的直接前驱节点的next指针指向该节点的直接后继节点,从而实现节点的删除。

顺序表 - 时间复杂度

在包含 n 个数据元素的顺序表中,▁▁B\C▁▁▁ 的时间复杂度为 O(n)。

A.访问第 i 个数据元素

B.在第 i(1≤i≤n) 个结点后插入一个新结点

C.删除第 i(1≤i≤n) 个结点

D.将 n 个元素按升序排序

在包含 n 个数据元素的顺序表中,时间复杂度为 O(n) 的操作是:

B. 在第 i(1≤i≤n) 个结点后插入一个新结点
C. 删除第 i(1≤i≤n) 个结点

解释如下:

A. 访问第 i 个数据元素 - 这个操作的时间复杂度是 O(1),因为你可以直接通过索引 i 来访问元素,不需要遍历整个数组。

B. 在第 i(1≤i≤n) 个结点后插入一个新结点 - 这个操作的时间复杂度是 O(n),因为你需要将第 i 个元素及其之后的所有元素都向后移动一个位置来为新的元素腾出空间。在最坏的情况下(即 i=n 时),你需要移动整个数组中的元素。

C. 删除第 i(1≤i≤n) 个结点 - 类似于插入操作,删除第 i 个元素也需要将第 i 个元素之后的所有元素都向前移动一个位置来填补空缺。在最坏的情况下(即 i=1 时),你需要移动数组中的 n-1 个元素。因此,这个操作的时间复杂度也是 O(n)。

D. 将 n 个元素按升序排序 - 这个操作的时间复杂度通常高于 O(n),具体取决于所使用的排序算法。例如,冒泡排序、插入排序和选择排序的平均和最坏情况时间复杂度都是 O(n^2),而快速排序、归并排序等更高效的排序算法的平均时间复杂度是 O(n log n)。因此,这个选项的时间复杂度不是 O(n)。

综上所述,选项 B 和 C 的时间复杂度是 O(n)。

链表 - 时间复杂度

在包含 n 个数据元素的链表中,▁B\C▁▁▁▁ 的时间复杂度为 O(n)。

A.访问第 i 个数据元素

B.在第 i (1≤i≤n) 个结点后插入一个新结点

C.删除第 i (1≤i≤n) 个结点

D.将 n 个元素按升序排序

A. 访问第 i 个数据元素 - 这个操作的时间复杂度是 O(i)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值