package test;
/**
* 雙向鏈表
* @author 冷浪進
*
*/
public class MyLinkedList {
//節點
class Node{
//指向向一節點
Node pre;
//指向下節點
Node next;
//節點的數據
Object data;
//兩個構造方法
public Node() { }
public Node(Node pre,Node next,Object data) {
this.pre = pre;
this.next = next;
this.data = data;
}
}
//保存頭結點
Node head;
//保存尾節點
Node tail;
//鏈表大小
int size;
/**
* 獲取鏈表大小
* @return
*/
public int size() {
return size;
}
/**
* 判斷是否爲空
* @return
*/
public boolean isEmpty() {
return size==0;
}
//查看節點數據的索引
public int indexOf(Object data) {
Node node = head;
for(int i=0; i<size&&node!=null; node=node.next,i++) {
if(node.data == data) {
return i;
}
}
return -1;
}
//查看指定索引的數據
private Node getNode(int index) {
//索引不在0到size之間
checkIndex(index);
//判斷index的值是否大於size的一半,再肯定從head開始,仍是從tail開始
//size>>1 ===> size/2 size>>1效率高
if(index <= size>>1) {
Node node = head;
for(int i=0; i<=size/2&&node!=null;node=node.next, i++) {
if(i==index) {
return node;
}
}
}else {//若是index<size/2
Node node = tail;
for(int i=size-1; i>size/2&&node!=null;node=node.pre, i--) {
if(i==index) {
return node;
}
}
}
return null;
}
public Object getValue(int index) {
return getNode(index).data;
}
private void checkIndex(int i) {
if(i<0||i>size) {
throw new RuntimeException("無效的索引");
}
}
//在鏈表的尾端添加節點
public void add(Object data) {
//判斷節點
if(head==null) {
head = new Node(null,null,data);
//只有一個節點,tail和head都指向該節點
tail = head;
}else {
//head不爲空,建立一個新節點 ,做爲最後一個節點
Node newNode = new Node(tail,null,data);
//首先最後一個節點指向新節點,而後再講tail指向新節點
tail.next = newNode;
tail = newNode;
}
size++;
}
//在指定索引加節點
public void add(int i,Object data) {
//索引不在
checkIndex(i);
if(head==null) {
head = new Node(null,null,data);
}else {
Node node = head;
for(int j=0; j<size&&node!=null; node=node.next,j++) {
if(i==j) {
Node no = new Node(node.pre,node,data);
node.pre.next = no;
node.pre = no;
}
}
}
size++;
}
//刪除最後一個節點
public Object remove() {
return remove(size-1);
}
//刪除指定索引的節點
public Object remove(int i) {
//判斷索引是否存在
checkIndex(i);
//獲取索引爲i的節點
Node node = getNode(i);
if(node.pre==null) {
head = node.next;
}else if(node.next==null) {
tail = tail.pre;
}else {
node.pre.next = node.next;
node.next.pre = node.pre;
}
size--;
return node.data;
}
//判斷是否包含key
public boolean contains(Object key) {
//直接判斷能夠的索引是否爲-1,若是是-1不存在
if(indexOf(key)==-1) {
return false;
}
return true;
}
//用data替換i索引處的數據
public void replace(int i,Object data) {
//判斷索引是否存在
checkIndex(i);
Node node = head;
for(int j=0; j<size&&node!=null; node = node.next, j++) {
if(i==j) {
node.data = data;
}
}
}
@Override
public String toString() {
StringBuffer sb = new StringBuffer("[");
Node node = head;
for(int i=0; i<size&&node!=null; node=node.next,i++) {
sb.append(node.data+",");
}
return sb.delete(sb.length()-1, sb.length()).append("]").toString();
}node
public static void main(String[] args) {
MyLinkedList my = new MyLinkedList();
my.add(1);
my.add(2);
my.add("34");
my.add("冷浪進");
System.out.println(my.size);
my.add(1,"冷霞");
my.replace(0, "王永先");
System.out.println(my.contains("冷浪進"));
my.remove(2);
System.out.println(my.getValue(2));
System.out.println(my.indexOf("34"));
System.out.println(my);
}
}app
運行結果ide
4
true
34
2
[王永先,冷霞,34,冷浪進]this