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

posted @ 2013-08-22 16:53  兰幽  阅读(493)  评论(0编辑  收藏  举报