什么是鏈表?
鏈表是一個線性結構,但是存儲的數據可以是非線性的。鏈表由一個個子節點構成,每個節點有兩個部分:數據域和指針域,數據域就是實際存儲數據的,指針域可以有一個和兩個,單鏈表就是單個指針域指向后一個節點,雙鏈表就是節點有兩個指針域,分別指向前一個和后一個節點。
鏈表的核心:
鏈表的核心就是指針域,通過對指針域的操作實現增加節點刪除節點,所謂鏈表就是形象的表示出一環扣一環,這是鏈表的優點也是缺點,優點是:插入刪除不需要移動所有節點,只需要將待插入的節點的指針域一個指向待插入位置的后一個節點,一個指向前一個節點;缺點就是搜索的時候必須遍歷節點。
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;
}
}
}
}
