package LinkedList;
/**
* <p><strong>我的Java單鏈表練習</strong></p>
* <p>單鏈表提供了在列表頭的高效插入和刪除操作,不過在單鏈表的末尾的插入操作效率很低.</p>
* <p>單鏈表指針域保存着下一節點的引用,尾結點的指針域等於null</p>
* @author baby69yy2000
*/
public class SingleLinkedList<T> {
/**
* 結點類
*/
private static class Node<T> {
T nodeValue; // 數據域
Node<T> next; // 指針域保存着下一節點的引用
Node(T nodeValue, Node<T> next) {
this.nodeValue = nodeValue;
this.next = next;
}
Node(T nodeValue) {
this(nodeValue, null);
}
}
// 下面是SingleLinkedList類的數據成員和方法
private Node<T> head, tail;
public SingleLinkedList() {
head = tail = null;
}
/**
* 判斷鏈表是否爲空
*/
public boolean isEmpty() {
return head == null;
}
/**
* 創建頭指針,該方法只用一次!
*/
public void addToHead(T item) {
head = new Node<T>(item);
if(tail == null) tail = head;
}
/**
* 添加尾指針,該方法使用多次
*/
public void addToTail(T item) {
if (!isEmpty()) { // 若鏈表非空那麼將尾指針的next初使化爲一個新的元素
tail.next = new Node<T>(item); // 然後將尾指針指向現在它自己的下一個元素
tail = tail.next;
} else { // 如果爲空則創建一個新的!並將頭尾同時指向它
head = tail = new Node<T>(item);
}
}
/**
* 打印列表
*/
public void printList() {
if (isEmpty()) {
System.out.println("null");
} else {
for(Node<T> p = head; p != null; p = p.next)
System.out.println(p.nodeValue);
}
}
/**
* 在表頭插入結點,效率非常高
*/
public void addFirst(T item) {
Node<T> newNode = new Node<T>(item);
newNode.next = head;
head = newNode;
}
/**
* 在表尾插入結點,效率很低
*/
public void addLast(T item) {
Node<T> newNode = new Node<T>(item);
Node<T> p = head;
while (p.next != null) p = p.next;
p.next = newNode;
newNode.next = null;
}
/**
* 在表頭刪除結點,效率非常高
*/
public void removeFirst() {
if (!isEmpty()) head = head.next;
else System.out.println("The list have been emptied!");
}
/**
* 在表尾刪除結點,效率很低
*/
public void removeLast() {
Node<T> prev = null, curr = head;
while(curr.next != null) {
prev = curr;
curr = curr.next;
if(curr.next == null) prev.next = null;
}
}
/**
* <p>插入一個新結點</p>
* <ul>插入操作可能有四種情況:
* <li>①表爲空, 返回false</li>
* <li>②表非空,指定的數據不存在</li>
* <li>③指定的數據是表的第一個元素</li>
* <li>④指定的數據在表的中間</li></ul>
* @param appointedItem 指定的nodeValue
* @param item 要插入的結點
* @return 成功插入返回true;
*/
public boolean insert(T appointedItem, T item) {
Node<T> prev = head, curr = head.next, newNode;
newNode = new Node<T>(item);
if(!isEmpty()) {
while((curr != null) && (!appointedItem.equals(curr.nodeValue))) { //兩個判斷條件不能換
prev = curr;
curr = curr.next;
}
newNode.next = curr; //②③④
prev.next = newNode;
return true;
}
return false; //①
}
/**
* <p>移除此列表中首次出現的指定元素</p>
* <ul>刪除操作可能出現的情況:
* <li>①prev爲空,這意味着curr爲head. head = curr.next; --> removeFirst();</li>
* <li>②匹配出現在列表中的某個中間位置,此時執行的操作是 --> prev.next = curr.next;,</li></ul>
* <p>在列表中定位某個結點需要兩個引用:一個對前一結點(prev左)的引用以及一個對當前結點(curr右)的引用.</p>
* prev = curr;
* curr = curr.next;
*/
public void remove(T item) {
Node<T> curr = head, prev = null;
boolean found = false;
while (curr != null && !found) {
if (item.equals(curr.nodeValue)) {
if(prev == null) removeFirst();
else prev.next = curr.next;
found = true;
} else {
prev = curr;
curr = curr.next;
}
}
}
/**
* 返回此列表中首次出現的指定元素的索引,如果列表中不包含此元素,則返回 -1.
*/
public int indexOf(T item) {
int index = 0;
Node<T> p;
for(p = head; p != null; p = p.next) {
if(item.equals(p.nodeValue))
return index;
index++;
}
return -1;
}
/**
* 如果此列表包含指定元素,則返回 true。
*/
public boolean contains(T item) {
return indexOf(item) != -1;
}
public static void main(String[] args) {
SingleLinkedList<String> t = new SingleLinkedList<String>();
t.addToHead("A");
//t.addFirst("addFirst");
t.addToTail("B");
t.addToTail("C");
System.out.println(t.indexOf("C")); // 2
System.out.println(t.contains("A")); // true
//t.addLast("addLast");
//t.removeLast();
//t.insert("B", "insert");
//t.removeFirst();
//t.remove("B"); // A C
t.printList(); // A B C
}
}
java實現單鏈表
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.