鏈表結構
鏈表是一種物理存儲單元上非連續、非順序的存儲結構,數據元素的邏輯順序是通過鏈表中的引用鏈接次序實現的。鏈表由結點組成。每個結點的構成:元素(數據元素的映象) +引用(指示後繼元素存儲位置),元素就是存儲數據的存儲單元,引用就是連接每個結點的地址數據。
何爲單鏈表
單鏈表是鏈式存取的結構,想要找到某個數據元素,必須先從第一個或者特指的某個元素向後查找。
代碼實現
功能包括:添加數據add, 修改數據update, 刪除數據remove,迭代器的實現,重寫toString方法。
注意:該鏈表結構設計時不允許重複元素出現。
package com.it;
import java.util.Iterator;
import com.it.SingleLink.Node;
/**
* 單鏈表數據結構
* @author Administrator
*
*/
public class SingleLink<T> implements Iterable<T>{
class Node{//創建節點類
private T date;
private Node next;
public Node(T date){
this.date = date;
}
}
private Node head;//頭結點
/**
* 添加數據
* @param date
* T數據
* @return
* Boolean類型返回值,true說明添加成功
* false說明添加失敗
*/
public boolean add(T date){//添加一個數據
boolean flag = false;
Node newNode = new Node(date);//創建新節點
//鏈表是否爲空
if(head==null){//爲空時,使用該數據創建節點,作爲頭結點
head = newNode;
flag = true;
}else{//不爲空,遍歷找到尾節點,next節點指向該新節點
Node tailNode = findTailNode();
tailNode.next = newNode;
flag = true;
}
return flag;
}
/**
* 移除數據
* @param date
* @return
*/
public boolean remove(T date){
boolean flag = false;
//遍歷鏈表,找到數據所在的節點
Node dateNode = findNode(date);
//找到前一個節點和後一個節點
Node prevNode = findPrevNode(date);
Node nextNode = dateNode.next;
if(prevNode==null){//說明該數據是頭結點
if(nextNode==null){//說明鏈表只有一個元素
//將頭結點置爲空
head = null;
flag = true;
}
//將頭結點指向下一個節點
head = nextNode;
flag = true;
}else if(nextNode==null){//說明該數據是尾節點
//將前一個節點的next節點置爲null
prevNode.next = null;
flag = true;
}else{//這時數據節點處在中間
//將前一個節點的next節點指向nextNode
prevNode.next = nextNode;
flag = true;
}
return flag;
}
/**
* 更新數據
* @param old
* @param newDate
* @return
*/
public boolean update(T old,T newDate){
boolean flag = false;
Node target = findNode(old);//找到要更新的節點(此時拿到的是節點的引用)
if(target==null){
throw new RuntimeException("沒有此數據");
}else{//確定節點已經存在
Node existNode = findNode(newDate);
if(existNode!=null){//確定數據唯一
throw new RuntimeException("該數據已經存在,請使用不存在的數據");
}
//修改該數據的date值
target.date = newDate;
flag = true;
}
return flag;
}
/**
* 查找前一個節點
* @param date
* 節點數據
* @return
* Node
*/
private Node findPrevNode(T date) {
//從頭開始遍歷
Node temp = head;
while(temp!=null){
if(temp.next!=null){
T dat = temp.next.date;
if(date.equals(dat)){
return temp;
}else{
temp = temp.next;//找到下一個節點
}
}
}
return null;
}
/**
* 根據數據內容查找節點
* @param date
* @return
*/
private Node findNode(T date) {
//從頭開始遍歷
Node temp = head;
while(temp!=null){
T dat = temp.date;
if(date.equals(dat)){
return temp;
}else{
if(temp.next!=null){//不是最後一個節點
temp = temp.next;//找到下一個節點
}else{//是最後一個節點
return null;
}
}
}
return null;
}
/**
* 找到尾節點
* @return
* 尾部節點
*/
private Node findTailNode() {
//從頭開始遍歷
Node temp = head;
Node tailNode = null;
while(temp!=null){
if(temp.next!=null){//不是最後一個節點
temp = temp.next;//找到下一個節點
}else{//是最後一個節點
tailNode = temp;
break;//跳出循環,將尾節點返回
}
}
return tailNode;
}
@Override
/**
* 重寫toString方法
*/
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append('[');
if(head!=null){
Node temp = head;
while(temp!=null){
if(temp.next!=null){//不是最後一個節點
sb.append(temp.date).append(',');
temp = temp.next;//找到下一個節點
}else{//是最後一個節點
sb.append(temp.date).append(']');
break;
}
}
}else
sb.append(']');
return sb.toString();
}
@Override
/**
* 迭代器的實現
* @return
*/
public Iterator<T> iterator() {
return new Iterator<T>() {
Node node = head;//從頭結點開始迭代
T date = null;//得到結點的數據
@Override
public boolean hasNext() {
return node!=null;
}
@Override
public T next() {
//先獲取到數據
date = node.date;
node = node.next;
return date;
}
@Override
public void remove() {
SingleLink.this.remove(date);
}
};
}
}