zoukankan      html  css  js  c++  java
  • java线性表学习笔记(二)

    链表中的每一个元素都包含一个称为节点的结构,每向链表中增加一个元素,就会产生一个与之相关的节点,每个节点与它相邻的节点相连接(这是基础吧,不过在看c的时候没认真看,呼)。

    定义节点类如下(使用了泛型,下面有个简单的具体实例):

      class Node<E>{
          E element ;
          Node<E> next;
          public Node(E e){
               element = e;
          }
      }

    下面讲解一个储存3个元素的链表的例子,每一个节点储存一个字符串;

    1、先声明head(指向第一个节点) 和tai(指向最后一个节点),刚开始时都是null

    Node<E> head  =  null;
    Node<E> tail   =  null;
    //链表为空

    2、追加第一个节点

    head = new Node<E>("Chicgo");
    last = head;

    3、追加第二个节点

    tail.next  = new Node<E>("Denver");
    tail = tail.next;

    3、追加第三个节点

    tail.next = new Node<E>("Dallas");
    tail = tail.next;

    每一个节点都包含元素和一个名为next的数据域,next指向下一个元素。如果元素是链表中的最后一个元素。则它的next所包含的为null,用这个特性可以检测某个节点是否为最后一个节点,例如下面的遍历程序:

    Node current  = head;
    while()current !=null){
        System.out.println(current.element);
        current = current.next;
    }

    下面就结合上面的知识给个简单的int类型事例:

    //一个节点类,每一个元素都包含了一个称为节点的结构
    public class Node{  
        int element;
        Node next ;
         public Node(int n){  //元素赋值
             element = n;
         }    
        public static void main(String[] args) {
            Node head , tail;             //申明head和tail
            head = new Node(1);          //插入第一个元素        
            tail = head;                 //head和tail在一起
            System.out.println(head.element);     //输出第一个元素
            tail.next = new Node(2);       //插入第二个元素
            tail = tail.next;
            tail.next =new Node(3);
            tail = tail.next;
            Node current = head ;
            while (current != null){     //遍历寻遍输出
                System.out.print(current.element);
                current = current.next;    
            }
        }
    }

    java中有提供LinkedList的类,可以通过导入 java.util.LinkedList来使用,不过书本上有教我们写一个自己的MyLinkedList,便于理解,这对我们掌握链表还是很有必要的。下面我们可以来仔细研究一下MyLinkedList了,有好多方法,不像MyArrayList容易理解,书本上也只是讲了几个方法,剩下的就自己去理解了,也不是很难,这里讲3个吧,就当练习打字。

    (补充:head始终指向链表的第一个节点,而tail则始终指向最后一个节点)

    1、实现addFirst(e)方法,就是创建第一个节点:

    //创建一个包含e元素节点,并放在第一个节点
      public void addFirst(E e) {
        Node<E> newNode = new Node<E>(e); // 创建一个的节点
        newNode.next = head; //新节点的next数据域指向head
        head = newNode; // head 指向新的节点
        size++; 
    
        if (tail == null) // 若链表为空,则head和tail都指向新节点
          tail = head;
      }

    (书本上的那个图很好看,但是画不下来==)

    2、实现add(index,e)方法,当index为0或则是在最后一个元素时就不说了,直接调用方法addFirst(e)或则addLast(e)就行了,若插入到中间时,假设为current和temp节点之间,则首先从head开始前进找到current的next,并被新节点赋给它,在把新节点的next指向temp,画个图就很容易理解了。

    public void add(int index, E e) {
        if (index == 0) {
          addFirst(e);
        }
        else if (index >= size) {
          addLast(e);
        }
        else {
          Node<E> current = head;
          for (int i = 1; i < index; i++) {
            current = current.next;
          }
          Node<E> temp = current.next;
          current.next = new Node<E>(e);
          (current.next).next = temp;
          size++;
        }
      }

    3、实现removeLast()方法,如果链表为空就返回null,如果只有一个节点就销毁并且head和tail都变为null,否则最后一个节点销毁,tail指向倒数第二个节点,size减一。

    public E removeLast() {
       if (size == 0) {
         return null;
       }
       else if (size == 1) {
         Node<E> temp = head;
         head = tail = null;
         size = 0;
         return temp.element;
       }
       else {
         Node<E> current = head;    //要从head开始遍历,增加了时间
         for (int i = 0; i < size - 2; i++) {
           current = current.next;  //找到倒数第二个节点
         }
    
         Node<E> temp = tail;    //临时引用temp
         tail = current;
         tail.next = null;
         size--;
         return temp.element;     
       }
     }

    最后在给出MyLinkedList的实现(仅有部分方法实现,还有部分,做作业):

      1 public class MyLinkedList<E> extends MyAbstractList<E> {
      2   private Node<E> head, tail;
      3 
      4   //创建默认链表
      5   public MyLinkedList() {
      6   }
      7 
      8   public MyLinkedList(E[] objects) {
      9     super(objects);
     10   }
     11 
     12   //获得链表的头
     13   public E getFirst() {
     14     if (size == 0) {
     15       return null;
     16     }
     17     else {
     18       return head.element;
     19     }
     20   }
     21 
     22   //获得链表的尾
     23   public E getLast() {
     24     if (size == 0) {
     25       return null;
     26     }
     27     else {
     28       return tail.element;
     29     }
     30   }
     31 
     32   //创建一个包含e元素节点,并放在第一个节点
     33   public void addFirst(E e) {
     34     Node<E> newNode = new Node<E>(e); // 创建一个的节点
     35     newNode.next = head; //新节点的next数据域指向head
     36     head = newNode; // head 指向新的节点
     37     size++; 
     38 
     39     if (tail == null) // 若链表为空,则head和tail都指向新节点
     40       tail = head;
     41   }
     42 
     43   //创建一个包含e元素节点,并放在最后一个节点
     44   public void addLast(E e) {
     45     Node<E> newNode = new Node<E>(e); 
     46 
     47     if (tail == null) {
     48       head = tail = newNode; 
     49     }
     50     else {
     51       tail.next = newNode; 
     52       tail = tail.next;
     53     }
     54     size++; 
     55   }
     56 
     57 
     58   //将一个元素插入到链表的指定下标处
     59   public void add(int index, E e) {
     60     if (index == 0) {
     61       addFirst(e);
     62     }
     63     else if (index >= size) {
     64       addLast(e);
     65     }
     66     else {
     67       Node<E> current = head;
     68       for (int i = 1; i < index; i++) {
     69         current = current.next;
     70       }
     71       Node<E> temp = current.next;
     72       current.next = new Node<E>(e);
     73       (current.next).next = temp;
     74       size++;
     75     }
     76   }
     77 
     78   //删除链表中的的首个元素
     79   public E removeFirst() {
     80     if (size == 0) {
     81       return null;
     82     }
     83     else {
     84       Node<E> temp = head;
     85       head = head.next;
     86       size--;
     87       if (head == null) {
     88         tail = null;
     89       }
     90       return temp.element;
     91     }
     92   }
     93 
     94   //删除最后一个元素
     95   public E removeLast() {
     96     if (size == 0) {
     97       return null;
     98     }
     99     else if (size == 1) {
    100       Node<E> temp = head;
    101       head = tail = null;
    102       size = 0;
    103       return temp.element;
    104     }
    105     else {
    106       Node<E> current = head;    //要从head开始遍历,增加了时间
    107       for (int i = 0; i < size - 2; i++) {
    108         current = current.next;  //找到倒数第二个节点
    109       }
    110 
    111       Node<E> temp = tail;    //临时引用temp
    112       tail = current;
    113       tail.next = null;
    114       size--;
    115       return temp.element;     
    116     }
    117   }
    118 
    119   //删除指定下标的元素
    120   public E remove(int index) {
    121     if (index < 0 || index >= size) {
    122       return null;
    123     }
    124     else if (index == 0) {
    125       return removeFirst();
    126     }
    127     else if (index == size - 1) {
    128       return removeLast();
    129     }
    130     else {
    131       Node<E> previous = head;
    132 
    133       for (int i = 1; i < index; i++) {
    134         previous = previous.next;
    135       }
    136 
    137       Node<E> current = previous.next;
    138       previous.next = current.next;
    139       size--;
    140       return current.element;
    141     }
    142   }
    143 
    144   public String toString() {
    145     StringBuilder result = new StringBuilder("[");
    146 
    147     Node<E> current = head;
    148     for (int i = 0; i < size; i++) {
    149       result.append(current.element);
    150       current = current.next;
    151       if (current != null) {
    152         result.append(", "); // 插入歌逗号
    153       }
    154       else {
    155         result.append("]"); // 插入]
    156       }
    157     }
    158 
    159     return result.toString();
    160   }
    161 
    162   //清空
    163   public void clear() {
    164     head = tail = null;
    165   }
    166 
    167   
    168   /** Return true if this list contains the element o */
    169   public boolean contains(E o) {
    170     System.out.println("Implementation left as an exercise");
    171     return true;
    172   }
    173 
    174   /** Return the element from this list at the specified index */
    175   public E get(int index) {
    176     System.out.println("Implementation left as an exercise");
    177     return null;
    178   }
    179 
    180   /** Return the index of the head matching element in this list.
    181    *  Return -1 if no match. */
    182   public int indexOf(E o) {
    183     System.out.println("Implementation left as an exercise");
    184     return 0;
    185   }
    186 
    187   /** Return the index of the last matching element in this list
    188    *  Return -1 if no match. */
    189   public int lastIndexOf(E o) {
    190     System.out.println("Implementation left as an exercise");
    191     return 0;
    192   }
    193 
    194   /** Replace the element at the specified position in this list
    195    *  with the specified element. */
    196   public Object set(int index, E o) {
    197     System.out.println("Implementation left as an exercise");
    198     return null;
    199   }
    200 
    201 
    202   private static class Node<E> {
    203     E element;
    204     Node<E> next;
    205 
    206     public Node(E element) {
    207       this.element = element;
    208     }
    209   }
    210 }
    View Code


    在附上一个测试程序:

     1 public class TestLinkedList {
     2   /** Main method */
     3   public static void main(String[] args) {
     4     // Create a list for strings
     5     MyLinkedList<String> list = new MyLinkedList<String>();
     6 
     7     // Add elements to the list
     8     list.add("America"); // Add it to the list
     9     System.out.println("(1) " + list);
    10 
    11     list.add(0, "Canada"); // Add it to the beginning of the list
    12     System.out.println("(2) " + list);
    13 
    14     list.add("Russia"); // Add it to the end of the list
    15     System.out.println("(3) " + list);
    16 
    17     list.addLast("France"); // Add it to the end of the list
    18     System.out.println("(4) " + list);
    19 
    20     list.add(2, "Germany"); // Add it to the list at index 2
    21     System.out.println("(5) " + list);
    22 
    23     list.add(5, "Norway"); // Add it to the list at index 5
    24     System.out.println("(6) " + list);
    25 
    26     list.add(0, "Poland"); // Same as list.addFirst("Poland")
    27     System.out.println("(7) " + list);
    28 
    29     // Remove elements from the list
    30     list.remove(0); // Same as list.remove("Australia") in this case
    31     System.out.println("(8) " + list);
    32 
    33     list.remove(2); // Remove the element at index 2
    34     System.out.println("(9) " + list);
    35 
    36     list.remove(list.size() - 1); // Remove the last element
    37     System.out.println("(10) " + list);
    38   }
    39 }
    View Code


    关于MyArrayList和MyLinkedList的方法的复杂度,看下面的图

    N3[F@2(ZO0}E2Y3W37KA]}8

  • 相关阅读:
    C++数据类型之实型(浮点型)&科学计数法
    C++之数据类型--整形&sizeof关键字
    C++之关键字&标识符命名规则
    C++之常量
    C++之变量
    zabbix3.x添加华为(93069306)网络设备详解
    一些最常见的SNMP的OID自动翻译成zabbix数字进行表示(华为9306)
    Linux:日期用法,及格式定义
    linux awk命令详解
    Bash常用快捷键及其作用
  • 原文地址:https://www.cnblogs.com/LZYY/p/3275264.html
Copyright © 2011-2022 走看看