目录

  • 第二章 线性表
    • 2.1 线性表的定义和操作
      • 2.1.1 线性表的定义
      • 2.1.2 线性表的基本操作
    • 2.2线性表的顺序表示
      • 2.2.1 顺序表的定义
      • 2.2.2 顺序表上基本操作的实现
    • 2.3 线性表的链式表示
      • 2.3.1 单链表的定义
      • 2.3.2 单链表上基本操作的实现
    • 2.3 双链表
      • 2.3.4 循环链表
      • 2.3.5 静态链表
      • 2.3.6 顺序表与链表的比较
      • 2.3.7实际中应怎样选取存储结构

第二章 线性表

【考纲内容】
(一)线性表的定义和基本操作
(二)线性表的实现
顺序存储;链式存储;线性表的应用

【框架】

2.1 线性表的定义和操作

2.1.1 线性表的定义

线性表是具有相同数据类型的n(n>=0)个数据元素的有限序列,其中n为表长,当n=0时,线性表是一个空表。若用L命名线性表,则其一般表示为
                               L=(a1 , a2,a3,……,ai,ai+1,……,an,)

a1是唯一的“第一个”元素,又称表头元素;an是唯一的“最后一个元素”,又称表尾元素。 除第一个元素外,每个元素有且仅有一个直接前驱。除最后一个元素外,每个元素有且只有一个直接后继。以上就是线性表的逻辑特性,这种线性有序的逻辑结构正式线性表的名字由来。

线性表的特点如下:
(1)表中元素个数有限。
(2)表中元素具有逻辑上的顺序性,表中元素有其先后次序。
(3)表中元素都是数据元素,每个元素都是单个元素。
(4)表中元素的数据类型都相同,这意味着每个元素占有相同大小的存储空间。
(5)表中元素具有抽象性,即仅讨论元素间的逻辑关系,而不考虑元素究竟表示什么内容。

注: 线性表是一种逻辑结构,表示元素之间一对一的相邻关系。顺序表和链表是指存储结构,两者属于不同层面的概念。

2.1.2 线性表的基本操作

一个数据结构的基本操作是指最核心、最基本的操作。其他较复杂的操作可以通过调用其基本操作来实现。线性表的主要操作如下:

  • InitList(&L):初始化表。构造一个空的线性表。
  • Length(L):求表长。返回线性表L的长度,即L中数据元素的个数。
  • LocateElem(L,e):按值查找操作。在表L中查找具有给定关键字值的元素。
  • GetElem(L,i):按位查找操作。获取表L中第i个位置的元素的值。
  • ListInsert(&L,i,e):插入操作,在表L中的第i个位置上插入指定元素e。
  • ListDelete(&L,i,&e):删除操作,删除表L中的第i个位置的元素,并用e返回删除元素的值。
  • PrintList(L):输出操作。按前后顺序输出线性表L的所有元素值。
  • Empty(L):判空操作。若L为空表,则返回true,否则返回false。
  • DestroyList(&L):销毁操作。销毁线性表,并释放线性表L所占用的空间。b

2.2线性表的顺序表示

2.2.1 顺序表的定义

线性表的顺序存储又称为顺序表。

它是用一组地址连续的存储单元依次存储线性表中的数据元素,从而使逻辑上相邻的两个元素在物理位置上也相邻。

第一个元素存储在线性表的起始位置,第i个元素的存储位置后面紧接着存储的是第i+1个元素,称i为元素ai在线性表中的位序。因此,顺序表的特点是表中元素的逻辑顺序与其物理顺序相同。

假设线性表L存储的起始位置为LOC(A),sizeof(ElemType)是每个数据元素所占用存储空间的大小,则表L所对应的顺序存储如图所示。

注: 线性表中元素的位序是从1开始的,而数组中元素的下标是从0开始的。

#define InitSize 100
typedef struct{ElemType data[MaxSize];int length;
}SqList;

一维数组可以是静态分配的,也可以是动态分配的。在静态分配时,由于数组的大小和空间事先已经固定,一旦空间占满,再加入新的数据将会产生溢出,进而导致程序崩溃。

在动态分配时,存储数组的空间是在程序执行过程中通过动态存储分配语句分配的,一旦数据空间占满,就另外开辟一块更大的存储空间,用以替换原来的存储空间,从而达到扩充存储数组空间的目的,而不需要为线性表一次性地划分所有空间。

#define InitSize 100
typedef struct{Elemtype *data;int MaxSize,length;
}SqList;

c的初始动态分配语句为

L.data=(ElemType*)malloc(sizeof(ElemType)*InitSize)

c++的初始动态分配语句为

L.data=new ElemType[InitSize];

动态分配不是链式存储,它同样属于顺序存储结构,物理结构没有变化,依然是随机存取方式,只是分配的空间大小可以在运行时决定。

顺序表最主要的特点是随机访问,即通过首地址和元素序号可在时间O(1)内找到指定的元素。
顺序表的存储密度高,每个结点只存储数据元素。
顺序表逻辑上相邻的元素物理上也相邻,所以插入和删除操作需要移动大量元素。

2.2.2 顺序表上基本操作的实现

  1. 插入操作
    在顺序表L的第i(1<=i<=L.length+1)个位置插入新元素e。若i的输入不合法,则返回false,表示插入失败;否则,将顺序表的第i个元素及其后的所有元素右移一个位置,腾出一个空位置插入新元素e,顺序表长度增加1,插入成功,返回true。

    **注:**区别顺序表的位序和数组下标。为何判断插入位置是否合法时if语句中用length+1,而移动元素的for语句中只用length。

最好情况: 在表尾插入(即i=n+1),元素后移语句不执行,时间复杂度为O(1)。
最坏情况: 在表头插入(即i=1),元素后移语句将执行n次,时间复杂度为O(n)。
平均情况: 假设pi (pi=1/(n+1))是在第i个位置上插入一个结点的概率,则在长度为n的线性表中插入一个结点时,所需移动结点的概率为:


因此,线性表插入算法的平均时间复杂度为O(n)。

  1. 删除操作
    删除顺序表L中第i(1<=i<=L.length)个位置的元素,若成功则返回true,并将被删除的元素用引用变量e返回,否则返回false。
bool ListDelete (SqList &L,int i,ElemType &e){if(i<=1||i>L.length)return false;e=L.data[i-1];for (int j=i;j<L.length;j++)L.data[j-1]=L.data[j];L.length--;return true;
}

最好情况: 删除表尾元素(即i=n),无需移动元素,时间复杂度为O(1)。
最坏情况: 删除表头元素(即i=1),需移动除第一个元素外的所有元素,时间复杂度为O(n)。
**平均情况:**假设pi(pi=1/n)是删除第i个位置上结点的概率,则在长度为n的线性表中删除一个结点时,所需移动结点的平均次数为:

因此,线性表删除算法的平均时间复杂度为O(n)。

下图为一个顺序表在进行插入和删除操作前、后的状态,记忆其数据元素在存储空间中的位置变化和表长的变化。

3. 按值查找(顺序查找)
在顺序表L中查找第一个元素值等于e的元素,并返回其位序。

int LocalElem(SqList L,ElemType e){int i;for(i=0;i<L.length;i++)if(L.data[i]==e)return i+1;return 0;
}

最好情况: 查找的元素就在表头,仅需要比较一次,时间复杂度为O(1)。
最坏情况: 查找的元素在表尾(或不存在时),需要比较n次,时间复杂度为O(n)。
**平均情况:**假设pi(pi=1/n)是查找第i个位置上结点的概率,则在长度为n的线性表中查找值为e的元素所需要比较的平均次数为:


因此,线性表按值查找算法的平均时间复杂度为O(n)。

2.3 线性表的链式表示

顺序表可以随时存取表中的任意一个元素,它的存储位置可以用一个简单直观的公式表示,但插入和删除的操作需要移动大量元素。

链式存储线性表时,不需要使用地址连续的存储单元,即不要求逻辑上相邻的元素在物理位置上也相邻,它通过“链”建立起数据元素之间的逻辑关系,因此插入和删除操作不需要移动元素,而只需要修改指针,但也会失去顺序表可随机存取的优点。

2.3.1 单链表的定义

线性表的链式存储又称单链表,它是指通过一组任意的存储单元来存储线性表中的数据元素。

为了建立数据元素之间的线性关系,对每个链表结点,除存放元素自身的信息外,还需要存放一个指向其后继的指针。

单链表的结构如图所示:

其中data为数据域,存放数据元素;next为指针域,存放其后继结点的地址。

单链表中结点类型的描述如下:

typedef struct LNode{ElemType data;struct LNode *next;
}LNode,*LinkList;

利用单链表可以解决顺序表需要大量连续存储单元的缺点,但单链表附加指针域,也存在浪费存储空间的缺点。

由于单链表的元素离散的分布在存储空间中,所以单链表是非随机存取的存储结构,即不能直接找到表中某个特定的结点。查找某个特定的结点时,需要从表头开始遍历,依次查找。

通常用头指针 来标识一个单链表,如单链表L,头指针为NULL时,表示一个空表。

为了操作上的方便,在单链表第一个结点之前附加一个结点,称为头结点,头结点的数据域可以不设任何信息,也可以记录表长等信息。头结点的指针域指向线性表的第一个元素结点,如图所示:

头结点和头指针的区别:不管带不带头结点,头指针始终指向链表的第一个结点,而头结点是带头结点的链表中的第一个结点,结点内通常不存储信息。

引入结点后带来的优点:
(1)由于第一个数据结点的位置被存放在头结点的指针域中,所以在链表的第一个位置上的操作和在表的其他位置上操作一致,无需进行特殊处理。

(2)无论链表是否为空,其头指针都指向结点的非空指针(空表中头结点的指针域为空),因此空表和非空表的处理也就得到了统一。

2.3.2 单链表上基本操作的实现

  1. 采用头插法建立单链表
    该方法从一个空表开始,生成新结点,并将读取到的数据存放到新结点的数据域中,然后将新结点插入到当前链表的表头,即头结点之后,如图所示:

    头插法建立单链表的算法如下:
LinkList List_HeadInsert(LinkList &L){LNode *s; int x;L=(LinkList)malloc(sizeof(LNode));L->next =NULL;scanf("%d",&x);while(x!=9999){s=(LNode*)malloc(sizeof(LNode));s->data=x;s->next=L->next;L->next=x;scanf("%d",&x);}return L;
}

采用头插法建立单链表时,读入数据的顺序与生成的链表中的元素的顺序是相反的。每个结点插入的时间为O(1),设单链表长为n,则总时间复杂度为O(n)。

如果没有设立头结点,需要修改哪些地方?
因为在头部插入新结点,每次插入新结点后,需要将它的地址赋给头指针L。

  1. 采用尾插法建立单链表
    头插法建立单链表的算法虽然简单,单生成的链表中结点的次序和输入数据的顺序不一致。若希望两者次序一致,可以采用尾插法。

该方法将新结点插入法到当前链表的尾表,为此必须增加一个尾指针r,使其始终指向当前链表的尾结点,如图所示:

尾插法建立单链表的算法如下:

LinkList List_TailInsert(LinkLiist &L){int x;L=(LinkList)malloc(sizeof(LNode));   //是由系统生产一个LNode型的结点,同时在该结点的其实位置赋值给变量指针s。LNode *s,*r=L;scanf("%d",&x);while(x!=9999){s=(LNode*)malloc(sizeof(LNode));s->data=x;r->next=s;r=s;scanf("%d",&x);}r->next=NULL;return L;
}

因为附设了一个指向表尾结点的指针,故时间复杂度和头插法的相同为O(n)。

  1. 按序号查找结点值
LNode *GetElem(LinkList L,int i){int j=1;LNode *p=L->next;if(i==0)return L;if(i<1)return NULL;while(P&&j<i){p=p->next;j++;}return p;
}

按序号查找操作的时间复杂度为O(n)。

  1. 按值查找表结点
    从单链表的第一个结点开始,由前往后一次比较表中各结点数据域的值,若某结点数据域的值等于给定值e,则返回该结点的指针;若整个单链表没有这样的结点,则返回NULL。

按值查找表结点的算法如下:

LNode *LocateElem(LinkList L,ElemType e){LMode *p=L->next;while(p!=NULL&&p->data!=e)p=p->next;return p;
}

按值查找操作的时间复杂度为O(n)。

  1. 插入结点操作
    插入结点操作将值为x的新结点插入到单链表的第i个位置上。先检查插入位置的合法性,然后找到待插入位置的前驱结点,即第i-1个结点,再在其后插入新结点。

算法首先调用按序号查找算法GetElem(L,i-1),查找第i-1个结点。
假设返回的第i-1个结点为*p,然后令新结点 *s的指针域指向 *p的后继结点,再令结点 *p的指针域指向新插入的结点 *s。

操作过程如下所示:

实现插入结点的代码片段如下:
① p=GetElem(L,i-1);
② s->next=p->next;
③ p->next=s;

算法中,语句②和 ③的顺序不能颠倒,否则,当限制性p->next=s后,指向其原后继的指针就不存在,再执行s->next=p->next时,相当于执行了s->next=s,显然是错误的。

本算法主要的时间开销在于查找第i-1个元素,时间复杂度为O(n),若在给定的结点后面插入新结点,则时间复杂度仅为O(1)。

扩展:对某一结点进行前插操作。
前插操作是指在某结点的前面插入一个新结点,后插操作的定义刚好与之相反。在单链表插入算法中,通常都采用后插操作。

以上面的算法为例,首先调用函数GetElem()找到第i-1个结点,即插入结点的前驱结点后,再对其执行后插操作。

由此可知,对结点的前插操作均可转化为后插操作,前提是从单链表的头结点开始顺序查找到其前驱结点,时间复杂度为O(n)。

还可以采用另一方式将其转化为后插操作来实现,设待插入结点为 *s,将 *s插入到 *p的前面。仍然可以将 *s插入到 *p的后面,然后将p->data 与s->data交换,这样既满足了逻辑关系,又能使时间复杂度为O(1)。

算法的代码片段如下:

//将*s结点插入到*p之前的主要代码片段
s->next=p->next;  //修改指针域,不能颠倒
p->next=s;
temp=p->data;   //交换数据域部分
p->data=s->data;
s->data=temp;
  1. 删除结点操作
    删除结点操作是将单链表的第i个结点删除。先检查删除位置的合法性,后查找表中第i-1个结点,即被删除结点的前驱结点,再将其删除。其删除过程如图所示:

    假设结点*p为找到的被删结点的前驱结点,为实现这一操作后的逻辑关系的变化,仅需修改 *p的指针域,即将 *p 的指针域next指向 *q 的下一结点。

实现删除结点的代码片段如下:

p=GetElem(L,i-1);
q=p->next;
p->next=q->next;
free(q);

和插入算法一样,该算法的主要时间也耗费在查找操作上,时间复杂度为O(n)。

扩展:删除节点*p
要删除某个给定结点*p,通常的做法是先从链表的头结点开始顺序找到其前驱结点,然后再执行删除操作,算法的时间复杂度为O(n)。

删除结点 p的操作可用删除p 的后继结点操作来实现,实质就是将其后继结点的值赋予其自身,然后删除后继结点,也能使得时间复杂度为O(1)。

实现上述操作代码片段如下:

q=p->next;
p->data=p->next->data;
p->next=q->next;
free(q);                  //有系统回收一个LNode型的结点,回收的空间可供再次生结点时用。
  1. 求表长操作
    求表长操作就是计算单链表中数据结点(不含头结点)的个数,需要从第一个结点开始顺序依次访问表中的每个结点,为此要设计一个计数器变量,每访问一个结点,计数器加1,直到访问到空结点位置。算法时间复杂度为O(n)。

因为单链表的长度是不包括头结点的,因此不带头结点和带头结点的单链表在求表长操作上会略有不同。对不带头结点的单链表,当表为空时,要单独处理。

2.3 双链表

单链表结点中只有一个指向其后继的指针,使得单链表只能从头结点依次顺序地向后遍历。要访问某个结点的前驱结点(插入、删除操作时),只能从头开始遍历,访问后继结点的时间复杂度为O(1),访问前驱结点的时间复杂度为O(n)。

为了克服单链表的缺点,引入双链表,双链表结点中有两个指针prior和next,分别指向其前驱结点和后继结点,如图所示

双链表结点类型描述如下:

typedef struct DNode{ElemType data;struct DNode *prior,*next;
}DNode,*DLinkList;

双链表在单链表的结点中增加了一个指向其前驱的prior指针,因此,双链表中的按值查找和按位查找的操作与单链表的相同。
但双链表在插入和删除的操作的实现上,与单链表由着较大的不同,这是因为“链”变化时也需要对prior指针做出修改,其关键是保证在修改的过程中不断链。此外,双链表可以很方便的找到其前驱结点,因此,插入、删除操作的时间复杂度为O(1)。

  1. 双链表的插入操作
    在双链表中p所指的结点在之后插入结点*s,其指针的变化过程如图所示:


插入操作的代码片段如下:
①s->next=p->next;
②p->next->prior=s;
③s->prior=p;
④p->next=s;

上述代码的顺序不是唯一的,也不是任意的,①和②两步必须在④步之前,否则*p的后继结点的指针就会丢掉,导致插入失败。

  1. 双链表的删除操作
    删除双链表中结点 *p的后继结点 *q,其指针变化过程如图所示:

    删除操作代码片段如下:
p->next=q->next;
q->next->prior=p;
free(q);

在建立双链表的操作中,也可以采用如同单链表的头插法和尾插法,但在操作上需要注意指针的变化和单链表有所不同。

2.3.4 循环链表

  1. 循环单链表
    循环单链表和单链表的区别在于,表中最后一个结点的指针不是NULL,而改为指向头结点,从而整个链表形成一个环,如图所示:

在循环单链表中,表尾结点*r的next域指向L,故表中没有指针域为NULL的结点,因此,循环单链表的判空条件不是头结点的指针是否为空,而是它是否等于头指针。

循环单链表的插入、删除算法与单链表的几乎一样,所不同的是若操作在表尾进行,则执行的操作不同,以让单链表继续保持循环的性质。当然,正式因为循环单链表是一个环,因此,在任何一个位置上插入和删除的操作都是等价的,无需判断是否是表尾。

在单链表中只能从表头结点开始往后顺序遍历整个链表,而循环单链表可以从表中的任意一个结点开始遍历整个链表。

有时对单链表常做的操作是在表头和表尾进行的,此时对循环单链表不设头指针仅设尾指针,从而使操作效率更高。原因是,若设的是头指针,对表尾进行操作需要O(n)的时间复杂度,而若设的是尾指针r,r->next,即为头指针,对于表头与表尾进行操作都只需要O(1)的时间复杂度。

  1. 循环双链表
    由循环单链表的定义不难退出循环双链表,不同的是在循环双链表中,头结点的prior指针还要指向表尾结点,如图所示:

    在循环双链表中,某结点*p为尾结点时,p->next==L;当循环双链表为空表时,其头结点的prior域和next域都等于L。

2.3.5 静态链表

静态链表借助数组来描述线性表的链式存储结构,结点也有数据域data和指针域next,与前面说的链表中的指针不同的是,这里的指针是结点的相对地址(数组下标),又称游标。和顺序表一样,静态链表也要预先分配一块连续的内存空间。

静态链表和单链表的对应关系如图所示:

静态链表结构类型描述:

#define MaxSize 50
typedef struct{ElemType data;int next;
}SlinkList[MaxSize];

静态链表以next==1作为其结束的标志。静态链表的插入、删除操作与动态链表的相同,只需要修改指针,而不需要移动元素。

总体来说,静态链表没有单链表使用起来方便,但在一些不支持指针的高级语言(如Basic)中,是一种非常巧妙的设计方法。

2.3.6 顺序表与链表的比较

  1. 存取(读写)方式
    顺序表可以顺序存取,也可以随机存取,链表只能从表头顺序存取元素。例如在第i个位置上执行或存取的操作,顺序表仅需一次访问,而链表则需从表头开始依次访问i次。

  2. 逻辑结构与物理结构
    采用顺序存储时,逻辑上相邻的元素,对应的物理存储位置也相邻。而采用链式存储时,逻辑上相邻的元素,物理位置则不一定相邻,对应的逻辑关系是通过指针链接来表示的。

  3. 查找和删除操作
    对于按值查找,顺序表无序时,两者的时间复杂度均为O(n);顺续表有序时,可采用折半查找,此时的时间复杂度为O(log2n)。
    对于按序号查找,顺序表支持随机访问,时间复杂度仅为O(1),而链表的平均时间复杂度为O(n)。顺序表的插入、删除操作,平津需要移动半个表长的元素。链表的插入、删除操作,只需修改相关结点的指针域即可。由于链表的而每个结点都带有指针域,故而存储密度不够大。

  4. 空间分配
    顺序存储在静态存储分配情形下,一旦存储空间装满就不能扩充,若再加入新元素,则会出现内存溢出,因此需要预先分配足够大的存储空间。预先分配过大,可能会导致顺序表后部大量元素闲置;预先分配过小,又会造成溢出。
    动态存储分配虽然存储空间可以扩充,但需要移动大量元素,导致操作效率降低,而且若内存中没有更大块的连续存储空间,则会导致分配失败。
    链式存储的结点空间只在需要时申请分配,只要内存中有空间就可以分配,操作灵活、高效。

2.3.7实际中应怎样选取存储结构

  1. 基于存储的考虑
    难以估计线性表的长度或存储规模时,不宜采用顺序表,链表不用事先估计存储规模,但链表的存储密度较低,显然链式存储结构的存储密度是小于1的。

  2. 基于运算的考虑
    在顺序表中按序号访问ai的时间复杂度为O(1),而链表中按序号访问的时间复杂度为O(n),因此,若经常做的运算时按序号访问数据元素,则显然顺序表优于链表。
    在顺序表中进行插入、删除操作时,平均移动表中一般的元素,当数据元素的信息量较大且表较长时,这一点是不应忽视的;在链表中进行插入、删除操作时,虽然也要找插入位置,但操作主要是比较操作,从这个角度考虑显然后者优于前者。

  3. 基于环境的考虑
    顺序表容易实现,任何高级语言中都有数组类型;链表的操作是基于指针的,相对来说,前者实现较为简单。
    总之,两种存储结构各有长短,选择哪一种由实际问题的主要因素决定。通常较稳定的线性表选择顺序存储,而频繁进行插入、删除操作的线性表(即动态性较强)宜选择链式存储。

数据结构第二章-线性表(详细知识点总结)相关推荐

  1. C语言数据结构-第二章线性表-电大

    第二章线性表--内容简介 本章将进入线性结构的学习. 线性结构是最简单.最常用的一种数据结构. 本章将学习线性表的定义.顺序和链式两种存储方式及相应存储结构上的运算实现.通过典型示例训练,掌握线性表的 ...

  2. 王道408数据结构——第二章 线性表

    文章目录 一.线性表的定义和基本操作 线性表 顺序表 1.插入操作 2.删除操作 3.按值查找(顺序查找) 二.单链表 1. 头插法 2. 尾插法 3. 按序号查找 4. 按值查找 5. 插入结点 6 ...

  3. 数据结构第二章线性表学习笔记

    1.    C++程序设计模板   (关于template的解释)[以下内容摘自百度] 函数声明格式 template <class(或typename) any(或任意符合规则的名称)> ...

  4. C++ 数据结构第二章 ----- 线性表

    文章目录 线性表 线性表的顺序存储 一.基本概念 二.基本操作 线性表的链式存储 一.基本概念 二.基本操作 三.双链表 (1) 双链表的插入操作 (2) 双链表的删除操作 四.循环链表 五.循环双链 ...

  5. (王道408考研数据结构)第二章线性表-第三节5:顺序表和链表的比较

    文章目录 一:逻辑结构比较 二:存储结构比较 三:基本操作比较 (1)初始化操作 (2)销毁操作 (3)插入和删除 (4)查找 顺序表和链表的选取原则 一:逻辑结构比较 顺序表和链表都是线性表,都是线 ...

  6. (王道408考研数据结构)第二章线性表-第三节1:单链表的定义及其操作(插入和删除,建立之尾插和头插)

    文章目录 一:单链表相关 (1)单链表的定义 (2)头指针与头结点 二:单链表代码描述 三:单链表的初始化 四:单链表的插入 五:单链表的删除 六:单链表查找 (1)按位查找 (2)按值查找 七:单链 ...

  7. (王道408考研数据结构)第二章线性表-第二节1:顺序表的定义

    文章目录 一:顺序表实现 (1)静态分配 (2)动态分配 二:顺序表特点 顺序表:也叫做线性表的顺序存储结构,指的是用一段地址连续的存储单元依次存储线性表的数据元素 一:顺序表实现 (1)静态分配 静 ...

  8. (王道408考研数据结构)第二章线性表-第一节:线性表的定义和基本操作

    文章目录 一:线性表的定义 二:线性表的基本操作 一:线性表的定义 线性表(Linear List):零个或多个数据元素的有限序列 元素之间是有顺序的 若元素存在多个,则第一个元素无前驱,最后一个元素 ...

  9. PTA数据结构第二章线性表

    顺序表 1-8 对于顺序存储的长度为N的线性表,访问结点和增加结点的时间复杂度分别对应为O(1)和O(N). T F 1-10 对于顺序存储的长度为N的线性表,删除第一个元素和插入最后一个元素的时间复 ...

最新文章

  1. Equinox P2的学习
  2. ts快捷键 vscode_vscode怎么调试ts
  3. windows下实现c++版faster-rcnn
  4. 《ODAY安全:软件漏洞分析技术》学习心得-----shellcode的一点小小的思考
  5. 计算机应用基础期末考试要点,计算机应用基础期末复习要点.doc
  6. 计算机技术要求单科成绩吗,软考考试合格标准怎样确定?单科成绩是否保留?
  7. 例子---纯CSS实现加载球
  8. iQOO Neo5活力版或本月发布:搭载骁龙870+高刷LCD屏
  9. form中的fieldset标签应用
  10. python的多行语句可以使用反斜杠_Python的续行符:反斜杠\
  11. Android WebView示例教程
  12. 微信小程序 this.data与this.setData
  13. 发现一个导致Arduino无法打开串口监视器问题
  14. 微信小程序chooseMedia应用
  15. MongoDB概念集合
  16. 抓包安卓7以上ca证书安装方法
  17. html设置编剧,编剧必备之电影剧本创作六大基本步骤
  18. <choose>标签的使用
  19. Chrome浏览器使用谷歌翻译插件的正确方法
  20. 《MySQL高级篇》三、存储引擎

热门文章

  1. python中notebook的快捷键_现在就飞起来!Jupyter Notebook 那些如有神助的快捷操作...
  2. Flink从入门到精通系列(四)
  3. 台式计算机系统配置,怎么看自己电脑配置 电脑配置参数说明【图文】
  4. 深度残差网络原理理解
  5. 定制 or 通用,中国 SaaS 未来发展趋势是什么?
  6. window10专业版下:docker中k8s安装
  7. 福布斯:区块链建立可能彻底改变招聘行业
  8. 计算机网络DTE和DCE,什么叫DTE与DCE
  9. 投资:SEC Form总结
  10. JS校验手机号和身份证号格式