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 + "}";
	}
}

你可能感兴趣的:(Java数据结构和算法-链表的学习记录)