• 链表与顺序表



    顺序表:

    顺序表是用一组地址连续的存储单元来保存数据的,使用之前必须指定其长度,一但内存分配,不可动态改变大小。所以它具有随机存取,查找快速的特点,但是做插入或删除动作是,需要移动大量元素,效率较低。

    • 长度固定,必须在分配内存之前确定数组的长度。
    • 存储空间连续,即允许元素的随机访问。
    • 存储密度大,内存中存储的全部是数据元素。
    • 要访问特定元素,可以使用索引访问,时间复杂度为 O(1)
    • 要想在顺序表中插入或删除一个元素,都涉及到之后所有元素的移动,因此时间复杂度为 O(n)
    • 顺序表实现主要是是使用数组的扩容实现的,System.arraycopy()

          


    链表 :

    链表,是用一组任意的存储单元存储线性表的数据元素(这组存储单元可以是连续的,也可以是不连续的)。每个数据结点单元有两部分组成,一个是数据域,存储数据值;另一个是指针域,指向下一个数据单元。

    当多个结点通过指针指向,关联起来,就形成了一个链,即链表(java没有指针概念,指针是指对象,即结点)。

    链表可分为单链表、双链表、循环链表。

    单链表就是沿着单方向的链表。例如a->b->c->d…  只能顺序往下连接下去,即只可以从A往下找元素,但是反之则不行。

    对比:

    链表是线性表的链式存储结构,它相比于顺序表,在插入和删除元素时,效率要高很多。

    数组线性表类ArrayList 和链表类LinkedList 是实现List接口的两个具体类。ArrayList 数组储存元素,这个数组是动态创建的。如果元素个数超过了数组的容量,就创建一个更大的新数组,并将当前所有元素都复制到新数组中。LinkedList在一个链表中储存元素。

    如果需要通过下标来随机访问元素,但是除了在末尾处之外,不能在其他位置插入或删除元素,那么使用ArrayList更高效。

    需要在线性表任意位置上插入或删除元素,就应该选择LinkedList。线性表的大小可动态增大或减小,但数组一旦被创建,大小就是固定的。如不需要在线性表中插入或删除元素,那么数组是效率最高的数据结构。

    ArrayList是一个实现List接口的大小可变的数组,向ArrayList中添加元素,容量自动增大,但不能自动减小,需使用trimToSize()将数组容量减小到线性表的大小

    若要提取元素或者在线性表的尾部插入和删除元素,ArrayList的效率比较高,若要在线性表任意位置上插入和删除元素,LinkedList效率较高。

    链表基本算法

    插入结点

    假设要在单链表的a结点和b结点之间插入一个值为x的新结点。

    如下图所示,指针s指向一个值为x的结点,为了插入s。

    首先让s的next指针指向b,即s->next = p->next;

    然后,让a的next指针指向s,即p->next = s;

     

    删除结点

    假设要删除单链表中的b结点。

    首先,找到b结点前面的结点a。

    如下图所示,p指针指向a结点。b的下一个结点就是p->next->next。

    所以,只要让p的next指针跳过b结点,指向b的下一个结点就OK了,即p->next = p->next->next;

    链表代码实现

     1 package structure.link;
     2 /**
     3  * 
     4  * Description: 定义结点
     5  * @author 
     6  */
     7 public class Node {
     8     protected Node next;// 指针
     9     protected int data;// 数据数值
    10 
    11     public Node(int data) {
    12         this.data = data;
    13     }
    14 
    15     // 显示
    16     public void display() {
    17         System.out.print(data + " ");
    18     }
    19 
    20 }
      1 package structure.link;
      2 /**
      3  * 
      4  * Description: LinkList方法
      5  * @author 
      6  */
      7 public class LinkList {
      8     private Node first; // 头节点
      9     private int pos = 0; // 节点位置
     10 
     11     public LinkList() {
     12         this.first = null;
     13 
     14     }
     15 
     16     // 插入一个头节点
     17     public void addFirstNode(int data) {
     18         Node node = new Node(data);
     19         node.next = first;
     20         first = node;
     21     }
     22 
     23     // 删除一个头结点,并返回头结点
     24     public Node deleteFirstNode() {
     25         Node tempNode = first;
     26         first = tempNode.next;
     27         return tempNode;
     28     }
     29 
     30     // 在任意位置插入节点 在index的后面插入 (插入在原链表index之前)
     31     public void add(int index, int data) {
     32         Node node = new Node(data);
     33         Node current = first; // 现在的
     34         Node previous = first; // 之前的(现在的前一个)
     35 
     36         while (index != pos++) {
     37             previous = current;
     38             current = current.next;
     39         }
     40         node.next = current;
     41         previous.next = node;
     42         pos = 0;
     43     }
     44 
     45     // 删除任意位置的节点
     46     public Node deleteByPos(int index) {
     47         Node current = first; // 现在的
     48         Node previous = first; // 之前的(现在的前一个)
     49         while (index != pos++) {
     50             if (current.next == null) {
     51                 break;
     52             }
     53             previous = current;
     54             current = current.next;
     55         }
     56         if (current == previous) {
     57             first = first.next;
     58         } else {
     59             previous.next = current.next;
     60             pos = 0;
     61         }
     62         return current;
     63     }
     64 
     65     // 根据节点的data删除节点(仅仅删除第一个)
     66     public Node deleteByData(int data) {
     67         Node current = first;
     68         Node previous = first;
     69         while (data != current.data) {
     70             if (current.next == null) {
     71                 break;
     72             }
     73             previous = current;
     74             current = current.next;
     75         }
     76         if (current.data == data) {
     77             first = first.next;
     78         } else {
     79             previous.next = current.next;
     80         }
     81         return current;
     82     }
     83 
     84     // 显示出所有的节点信息
     85     public void displayAllNodes() {
     86         Node current = first;
     87         while (current != null) {
     88             current.display();
     89             current = current.next;
     90         }
     91         System.out.println();
     92     }
     93 
     94     // 根据位置查找节点信息
     95     public Node findByPos(int index) {
     96         Node current = first;
     97         while (index != pos++) {
     98             current = current.next;
     99         }
    100         return current;
    101     }
    102 
    103     // 根据数据查找节点信息
    104     public Node findByData(int data) {
    105         Node current = first;
    106         while (data != current.data) {
    107             if (current.next == null)
    108                 break;
    109             current = current.next;
    110         }
    111         return current;
    112 
    113     }
    114 
    115 }

      

  • 相关阅读:
    经典机器学习算法总结
    从0开始学Python---01
    Android-Canvas.save() Canvas.restore() 总结
    Android-属性动画原理总结
    设计模式-外观模式
    设计模式-模板方法
    设计模式-装饰者模式
    设计模式-策略模式
    设计模式-工厂方法模式
    设计模式-简单工厂模式
  • 原文地址:https://www.cnblogs.com/snow1314/p/4976672.html
Copyright © 2020-2023  润新知