单链表

链表介绍

链表是有序的列表,但是它在内存中的存储如下:

  • 链表是以节点的方式来存储,是链式存储
  • 每个节点包含data域,next域:指向下一个节点
  • 如图:发现链表的各个节点不一定是连续存储
  • 链表分带头结点的链表没有头结点的链表,根据实际需求来确定

单链表(带头结点)逻辑结构示意图如下

单链表的应用实例

使用带head头的单向链表实现 - 水浒英雄排行榜管理完成对英雄任务的增删改查

  • 第一种方法在添加英雄时,直接添加到链表的尾部 (需要一个辅助指针遍历到链表尾部[因为头结点不能动],进行添加)
  • 第二种方式在添加英雄的时候,根据排名将英雄插入到指定位置(如果有这个排名则添加失败,并给出提示)
  • 修改节点功能
    • 通过遍历,找到该节点
    • 对节点数据进行修改
  • 删除节点

代码

public class singleLinkedList {

    HeroNode hero1 = new HeroNode(1, "宋江", "及时雨");
    HeroNode hero2 = new HeroNode(2, "卢俊义", "玉麒麟");
    HeroNode hero3 = new HeroNode(3, "吴用", "智多星");
    HeroNode hero4 = new HeroNode(4, "林冲", "豹子头");

    /**
     * 测试单链表尾部插入
     *
     */
    @Test
    public void testAdd() {
        SingleLinkedList singleLinked = new SingleLinkedList();
        singleLinked.add(hero1);
        singleLinked.add(hero3);
        singleLinked.add(hero2);
        singleLinked.add(hero4);
        singleLinked.list();
    }
    //序号插入
    @Test
    public void testAddByOrder(){
        SingleLinkedList singleLinked = new SingleLinkedList();
        singleLinked.addByOrder(hero2);
        singleLinked.addByOrder(hero1);
        singleLinked.addByOrder(hero4);
        singleLinked.addByOrder(hero3);
        singleLinked.list();
    }
    @Test
    public void testUpdate(){
        SingleLinkedList singleLinked = new SingleLinkedList();
        singleLinked.addByOrder(hero2);
        singleLinked.addByOrder(hero1);
        singleLinked.addByOrder(hero4);
        singleLinked.addByOrder(hero3);
        System.out.println("修改前---------------------");
        singleLinked.list();
        HeroNode hero5 = new HeroNode(4, "林冲!!!", "豹子头$$$$$$$$");
        singleLinked.update(hero5);
        System.out.println("修改后---------------------");
        singleLinked.list();
    }

    @Test
    public void testDelete(){
        SingleLinkedList singleLinked = new SingleLinkedList();
        singleLinked.addByOrder(hero2);
        singleLinked.addByOrder(hero1);
        singleLinked.addByOrder(hero4);
        singleLinked.addByOrder(hero3);
        System.out.println("删除前----------------------------");
        singleLinked.list();
        singleLinked.delete(4);
        System.out.println("删除后----------------------------");
        singleLinked.list();
    }

}

class SingleLinkedList {
    //先创建一个头结点
    HeroNode head = new HeroNode(0, "", "");

    //直接在链表尾部添加元素
    public void add(HeroNode heroNode) {
        //由于头结点不能动,所以需要定义一个节点,指向头结点
        HeroNode tmp = head;

        while (true) {
            if (tmp.next == null) {
                break;
            }
            tmp = tmp.next;
        }
        tmp.next = heroNode;
    }

    // 按照顺序插入
    public void addByOrder(HeroNode heroNode){
        HeroNode tmp = head;
        while (true){
            if (tmp.next == null){
                break;
            }
            if (tmp.next.no == heroNode.no){
                System.out.printf("顺序为%d的节点已经存在\n",heroNode.no);
                return;
            }else if (tmp.next.no > heroNode.no){
                break;
            }
            tmp = tmp.next;
        }
        //插入
        heroNode.next = tmp.next;
        tmp.next = heroNode;
    }
    //链表节点修改 ,只能修改存在的节点,且不能修改节点的no
    public void update(HeroNode heroNode){
        if (head.next == null){
            System.out.println("链表为空!!");
            return;
        }
        HeroNode tmp = head.next;
        boolean flag = false;
        while (true){
            if (tmp == null){
                break;
            }
            if (tmp.no == heroNode.no){
                flag = true;
                break;
            }
            tmp = tmp.next;
        }
        if (flag){
            tmp.name = heroNode.name;
            tmp.nickName = heroNode.nickName;
        }else {
            System.out.printf("链表中不存在序号为%d的节点\n",heroNode.no);
        }
    }

    //删除链表元素,根据序号进行删除
    public void delete(int no){
        if (head.next == null){
            System.out.println("链表为空!!");
            return;
        }
        HeroNode tmp = head;
        boolean flag = false;
        while (true){
            if (tmp.next == null){
                break;
            }
            if (tmp.next.no == no){
                flag = true;
                break;
            }
            tmp = tmp.next;
        }
        if (flag){
            tmp.next = tmp.next.next;
        }else {
            System.out.printf("链表中没有序号为%d的节点\n",no);
        }
    }
    //显示链表
    public void list() {
        if (head.next == null) {
            System.out.println("链表为空!!");
            return;
        }
        HeroNode tmp = head.next;
        while (true) {
            if (tmp == null) {
                break;
            }
            System.out.println(tmp);
            tmp = tmp.next;
        }
    }

}

class HeroNode {
    public int no;
    public String name;
    public String nickName;
    public HeroNode next;

    public HeroNode(int no, String name, String nickName) {
        this.no = no;
        this.name = name;
        this.nickName = nickName;
    }

    @Override
    public String toString() {
        return "HeroNode{" +
                "no=" + no +
                ", name='" + name + '\'' +
                ", nickName='" + nickName + '\'' +
                '}';
    }
}
posted @ 2020-10-10 17:35  刘指导  阅读(193)  评论(0编辑  收藏  举报