java由於沒有指針,實現鏈表可以通過對象的引用代替指針記錄對象位置完成
--鏈表的默認插入方式有兩種
1.頭插法:每次插入的節點爲鏈表頭,最初插入的節點爲鏈表尾。(每個新來的數據放在最前面,類似於一個棧)
實現:需要鏈表類定義全局的頭結點對象,每個節點包含了本身攜帶的數據及下個對象的引用(這裏的下個對象就是在你前面進來的那個數)。
2、尾插法 :每次插入的節點放在鏈表尾部,符合正常人邏輯。第一個加到鏈表的數據爲表頭,後來的數據依次添加;
實現:全局變量至少得有head,最好能加last,不然每次添加元素的時候都得遍歷鏈表全部數據才能添加下一個元素,因爲你根本不能知道尾部節點在哪裏,得從頭一個一個找;
尾插法代碼實現:
/**
* Created by 我來殺ai on 2019/4/11.
*/
public class MyLink {
/**
* * 自定義鏈表設計
* *
* *
* *
*
*/
Node head = null;
Node last = null;
// 頭節點
/**
* * 鏈表中的節點,data代表節點的值,next是指向下一個節點的引用
* *
* *
* *
*
*/
class Node {
Node next = null;
// 節點的引用,指向下一個節點
int data;
// 節點的對象,即內容
public Node(int data) {
this.data = data;
}
}
/**
* * 向鏈表中插入數據
* *
* * @param d
*
*/
public void addNode(int d) {
Node newNode = new Node(d);
// 實例化一個節點
if (head == null) {
head = newNode;
last = newNode;
return;
}
last.next = newNode;
last = newNode;
}
/**
* *
* * @param index:刪除第index個節點
* * @return
*
*/
public Boolean deleteNode(int index) {
if (index < 1 || index > length()) {
System.out.println("刪除失敗,沒有有效節點鏈");
return false;
}
//頭結點刪除
if (index == 1) {
head = head.next;
System.out.println("刪除成功,刪除了頭結點");
return true;
}
int flag = 2;//標識,因爲設置了前驅元素,所以當前元素開始就是第2個,刪頭元素的情況在上面寫過了
Node preNode = head; //precursor前驅 preNode前一個節點
Node curNode = preNode.next; //current當前 curNode當前節點
while (curNode != null) {
if (index == flag) {
//判斷是否是刪除了尾結點
if(flag == length()){
preNode.next=null;
last = preNode;
System.out.println("刪除了尾結點");
return true;
}
preNode.next = curNode.next;
System.out.println("刪除成功,刪除了第"+flag+"個節點");
return true;
}
preNode = curNode;
curNode = curNode.next;
flag++;
}
System.out.println("刪除錯誤");
return false;
}
/**
* *
* * @return 返回節點長度
*
*/
public int length() {
int length = 0;
Node tmp = head;
while (tmp != null) {
length++;
tmp = tmp.next;
}
return length;
}
/**
* 打印鏈表
*/
public void printList() {
Node tmp = head;
while (tmp != null) {
System.out.print("->|-"+tmp.data);
tmp = tmp.next;
}
System.out.println("-||");
}
/**
* 新增單鏈表反轉功能
* @param
*/
public boolean reverse(){
if (length()<=1){
System.out.println("小於一個節點的鏈表不能反轉");
return false;
}
Node newHead = head.next.next;//提前保存第三個節點的信息在大於2的鏈表使用,防止斷鏈發生的節點丟失
last = head;//首先原本的尾部指向頭部
Node second = head.next;//獲得第二個節點
second.next = head;//將第二個結點的next指向第一個結點
head.next = null;//將原頭結點的next指向空
head = second;//將head移到新的頭結點處
//當結點數大於2時
while (newHead!=null){
Node next = newHead.next;//提前保存下個節點的信息,防止斷鏈丟失
newHead.next = head; //將後半截鏈表頭結點指向反轉鏈表的頭結點
head = newHead;
newHead = next;
}
return true;
}
public static void main(String[] args) {
MyLink list = new MyLink();
list.addNode(36);
list.addNode(48);
list.addNode(55);
list.addNode(56);
list.addNode(57);
list.addNode(58);
list.addNode(59);
System.out.println("linkLength:" + list.length());
System.out.println("head.data:" + list.head.data);
System.out.println("last.data:" +list.last.data);
list.printList();
list.deleteNode(7);
System.out.println("刪除(7):");
list.printList();
System.out.println("打印尾結點");
System.out.println(list.last.data);
}
}
事實上單鏈表還是很難用,在知道一個節點的情況下,並不能直接新增或者刪除節點,因爲你只能知道該節點的後繼,不知道他的前驅。單鏈表只是用來一直增加數據足夠使用,如果有增刪操作最好還是使用雙鏈表,下篇博客實現雙鏈表。
單鏈表不通過使用新鏈表反轉方法 圖示 (請忽略這個搓比圖,關注內容就好):