鏈表介紹
鏈表是有序的列表:鏈表是一種物理存儲結構上非連續,非順序的存儲結構,數據元素的邏輯順序是通過鏈表中的指針鏈接次序實現的
- 鏈表是以節點的方式來存儲數據的
- 每個節點包含data域,next域(指向下一個節點)
- 每個節點不一定是連續存儲
- 鏈表分爲帶頭結點的鏈表和沒有頭結點的鏈表,根據實際的需求來確定
代碼實現
package com.data.structure;
import java.util.Objects;
import com.alibaba.fastjson.JSON;
/**
* 單鏈表實現
* @author Taoweidong
*/
public class HeroNode {
public static void main(String[] args) {
HeroNode node = new HeroNode(10, "晁蓋");
HeroNode node1 = new HeroNode(25, "宋江");
HeroNode node2 = new HeroNode(22, "武松");
node.add(node2);
node.add(node1);
node.showAll();
}
/**
* 添加節點
* @param node
*/
public void add(HeroNode node) {
// 遍歷鏈表
HeroNode tmp = this;
while (Objects.nonNull(tmp.getNext())) {
tmp = tmp.getNext();
}
tmp.setNext(node);
}
/**
* 顯示鏈表信息
*/
public void showAll() {
// 遍歷鏈表
HeroNode tmp = this;
while (Objects.nonNull(tmp)) {
System.out.printf("name=%s,age=%d\n", tmp.getName(), tmp.getAge());
tmp = tmp.getNext();
}
}
/**
* 年齡
*/
private int age;
/**
* 姓名
*/
private String name;
/**
* 下一個人物信息
*/
private HeroNode next;
public HeroNode(int age, String name) {
this.age = age;
this.name = name;
}
@Override
public String toString() {
return JSON.toJSONString(this);
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public HeroNode getNext() {
return next;
}
public void setNext(HeroNode next) {
this.next = next;
}
}
單鏈表的實際應用案例
- 單向鏈表的創建
- 單向鏈表的添加和顯示
- 單向鏈表的排序添加
- 單向鏈表刪除指定節點
package com.data.structure;
import org.apache.commons.lang3.StringUtils;
import java.util.Objects;
/**
* 單鏈表實現
* @author Taoweidong
*/
public class SingleLinkedList {
public static void main(String[] args) {
SingleHeroNode node1 = new SingleHeroNode(1, "張三", 12);
SingleHeroNode node2 = new SingleHeroNode(3, "李四", 66);
SingleHeroNode node3 = new SingleHeroNode(4, "王五", 25);
SingleHeroNode node4 = new SingleHeroNode(5, "馬六", 23);
SingleHeroNodeManage singleNode = new SingleHeroNodeManage();
singleNode.addByOrder(node1);
singleNode.addByOrder(node4);
singleNode.addByOrder(node3);
singleNode.addByOrder(node2);
singleNode.showAll();
System.out.println("**************************************");
SingleHeroNode node4New = new SingleHeroNode(55, "馬六000000000", 555);
singleNode.update(node4New);
singleNode.showAll();
System.out.println("**************************************");
singleNode.delete(node4New);
singleNode.showAll();
}
}
/**
* 管理器
*/
class SingleHeroNodeManage {
/**
* 先初始化一個頭結點:一般不需要動
*/
public SingleHeroNode head = new SingleHeroNode(0, StringUtils.EMPTY, 0);
/**
* 刪除節點
* @param node
*/
public void delete(SingleHeroNode node) {
SingleHeroNode temp = head;
boolean flag = false;
while (true) {
if (Objects.isNull(temp.next)) {
System.out.println("鏈表爲空");
break;
}
if (temp.next.no == node.no) {
//找到了待修改的節點
flag = true;
break;
}
//如果沒有找到,則節點繼續後移
temp = temp.next;
}
if (flag) {
//刪除當前節點:實際上也就是將待刪除節點的前一個節點的next指向修改
temp.next = temp.next.next;
} else {
System.out.println("沒有帶刪除的節點:" + node.no);
}
}
/**
* 更新節點
* @param node 節點
*/
public void update(SingleHeroNode node) {
SingleHeroNode temp = head;
while (true) {
if (Objects.isNull(temp.next)) {
System.out.println("鏈表爲空");
break;
}
if (temp.next.no == node.no) {
//找到了待修改的節點
temp.next.name = node.name;
temp.next.age = node.age;
break;
}
//如果沒有找到,則節點繼續後移
temp = temp.next;
}
}
/**
* 添加有序的節點
* @param node 節點
*/
public void addByOrder(SingleHeroNode node) {
SingleHeroNode temp = head;
// 檢查當前節點是否已經存在
boolean flag = false;
while (true) {
// 如果當前鏈表爲空:則可以直接插入
if (Objects.isNull(temp.next)) {
break;
}
// 找到了當前待插入節點的位置
if (temp.next.no > node.no) {
break;
} else if (temp.next.no == node.no) {
flag = true;
break;
}
// 沒有找到對應的節點:移動當前節點位置到下一個節點
temp = temp.next;
}
if (flag) {
System.out.println("待插入節點已經存在:" + node.no);
} else {
// 增加節點
node.next = temp.next;
temp.next = node;
}
}
/**
* 添加一個節點.
* @param node 節點
*/
public void add(SingleHeroNode node) {
// 1、找到當前鏈表的最後節點
// 2、將最後這個節點的next指向新的節點
SingleHeroNode temp = head;
while (true) {
// 找到鏈表的結尾
if (Objects.isNull(temp.next)) {
break;
}
// 如果沒有找到繼續後移
temp = temp.next;
}
// 退出循環時,temp就指向鏈表的最後
// 把新增的節點加到鏈表的最後
temp.next = node;
}
public void showAll() {
// 判斷鏈表是否爲空
if (Objects.isNull(head.next)) {
System.out.println("鏈表爲空");
return;
}
SingleHeroNode temp = head.next;
while (true) {
if (Objects.isNull(temp)) {
break;
}
// 輸出當前節點
System.out.println(temp.toString());
// 將下一個節點後移
temp = temp.next;
}
}
}
/**
* 節點對象
*/
class SingleHeroNode {
public int no;
public String name;
public int age;
public SingleHeroNode next;
/**
* 構造器
* @param no 編號
* @param name 姓名
* @param age 年齡
*/
public SingleHeroNode(int no, String name, int age) {
this.no = no;
this.name = name;
this.age = age;
}
@Override public String toString() {
return "SingleHeroNode{" + "no=" + no + ", name='" + name + '\'' + ", age=" + age + "}";
}
}