线性表,线性表和链表的区别


存储类别

顺序存储结构 单链表
存储分配方式 用一段连续的存储单元依次存储线性表的数据元素 采用链式存储结构,用一组任意的存储单元存放线性表的元素
时间性能 查找O(1)、插入和删除O(n) 查找O(n)、插入和删除O(1)
空间性能 需要预分配存储空间,分大了浪费,小了容易发生上溢 不需要分配存储空间,只要有就可以分配,元素个数不受限制

通过上面的对比,可以得出一些经验性的结论:

  • 若线性表需要频繁查找,很少进行插入和删除操作时,宜采用顺序存储结构。若需要频繁插入和删除时,宜采用单链表结构。
  • 当线性表中的元素个数变化较大或者根本不知道有多大时,最好用单链表结构,这样可以不需要考虑存储空间的大小问题。而如果事先知道线性表的大致长度,用顺序存储结构效率会高很多。

http://zhidao.baidu.com/question/237262292.html?si=10&qbpn=1_10&tx=&wtp=wk&word=%E7%BA%BF%E6%80%A7%E8%A1%A8%E5%92%8C%E9%93%BE%E8%A1%A8%E7%9A%84%E5%8C%BA%E5%88%AB&fr=solved&from=qb&ssid=&uid=bd_1424171539_897&pu=sz%40224_240%2Cos%40&step=18&bd_page_type=1&init=middle

线性表、包括顺序表和链表顺序表里面元素的地址是连续的,链表里面节点的地址不是连续的,是通过指针连起来的。

http://www.bkjia.com/Javabc/1125496.html

简介


一种逻辑结构,相同数据类型的n个数据元素的有限序列,除第一个元素外,每个元素有且仅有一个直接前驱,除最后一个元素外,每个元素有且仅有一个直接后继。


线性表的特点:


(1)元素个数有限    (2)逻辑上元素有先后次序


(3)数据类型相同    (4)仅讨论元素间的逻辑关系


注:线性表是逻辑结构,顺序表和链表是存储结构。



1.顺序存储


顺序表,使用数组实现,一组地址连续的存储单元,数组大小有两种方式指定,一是静态分配,二是动态扩展。


注:线性表从1开始,而数组从0开始。


优点:随机访问特性,查找O(1)时间,存储密度高;逻辑上相邻的元素,物理上也相邻;


缺点:插入删除需移动大量元素。


顺序表相关的操作跟数组有关,一般都是移动数组元素。


这里说一下插入和删除时的边界条件,首先线性表从1开始,数组从0开始,单纯的文件说明不够直接,来看图说话吧。



插入时:对于线性表来说最小能插入的位置是1,最大能插入的位置是8(=7+1),所以  1<= index <=(7+1);移动数组元素时要注意,for (int i = count; i >= index; i--) {  items[i] = items[i-1];}


删除时:只能在蓝色方块之间寻找节点删除,即1 <= index <= 7。移动元素,for (i = index; i < count; i++) { items[i-1] = items[i];}


2.链式存储


链表的定义是递归的,它或者为空null,或者指向另一个节点node的引用,这个节点含有下一个节点或链表的引用。


与顺序存储相比,允许存储空间不连续,插入删除时不需要移动大量的元素,只需修改指针即可,但查找某个元素,只能从头遍历整个链表。


Java中使用嵌套类来定义节点的抽象数据类型:



private class Node{
    // 链表节点的嵌套类
    T item; // 节点内容
    Node next; // 后继节点
}




2.1 单链表


使用任意存储单元来存储线性表中的数据元素,节点类型如上。


单链表分为带头结点和不带头结点两种,不管有没有头结点,头指针都指向链表的第一个节点(有头结点指向头结点)。


头结点:数值域可不设任何信息,头结点的指针域指向链表的第一个元素。


带头节点的好处有:


(1)链表第一位置节点上的操作和其它位置上的操作一致


(2)无论链表是否为空,头指针都指向头结点(非空),空表和非空表处理一样


(这里我没有使用头结点)


注:链表麻烦的地方是插入和删除时指针的修改,保证不断链,一般先断后链。



基本操作


1. 头插法


将新节点插入到当前链表的表头,(头结点之后),插入的顺序与链表中的顺序相反,关键点就是记住旧的表头,生成一个新的放到旧表头前面,如图:



核心代码:
public void headInsert(T item) {
    Node old = first;
    first = new Node();
    first.item = item;
    first.next = old;
    count++;
}

2. 尾插法


增加一个尾指针,新节点插到链表的尾部,插入的顺序和链表的顺序一致,如图:



核心代码:
public void tailInsert(T item) {
    Node old = last;
    last = new Node();
    last.item = item;
    last.next = null;
    if (isEmpty()) {
        first = last;
    } else {
        old.next = last;
    }
    count++;
}

节点的插入和删除,要点是先断后连,关键就是不要断链了,以插入为例(把s插入p和q之间),先断意思是先把p->q断了,变成s->q,后连,最后再把p和s连接起来。


3. 插入节点


待插入节点为s,一般采用后插法,即先找到插入位置节点的前驱节点,然后插入,时间复杂度O(n)。



核心代码为:
p=getNodeByIndex(i-1);
s.next = p.next;
p.next = s;

还有一种方法是,直接插入到位置的后面(前插法),然后交换两个节点的值,插入的节点到了指定位置,时间复杂度O(1):


核心代码:
s.next = p.next;
p.next = s;
temp = p.item;    // 交换内容
p.item = s.item;
s.item = temp;

4. 删除节点


待删除节点为q,也是先找到前驱节点,修改指针域即可,时间复杂度O(n)。



核心代码:
P = getNodeByIndex(i-1);
q = p.next;
p.next = q.next;
q = null;

删除节点也能直接删除其后继节点,然后将后继节点的内容赋给自己即可,时间复杂度为O(1):


核心代码:
q = p.next;
p.item = p.next.item;
p.next = q.next;
q = null;

2.2 双链表


单链表节点的缺点是只有一个后继节点,访问前驱节点只能从头遍历(如插入、删除),时间复杂度为O(n)。双链表,即添加一个指向前驱的节点,节点类型如下:


private class Node{
    // 链表节点的嵌套类
    T item; // 节点内容
    Node prior, next; // 前驱节点和后继节点
}


双链表的查找和单链表的相同再次不在赘述,双链表的构造也分为头插和尾插,与单链表唯一不同的是修改前驱指针prior,具体见源码。插入和删除时不同,因为需要修改两个指针,如果给定要操作的节点,插入和删除的时间复杂度为O(1)。


注:插入删除操作同样也是先断后连。


1. 插入节点


在p节点后插入s节点,先断后连,先把p和原后继节点的链条给断了,使后继节点只跟s节点有关:



①s.next = p.next; // 先断了p的后继
②p.next.prior = s; // 在断了p后继的前驱
③s.prior = p; // 让s的前驱指向p
④p.next = s; // p的后继指向s,重新连接上链条,此步必须在①②之后

2. 删除节点


删除节点p的后继节点q,也是先断后连,把q和其后继节点的关系,转让给p即可:



①p.next = q.next; // 先断了q的后继
②q.next.prior = p; // 在断了q后继的前驱

删除节点q的前驱节点p,把p和去前驱节点的关系转让给q即可:
①q = p.prior.next; // 把p前驱节点的后继改成q
②q.prior = p.prior; // 把q的前驱节点改成p的前驱节点

2.3 循环链表


1. 循环单链表


与单链表的区别在于,表中最后一个节点的指针不为null,而改为指向头结点(第一个节点),从而整个链表形成一个环。判断循环单链表是否为空,判断是否等于头指针。


只有一个尾指针的循环单例表,可以很方便的操作表头和表尾,因为尾指针的后继就是头指针O(1) 。




2. 循环双链表


与双链表的区别在于,头结点的prior指针指向尾节点,尾节点的next指针指向头结点。



2.4 静态链表


静态链表是借助数组来描述线性表的链式存储结构,节点也有数据域和指针域,这里的指针是节点的相对地址(数组下标),也需要预先分配一块连续的内存空间。


特点,插入删除和动态链表一样,以next==-1为结束标志。



2.5 顺序表和链表的比较


1. 顺序表可以顺序存取,也支持随机存取;链表只能顺序存取。


2. 顺序表逻辑上相邻的物理上也相邻;而链表不一定,它是用指针来描述元素之间的关系。


3. 顺序表插入和删除要移动大量元素;链表只需修改指针即可

				
时间: 2024-10-06 00:19:37

线性表,线性表和链表的区别的相关文章

数据结构&gt;&gt;线性表【注意】--&gt;链表求A-B(原A与B都递增,求完的A-B不改变A原来的顺序)

/*关于链表的题目 * A.B是两个递增有序的单链表,元素个数分别是m和n,求 * 集合A-B,并将结果保存在A中,且仍然保持递增有序. * converge_ab */ #include <iostream.h> using namespace std; typedef struct lnode{ int data; struct lnode * next; }lnode; int main(){ lnode * create_chain(int num,int interval,int s

小猪的数据结构辅助教程——2.2 线性表中的单链表

小猪的数据结构辅助教程--2.2 线性表中的单链表 标签(空格分隔): 数据结构 本节学习路线图与学习要点 学习要点: 1.理解顺序表以及单链表各自的有点以及缺点! 2.熟悉单链表的形式,对于头指针,头结点,尾结点,数据域和指针域这些名词要知道是什么! 3.熟悉单链表的结点结构 4.区分头指针与头结点! 5.熟悉创建单链表的两种方式:头插法和尾插法 6.了解单链表12个基本操作的逻辑 7.有趣的算法题:查找单链表的中间结点~ 1.单链表的引入(顺序表与单链表的PK) 2.单链表的结构图以及一些名

线性表——顺序表与单链表学习小结

线性表 线性表(linear list)是n个具有相同特性的数据元素的有限序列. 线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表.链表.栈.队列.字符串... 线性表在逻辑上是线性结构,也就说是连续的一条直线.但是在物理结构上并不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储. 顺序表 顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储.在数组上完成数据的增删查改. 链表 链表是一种物理存储结构上非连续.非顺序的存储结构,数据

顺序表与单链表的区别及优缺点

线性表之顺序表与单链表的区别及优缺点 尊重原创 -->原文链接 --> 侵权删 这里比较的是基于C语言实现的顺序表与单链表,与其他语言的实现可能会有差异,但我相信语言是相通的,它们的实现机制应该也差不多. 顺序表描述: 顺序表是在计算机内存中以数组的形式保存的线性表,是指用一组地址连续的存储单元依次存储数据元素的线性结构.只要确定了起始位置,表中任一元素的地址都通过下列公式得到:LOC(ai)=LOC(a1)+(i-1)*L 1≤i≤n 其中,L是元素占用存储单元的长度. 单链表描述: 单链表

哈希表——线性探测法、链地址法、查找成功、查找不成功的平均长度

一.哈希表 1.概念 哈希表(Hash Table)也叫散列表,是根据关键码值(Key Value)而直接进行访问的数据结构.它通过把关键码值映射到哈希表中的一个位置来访问记录,以加快查找的速度.这个映射函数就做散列函数,存放记录的数组叫做散列表. 2.散列存储的基本思路 以数据中每个元素的关键字K为自变量,通过散列函数H(k)计算出函数值,以该函数值作为一块连续存储空间的的单元地址,将该元素存储到函数值对应的单元中. 3.哈希表查找的时间复杂度 哈希表存储的是键值对,其查找的时间复杂度与元素数

java实现数据结构-线性表-顺序表,实现插入,查找,删除,合并功能

package 顺序表; import java.util.ArrayList; import java.util.Scanner; public class OrderList { /** * @param args * @author 刘雁冰 * @2015-1-31 21:00 */ /* * (以下所谓"位置"不是从0开始的数组下标表示法,而是从1开始的表示法.) * (如12,13,14,15,16数据中,位置2上的数据即是13) * * 利用JAVA实现数据结构-线性表-顺

顺序表和链表的区别

首先了解顺序表和链表的概念 1.顺序表 顺序表是在计算机内存中以数组的形式保存的线性表,是指用一组地址连续的存储单元依次存储数据元素的线性结构. 线性表采用顺序存储的方式存储就称之为顺序表.顺序表是将表中的结点依次存放在计算机内存中一组地址连续的存储单元中. 特点: (1)在顺序表中,各个表项的逻辑顺序与其存储的物理顺序一致,即第 i 个表项存储于第 i 个物理位置(1 < i < n) (2)对顺序表中的所有表项,即可以进行顺序的访问,也可以随机的访问,也就是说,既可以从表的第一个表项开始逐

[BS]线性表-顺序表基本操作

线性表分为顺序表和链表. 顺序表的基本操作如下: #include <stdio.h> #include <stdlib.h> /*---------------------------------------------*/ #define INIT_VOLUME_OF_LIST 100 #define INCRESE_VOLUME 10 /*---------------------------------------------*/ typedef char ElemType

【数据结构】线性表&amp;&amp;顺序表详解和代码实例

喜欢的话可以扫码关注我们的公众号哦,更多精彩尽在微信公众号[程序猿声] 01 预备知识 1.0 什么是线性表? 线性表(List)是零个或者多个数据元素的有限序列. 首先它是一个序列.里面的元素是有顺序的,如果有多个元素,除开头和结尾以外的元素都有一个前驱和一个后继.而开头元素只有后继,结尾元素只有前驱. 其次线性表是有限的,也就是里面的元素个数是有限的. 1.1 线性表的基本操作(描述) 1ADT 线性表(List) 2Data 3    线性表的数据对象集合为{a1, a2, a3, ...