Java數據結構和算法-鏈表的學習記錄

鏈表介紹

鏈表是有序的列表:鏈表是一種物理存儲結構上非連續,非順序的存儲結構,數據元素的邏輯順序是通過鏈表中的指針鏈接次序實現的

  • 鏈表是以節點的方式來存儲數據的
  • 每個節點包含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 + "}";
	}
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章