什么是鏈表?
鏈表是一個線性結構,但是存儲的數據可以是非線性的。鏈表由一個個子節點構成,每個節點有兩個部分:數據域和指針域,數據域就是實際存儲數據的,指針域可以有一個和兩個,單鏈表就是單個指針域指向后一個節點,雙鏈表就是節點有兩個指針域,分別指向前一個和后一個節點。
鏈表的核心:
鏈表的核心就是指針域,通過對指針域的操作實現增加節點刪除節點,所謂鏈表就是形象的表示出一環扣一環,這是鏈表的優點也是缺點,優點是:插入刪除不需要移動所有節點,只需要將待插入的節點的指針域一個指向待插入位置的后一個節點,一個指向前一個節點;缺點就是搜索的時候必須遍歷節點。
Java實現鏈表基本操作
//一個節點 class Node<E> { public Node next; public Node prev; public E item; public Node(E data) { this.item = data; next = null; prev = null; } } public class MyLinkedList<E> { private Node<E> head; //表頭 private Node<E> tail; //表尾 private int size; //表長 public MyLinkedList() { size = 0; head = null; tail = null; } public int size() { return this.size; } public void add(E o) { //將o增加到鏈表尾部 Node tempNode = new Node(o); if(size == 0){ //節點為空節點的時候 head = tempNode; tail =tempNode; }else { tail.next = tempNode; tempNode.prev = tail; tail = tempNode; } size++; } public E remove() { //從頭移除元素 return removeFirst(); } public void showList(){ Node<E> tempNode = head; while(tempNode != null){ System.out.println(tempNode.item + " "); tempNode = tempNode.next; } } public void showListRevise(){ Node<E> tempNode = tail; while(tempNode != null){ System.out.println(tempNode.item + " "); tempNode = tempNode.prev; } } public E remove(int index) { //刪除指定位置的元素 Node<E> tempNode; Node<E> resultNode; if(index<0 || index>size){ return null; }else { if (index < (size >> 1)) { tempNode = head; for(int i=0;i<index;i++) tempNode = tempNode.next; Node<E> par = tempNode.prev; Node<E> ch = tempNode.next; tempNode.prev.next = tempNode.next; tempNode.next.prev = tempNode.prev; resultNode = tempNode; } else { tempNode = tail; for(int i=size-1;index<i;i--) tempNode = tempNode.prev; resultNode = tempNode; tempNode = tempNode.prev; } size--; return resultNode.item; } } public boolean remove(Object o) { return removeFirstOccurrence(0); } public E removeFirst() { Node<E> tempNode; if(size>0){ tempNode = head; head = head.next; head.prev = null; size--; return tempNode.item; }else return null; } public E removeLast() { E temp = tail.item; tail = tail.prev; tail.next = null; size--; return temp; } public boolean removeFirstOccurrence(Object o){ //刪除此列表中指定元素的第一個出現(從頭到尾遍歷列表時)。 int tempSize = size; Node<E> tempNode = head; for(int i=0;i<tempSize;i++){ if(tempNode.item.equals(o)){ tempNode.prev = tempNode.next; tempNode.next = tempNode.prev; size--; return true; } } return false; } public void addFirst(E o) { //將o插入鏈表開頭 Node tempNode = new Node(o); if(size==0){ head = tempNode; tail = tempNode; }else { tempNode.next = head; tempNode.prev = null; //前一個節點是空 head = tempNode; } size++; } public void addLast(E o) { //將o增加到鏈表尾部 Node tempNode = new Node(o); if(size==0){ head = tempNode; tail = tempNode; }else { tail.next = tempNode; tempNode.prev = tail; tail = tempNode; } size++; } public void clear() { //清空鏈表 head = null; tail = null; size = 0; } public boolean contains(E o) { //判斷元素o是否包含於鏈表 int tempSize = size; Node tempNode = head; Boolean result = false; while (tempSize != 0) { Object o1 = tempNode.item; if(o.equals(o1)){ result = true; } tempNode = tempNode.next; tempSize--; } return result; } public E get(int index) { //獲取指定節點 Node<E> tempNode; if(index < 0 || index >= size) { return null; }else { if(index < (size >> 1)) { //右移 tempNode = head; for(int i=0;i<index;i++) tempNode = tempNode.next; return tempNode.item; }else { tempNode = tail; for (int i = size-1; index < i; i--) { System.out.println(index+ " " + i); tempNode = tempNode.prev; } return tempNode.item; } } } }