普通單向鏈表應該包含的數據和方法:
結點類(Node):
屬性:
AnyType value; //任意類型的數據
Node* next; //指向下一個節點的指針
方法:
構造方法 Node(AnyType* value, Node* next);
鏈表類(LinkedList):
Node* head; //鏈表頭結點的指針
Node* tail; //鏈表尾結點的指針,可選
int length; //鏈表長度,可選
int isEmpty(); //鏈表是否爲空
int contains(); //鏈表是否包含某個值
void addToHead(AnyType value); //向鏈表頭添加數據
void addToTail(AnyType value); //向鏈表尾添加數據
void addNode(AnyType value, int index) //向鏈表指定下標處添加數據
int deleteFromHead(); //從鏈表頭刪除一個數據,返回被刪除的數據
int deleteFromTail(); //從鏈表尾刪除一個數據,返回被刪除的數據
int deleteNode(); //刪除指定下標處的數據,返回被刪除的數據
實現每種方法的思路:
1、因爲LinkedList類的屬性有:head,tail,length
所以要根據不同情況更新三個屬性
2、所以每種方法,都要處理:
1)head發生變化
2)tail發生變化
的情況
下方是Java代碼:
//鏈表類
public class LinkedList {
//
Node head; //鏈表頭結點的指針
Node tail; //鏈表尾結點的指針,可選
int length; //鏈表長度,可選
int isEmpty() { //鏈表是否爲空
//頭結點爲空,鏈表爲空
return head == null ? 1 : 0;
};
int contains(int value) { //鏈表是否包含某個值
//遍歷鏈表,查找值
for (Node now=head; now!=null; now=now.next)
if (now.value == value)
return 1;
return 0;
}
void addToHead(int value) { //向鏈表頭添加數據
//如果鏈表爲空,更新head和tail
if (head == null)
head = tail = new Node(value);
//否則直接添加
else
this.head = new Node(value, this.head);
this.length++;
}
void addToTail(int value) { //向鏈表尾添加數據
//如果鏈表爲空,更新head和tail
if (head == null)
head = tail = new Node(value);
//否則直接添加
else
tail = tail.next = new Node(value);
length++;
}
void addNode(int value, int index) { //向鏈表指定下標處添加數據
//如果要添加的下標不合法,直接返回
if (index <= 0) return;
//如果鏈表爲空,且在第一個位置插入
if (head == null && index == 1) {
head = tail = new Node(value);
length++;
return ;
}
//如果鏈表爲空,要在非法位置插入
else if (head == null && index != 1) {
return ;
}
//如果在頭部插入,更新head
if (index == 1) {
head = new Node(value, head);
length++;
return ;
}
//在其他部位插入
Node aheadOfAdd = null;
int cnt = 1;
//循環查找鏈表,找到index-1位置的結點,存入aheadOfAdd
//使得循環停止的條件有兩個:
//情況1:aheadOfAdd=null單獨成立,說明要添加的序號已經超出現有的鏈表長度
//情況2:cnt+1=index成立且aheadOfAdd爲空,說明要插入的位置剛好在鏈表尾向後第二個位置
//情況3:cnt+1=index單獨成立,說明找到了要插入的結點的前一個結點
for (aheadOfAdd=head,cnt=1; aheadOfAdd!=null&&cnt+1<index; cnt++,aheadOfAdd=aheadOfAdd.next);
//System.out.println(cnt);
//System.out.println(aheadOfAdd);
//情況1
if (index != cnt+1)
return ;
//情況2
if (aheadOfAdd == null)
return ;
//情況3
aheadOfAdd.next = new Node(value, aheadOfAdd.next);
length++;
if (aheadOfAdd.next.next == null) tail = aheadOfAdd.next;
}
int deleteFromHead() { //從鏈表頭刪除一個數據,返回被刪除的數據
int deletedValue = -1;
//鏈表爲空,直接返回
if (head == null)
return -1;
deletedValue = head.value;
//鏈表只有一個元素,刪除並更新head和tail
if (head == tail)
head = tail = null;
//刪除頭部
else
head = head.next;
length--;
return deletedValue;
}
int deleteFromTail() { //從鏈表尾刪除一個數據,返回被刪除的數據
int deletedValue = -1;
//鏈表爲空,直接返回
if (head == null)
return -1;
//鏈表只有一個元素,刪除並更新head和tail
if (head == tail) {
deletedValue = head.value;
head = tail = null;
}
//刪除尾部
else {
Node now = null;
//遍歷找到尾部
for (now = head; now.next!=tail; now=now.next);
deletedValue = now.next.value;
now.next = null;
tail = now;
}
length--;
return deletedValue;
}
int deleteNode(int index) { //刪除指定下標處的數據,返回被刪除的數據
//下標不合法,直接返回
if (index <= 0) return -1;
int deletedValue = -1;
int cnt = 1;
Node now = null;
//鏈表爲空,直接返回
if (head == null)
return -1;
//鏈表只有一個結點且要刪除那個結點
if (head == tail && index == 1) {
deletedValue = head.value;
head = tail = null;
}
//如果要刪除第一個結點,那麼下方循環將會出現問題,所以單獨處理
if (index == 1) {
deletedValue = head.value;
head = head.next;
}
else {
//循環找到要刪除的那個結點
//循環終止的條件有兩個
//情況1:now==null成立,找到要刪除的結點之前已經到了鏈表尾
//情況2:cnt+1=index成立,找到了要刪除的結點的前一個結點
for(now=head; cnt+1<index && now!=null; cnt++,now=now.next);
//情況1
if(now == null) return -1;
//情況2
deletedValue = now.next.value;
if (now.next == tail)
tail = now;
now.next = now.next.next;
}
length--;
return deletedValue;
}
//轉換爲字符串方便顯示
public String toString() {
StringBuilder sb = new StringBuilder("LinkedList: [");
for (Node now = head; now!=null; now=now.next) {
sb.append(now.value + ", ");
}
sb.append("]");
if (head != null)
sb.append("\n\t\t@ StartValue: " + head.value
+ "; TailValue: " + tail.value
+ "; Length: " + length);
return sb.toString();
}
//打印鏈表內容
void printSelf() {
System.out.println(this.toString());
}
//測試函數
static public void main(String[] argv) {
LinkedList list = new LinkedList();
list.addToHead(1);list.addToHead(2);list.addToHead(5);list.printSelf();
//list.deleteFromHead();list.deleteFromTail();list.printSelf();
list.addNode(12, 1);list.printSelf();
list.deleteNode(1);list.printSelf();
//System.out.println(list.contains(5));
//System.out.println(list.isEmpty());
}
}
//鏈表的結點
class Node{
int value; //節點的值
Node next; //下一個結點的指針
//兩個構造函數
public Node(int value) {
this.value = value;
this.next = null;
}
public Node(int value, Node next) {
this.value = value;
this.next = next;
}
}