1.什么是线性表(List)?

  零个或多个数据元素的有限序列。

  (1)元素之间是有序的。

  (2)线性表强调是有限的。

2.线性表有哪些操作?

  (1)线性表的创建和初始化,InitList

  (2)判空,ListEmpty(),true-空

  (3)线性表重置为空表,ClearList()

  (4)获取线性表第i个位置的值,GetElem(int i)

  (5)查找线性表中值为x的结点 ,LocateElem(int x)

  (6)在线性表中第i个位置插入值为x的结点 , InsertElem(int x,int i)

  (7)删除线性表的第i个结点  ,DeleteElem(int i)

  (8)求线性表的长度 ,ListLength()

  (9)判断线性表是否已满 ,ListFull()

3.线性表的两种物理结构:顺序存储结构和链式存储结构

  (1)顺序存储结构

    三个属性:

      存储空间的起始位置:数组data

      线性表的最大存储容量:数组长度MaxSize

      线性表的当前长度:length

  注意:数组长度和线性表长度的区别

      数组长度一般存储分配后就不变了。

      线性表长度是变化的,因为删除和插入的操作。

      所以线性表的长度应小于等于数组的长度

4.插入算法的思路:
      如果插入位置不合理,抛出异常
      如果线性表长度大于等于数组长度,则抛出异常或动态增加容量;
      从最后一个元素开始向前遍历到第i个位置,分别将它们都向后移动一个位置;
      将要插入元素填入位置 i 处;
      表长加1.
 
5. 删除算法的思路:
       如果删除位置不合理,抛出异常
       取出删除元素
          从删除元素位置开始遍历到最后一个元素位置,分别将他们都向前移动一个位置;
          表长减1

   线性表的顺序存储结构,在存,读取数据时,不管是哪个位置,时间复杂度都是O(1),插入和删除元素,时间复杂度都是O(n).

  1. public class LinearList {
  2. private int[] data; //线性表以数组形式存放
  3. private int MaxSize;//表空间的最大范围
  4. private int Last; //表当前结点个数,即表长
  5. //构造函数
  6. public LinearList(int MaxSize) {
  7. if(MaxSize>0){
  8. this.MaxSize = MaxSize;
  9. Last = 0;
  10. //创建表空间
  11. data = new int [MaxSize];
  12. }
  13. }
  14. //判断线性表是否为空
  15. public boolean ListEmpty(){
  16. return (Last <=0)?true:false;
  17. }
  18. //判断线性表是否已满
  19. public boolean ListFull(){
  20. return(Last >= MaxSize)?true:false;
  21. }
  22. //求线性表的长度
  23. public int ListLength(){
  24. return Last;
  25. }
  26. //求线性表中第i个结点的值
  27. public int GetElem(int i){
  28. //若存在,返回结点,否则,返回null;
  29. return(i<0||i>Last)?null:data[i];
  30. }
  31. //查找线性表中值为x的结点
  32. public int LocateElem(int x){
  33. //查找表中值为x的结点,找到则返回该结点的序号;否则返回-1;
  34. //若表中值为x的结点有多个,找到的是最前面的一个;
  35. for(int i=0;i<Last;i++){
  36. if(data[i] == x)return i;
  37. }
  38. return -1;
  39. }
  40. //在线性表中第i个位置插入值为x的结点
  41. public boolean InsertElem(int x,int i){
  42. //在表中第i个位置插入值为x的结点
  43. //若插入成功,则返回true,否则返回false
  44. //插入位置不合理,插入失败
  45.  
  46. if(i<0||i>Last||Last == MaxSize)
  47. return false;
  48. else
  49. {
  50. //后移
  51. for(int j = Last;j>i;j--)
  52. data[j] = data[j-1];
  53. //插入
  54. data[i] = x;
  55. //表长增一
  56. Last++;
  57. return true;
  58. }
  59.  
  60. }
  61. //删除线性表的第i个结点
  62. public boolean DeleteElem(int i){
  63. //删除表中第i个结点,若成功,返回true;否则返回false;
  64. //第i个结点不存在,删除失败;
  65. if(i<0||i>=Last||Last == 0)
  66. return false;
  67. else
  68. {
  69. //前移
  70. for(int j=i;j<Last-1;j++)
  71. data[j] = data[j+1];
  72. //表长减1
  73. Last--;
  74. return true;
  75. }
  76. }
  77. public void display(){
  78. System.out.println("当前链表长度:"+ ListLength());
  79. for(int i=0;i<Last;i++)
  80. {
  81. System.out.println("第"+i+"结点为:"+data[i]);
  82. }
  83. }

  总结:线性表顺序存储结构的优缺点

     优点:可以快速地存和取表中任一位置的元素

     缺点:插入和删除操作需要移动大量元素

  (2)线性表链式存储结构

    结点(Node)由两部分组成:存放数据元素的数据域+存放后继结点地址的指针域

  获得链表第i个元素的思路:
    (1)声明一个结点p指向链表的第一个结点,初试化j从1开始;
    (2)当j<i 时,就遍历链表,让p指针向后移动,不断指向下一节点,j累加1;
    (3)若到链表末尾p为空,则说明第 i 个元素不存在;
    (4)否则查找成功,返回结点p的数据。
  核心思想:工作指针向后移
  1. /*
  2. * 查找方法
  3. * */
  4. public Node find(long value){
  5. Node current=first;//让current指向链表的第一个结点
  6. while(current.data!=value){  //如果data不等于value,就一直往下面遍历。
  7. if(current.next==null){  //若到了链表末尾,则没有找到,返回null
  8. return null;
  9. }
  10. current=current.next; //否则,不断往下个结点移动
  11. }
  12. return current; //当找到data等于value,则返回current
  13. }

  栗子:

  链表不具有的特点是(B)

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

     B.可随机访问任一元素(错误,因为要访问一个元素,链表头指针只能通过链表元素的指针域前或向后移动,所以并不能随机访问任意元素。)

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

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

  单链表第 i 个数据插入结点的算法思路:(先遍历查找第 i 个结点,再插入)

  (1)声明一个结点p指向链表的第一个结点,初始化j从1开始;
  (2)当j<i 时,就遍历链表,让p的指针向后移动,不断指向下一结点,j累加1;
  (3)若到链表末尾p为空,则说明第i个元素不存在;
      否则查找成功,在系统中生成一个空结点s;
  (4)将数据元素e赋值给s.data;
  (5)单链表的插入标准语句s.next=p.next;p.next=s;(注意顺序不能变)
    返回成功
 
  单链表第 i 个数据删除结点的算法思路:

(1)声明一结点p指向链表的第一个结点,初始化j从1开始;

(2)当j<i时,就遍历链表,让p的指针向后移动,不断指向下一个结点,j累加1;

(3)若到链表末尾p为空,则说明第i个元素不存在

(4)否则查找成功,将欲删除的结点p->next赋值给q;

(5)单链表的删除标准语句p->next=q->next;

(6)将q结点中的数据赋值给e,作为返回

(7)释放q结点;

(8)返回成功.

其实,1.删除可以归结为一步:p->next=p->next->next;

2.单链表插入和删除,都是由两部分组成:

遍历查找第i个结点,

插入和删除结点,

最坏的情况的时间复杂度都是O(n)

栗子:头插法整表创建和在头结点处进行删除结点

  1. Node
  2. package cn.itcast;
  3. /*
  4. * 链结点,相当于是车厢
  5. * */
  6. public class Node {
  7. //数据域
  8. public long data;
  9. //结点域(指针域):用来保存下一个节点的引用,初始化是null
  10. public Node next;
  11.  
  12. public Node(long value){
  13. this.data=value;
  14. }
  15.  
  16. /*
  17. * 显示方法
  18. * */
  19. public void display(){
  20. System.out.print(data+" ");
  21. }
  22. }
  23.  
  24. LinkList
  25. package cn.itcast;
  26. /*
  27. * 链表,相当于火车
  28. * */
  29. public class LinkList {
  30. //头结点
  31. private Node first;
  32. //默认构造函数
  33. public LinkList(){
  34. first=null;
  35. }
  36.  
  37. /*
  38. * 插入一个结点,在头结点后进行插入,头指针是链表中第一个结点的存储位置,而头指针是在头结点中的,头结点的数据域可以不存储任信息,也可以存储如线性表的长度的附加信息。头结点的指针与存储指向第一个结点的指针
  39. * */
  40. public void insertFirst(long value){
  41. Node node=new Node(value);
  42. node.next=first;  //将first作为node的后继结点
  43. first=node; //将当前新定义的node作为第一个结点,本来 first是第一个结点,可现在已经不是第一个结点了,现在第一个结点是 node。所以应该要让将node结点这个第一个结点赋值给first.此时,first又是第一个结点了。
  44. }
  45.  
  46. /*
  47. * 删除一个结点,在头结点后进行删除;单链表的第一个结点前附设一个结点,就是头结点
  48. * */
  49. public Node deleteFirst(){
  50. Node tmp=first;
  51. first=tmp.next;
  52. return tmp;
  53. }
  54.  
  55. /*
  56. * 显示方法*/
  57. public void display() {
  58. Node current=first;
  59. while(current!=null){
  60. current.display();
  61. current=current.next;
  62. }
  63. System.out.println();
  64. }
  65. /*
  66. * 查找方法
  67. * */
  68. public Node find(long value){
  69. Node current=first;//让current指向链表的第一个结点
  70. while(current.data!=value){  //如果data不等于value,就一直往下面遍历。
  71. if(current.next==null){  //若到了链表末尾,则没有找到,返回null
  72. return null;
  73. }
  74. current=current.next; //否则,不断往下个结点移动
  75. }
  76. return current; //当找到data等于value,则返回current
  77. }
  78.  
  79. /*
  80. * 删除方法,根据数据域来进行删除
  81. * */
  82. public Node delete(long value){
  83. Node current=first;
  84. Node previous=first;
  85. while(current.data!=value){
  86. if(current.next==null){
  87. return null;
  88. }else{
  89. previous=current;
  90. current=current.next; //将下一结点给current
  91. }
  92. }
  93. if(current==first){
  94. first=first.next; //如果是第一个结点,就把第一个结点的后继结点作为第一个结点
  95. }else{
  96. previous.next=current.next;//把当前结点current的后继结点(current.next)作为previous的后继结点(previous.next)
  97. }
  98. return current;
  99. }
  100.  
  101. }
  102.  
  103. TestLinkList
  104. package cn.itcast;
  105.  
  106. public class TestLinkList {
  107. public static void main(String[] args) {
  108. LinkList linklist=new LinkList();
  109. linklist.insertFirst(34);
  110. linklist.insertFirst(23);
  111. linklist.insertFirst(12);
  112. linklist.insertFirst(1);
  113. linklist.insertFirst(51);
  114. linklist.insertFirst(47);
  115.  
  116. linklist.display();
  117.  
  118. linklist.deleteFirst();//删除第一个结点,值value为47
  119. linklist.display();
  120.  
  121. Node node=linklist.find(51);//查找value是51的
  122. node.display();
  123. System.out.println();
  124. Node node1=linklist.delete(1);//删除值为1的
  125. node1.display();
  126. }
  127. }

  总结:单链表适合插入和删除操作,时间复杂度O(1)。而查找则是O(n)

     顺序存储结构适合查找,时间复杂度O(1)。而插入和删除操作则是O(n)(为什么适合查找?因为顺序用的是数组,只要data[i]就是想要查的元素)

栗子:

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

  1. A.顺序表
  2.  
  3. B.双链表
  4.  
  5. C.带头结点的双循环链表
  6.  
  7. D.单循环链表

线性表(List)的更多相关文章

  1. 线性表Linearlist

    顺序存储,链式存储,索引存储,散列存储 基本运算 SLIST         1.置空表 void SetNull(&L)     2.求长度 int Length(L)     3.取元素 ...

  2. 数据结构(Java描述)之线性表

    基础概念 数据结构:是相互之间存在一种或多种关系的数据元素的集合. 逻辑结构和物理结构 关于数据结构,我们可以从逻辑结构和物理结构这两个维度去描述 逻辑结构是数据对象中数据元素之间的关系,是从逻辑意义 ...

  3. JAVASE02-Unit04: 集合框架 、 集合操作 —— 线性表

    Unit04: 集合框架 . 集合操作 -- 线性表 操作集合元素相关方法 package day04; import java.util.ArrayList; import java.util.Co ...

  4. 数据结构代码整理(线性表,栈,队列,串,二叉树,图的建立和遍历stl,最小生成树prim算法)。。持续更新中。。。

    //归并排序递归方法实现 #include <iostream> #include <cstdio> using namespace std; #define maxn 100 ...

  5. Java集合类学习笔记(各种线性表性能分析)

    ArrayList.LinkedList是线性表的两种典型实现:基于数组的线性表和基于链的线性表. Queue代表了队列,Deque代表了双端队列. 一般来说,由于数组以一块连续内存区来保存所有的数组 ...

  6. 动态分配的顺序线性表的十五种操作—C语言实现

    线性表 定义:是最常用的,也是最简单的数据结构,是长度为n个数据元素的有序的序列. 含有大量记录的线性表叫文件 记录:稍微复杂的线性表里,数据元素为若干个数据项组成,这时把一个数据元素叫记录 结构特点 ...

  7. Java Se :线性表

    Java的集合框架分为两个系列,Collection和Map系列.在大学期间,学习数据结构时,好像学习了线性表.非线性表.树,哎,都给忘了.其实,在Collection系列内部又可以分为线性表.集合两 ...

  8. 数据结构算法C语言实现(二)---2.3线性表的链式表示和实现之单链表

    一.简述 [暂无] 二.头文件 #ifndef _2_3_part1_H_ #define _2_3_part1_H_ //2_3_part1.h /** author:zhaoyu email:zh ...

  9. 数据结构算法C语言实现(一)---2.2线性表的顺序表示和实现

    注意: 虽然是用C语言实现,但是考虑到使用了一个C++的特性----引用以简化代码,所以所有的代码均以cpp作为后缀,用g++编译(以后不做说明). g++版本: 一.简述 本节主要讲述线性表的顺序实 ...

  10. C#线性表之顺序表

    线性表是最简单.最基本.最常用的数据结构.线性表是线性结构的抽象(Abstract), 线性结构的特点是结构中的数据元素之间存在一对一的线性关系. 这种一对一的关系指的是数据元素之间的位置关系,即: ...

随机推荐

  1. nginx的安装及简单负载均衡配置

    Nginx 是一个很强大的高性能Web和反向代理服务器,它具有很多非常优越的特性.本人目前所在公司也使用nginx,主要用来做负载均衡服务器.同时也可以作为邮件代理服务器. 1. nginx的安装.本 ...

  2. 小程序里打开app的实现过程

    之前开发过类似得需求,也踩了一些小坑,在这里和大家分享下,毕竟这样的需求也不在少数,基本上产品后期都会有这样的需求: 官方说明 因为需要用户主动触发才能打开 APP,所以该功能不由 API 来调用,需 ...

  3. 01、Spark安装与配置

    01.Spark安装与配置 1.hadoop回顾 Hadoop是分布式计算引擎,含有四大模块,common.hdfs.mapreduce和yarn. 2.并发和并行 并发通常指针对单个节点的应对多个请 ...

  4. April 3 2017 Week 14 Monday

    Don't worry about finding your soul mate. Find yourself. 欲寻佳侣,先觅本心. You may fail to find your soul m ...

  5. POJ-3274 Gold Balanced Lineup---hash经典题!

    题目链接: https://vjudge.net/problem/POJ-3274 题目大意: 给定多头牛的属性,每头牛的属性由一个非负数表示,该数的二进制表示不会超过K位,它的二进制表示的每一位若为 ...

  6. 【BZOJ3622】已经没有什么好害怕的了(动态规划+广义容斥)

    点此看题面 大致题意: 有\(n\)个糖果和\(n\)个药片,各有自己的能量.将其两两配对,求糖果比药片能量大的组数恰好比药片比糖果能量大的组数多\(k\)组的方案数. 什么是广义容斥(二项式反演) ...

  7. 贪心,POJ(2709)

    题目链接:http://poj.org/problem?id=2709 解题报告: #include <stdio.h> #include <algorithm> #inclu ...

  8. CentOS7 设置开机自启

    [root@master-1 ~]# systemctl enable mariadb ln -s '/usr/lib/systemd/system/mariadb.service' '/etc/sy ...

  9. python selenium 模块的安装及使用

    安装 pip install selenium 或者到https://pypi.python.org/pypi/selenium 下载setup安装包,之后进入目录后运行python setup.py ...

  10. ReactiveCocoa实战: 模仿 "花瓣",重写 LeanCloud Rest Api的iOS REST Client.

    这一次我们将要讨论的是移动开发中比较重要的一环--网络请求的封装.鉴于个人经验有限,本文将在一定程度上参考 基于AFNetworking2.0和ReactiveCocoa2.1的iOS REST Cl ...