数据结构之链表(单链表)

单链表的物理结构

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

说明:

1) 链表是以节点的方式来存储,是链式存储

2) 每个节点包含 data 域, next 域:指向下一个节点.

3) 如图:发现链表的各个节点不一定是连续存储.

4) 链表分带头节点的链表和没有头节点的链表,根据实际的需求来确定

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

 

\\

 

应用案例

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

关键点: 头指针 辅助变量遍历

1. 第一种方法在添加英雄时,直接添加到链表的尾部

2. 根据排名将英雄插入到指定位置(如果有这个排名,则添加失败,并给出提示)

 

 

 

 

 

3.修改节点

思路

(1) 先找到该节点,通过遍历,

(2) temp.name = newHeroNode.name ; temp.nickname= newHeroNode.nickname

4.删除节点

 

代码

package com.example.demo1.dataStructure;

/**
 * @author liangqing
 * @since 2021/2/2 11:21
 */
public class SingleLinkedList {

    //头节点 用于遍历使用
    private final Node head = new Node("", "", null);

    //第一种方式:往单链表中添加元素,尾部添加
    public void addNode(Node node) {
        Node temp = head;

        //遍历
        while (temp.next != null) {
            temp = temp.next;
        }
        temp.next = node;
    }

    //第二种方式:通过no顺序添加
    public void addByOrder(Node node) {
        Node temp = head;

        //1. 遍历链表,定位到相应的位置 2 直接添加操作
        boolean flag = false;
        while (temp.next != null) {
            if (temp.next.no > node.no) {
                break;
            } else if (temp.next.no.equals(node.no)) {
                flag = true;
                break;
            }
            temp = temp.next;
        }
        if (flag) {
            System.out.printf("准备插入的英雄的编号 %d 已经存在了, 不能加入\n", node.no);
        } else {
            node.next = temp.next;
            temp.next = node;
        }


    }

    //遍历链表
    public void listNode() {
        Node temp = head.next;

        while (temp != null) {
            System.out.println(temp);
            temp = temp.next;
        }

    }

    //修改节点
    public void updateNode(Node node) {
        Node temp = head.next;

        boolean flag = false;
        while (temp != null) {
            if (temp.no.equals(node.no)) {
                flag = true;
                break;
            }
            temp = temp.next;
        }
        if (flag) {
            temp.name = node.name;
            temp.nickName = node.nickName;
        } else {
            System.out.println("不存在要修改的元素");
        }
    }

    /*
    删除节点
    不管如何,先定义辅助操作节点
    1. 定位到当前元素的上一个元素
    2.调整上一个元素的下个指针指向下下个元素
    3.当前节点没有指针指向,根据gc可达性分析,垃圾对象,被回收
     */
    public void deleteNode(Node node) {
        Node temp = head;

        boolean flag = false;
        while (temp.next != null) {
            if (temp.next.no.equals(node.no)) {
                flag = true;
                break;
            }
            temp = temp.next;
        }
        if (flag) {
            temp.next = temp.next.next;
        } else {
            System.out.printf("删除的节点不存在%d", node.no);
        }
    }

    public static void main(String[] args) {
        //第一种方式遍历,尾部添加
        addOne();
        //第二种方式遍历,按照no添加
        addTwo();


    }

    private static void addOne() {
        SingleLinkedList singleLinkedList = new SingleLinkedList();
        Node node = new Node("lq", "lqqq", 1);
        Node node1 = new Node("qa", "qaaaa", 2);
        Node node2 = new Node("ws", "wsss", 3);

        singleLinkedList.addNode(node);
        singleLinkedList.addNode(node1);
        singleLinkedList.addNode(node2);

        singleLinkedList.listNode();
    }

    private static void addTwo() {
        SingleLinkedList singleLinked1List = new SingleLinkedList();
        Node node4 = new Node("lqq", "lqqq", 5);
        Node node5 = new Node("qaa", "qaaaa", 4);
        Node node6 = new Node("wss", "wsss", 2);
        singleLinked1List.addByOrder(node4);
        singleLinked1List.addByOrder(node5);
        singleLinked1List.addByOrder(node6);
        System.out.println("修改前");
        singleLinked1List.listNode();

        //修改节点
        singleLinked1List.updateNode(new Node("update", "update111", 4));
        System.out.println("修改后");
        singleLinked1List.listNode();
        System.out.println("删除后的节点");
        singleLinked1List.deleteNode(new Node("update", "update111", 4));
        singleLinked1List.listNode();
    }

    //单链表节点
    static class Node {

        private String name;

        private String nickName;

        private Integer no;

        private Node next;

        public Node(String name, String nickName, Integer no) {
            this.name = name;
            this.nickName = nickName;
            this.no = no;
        }


        //重写toString
        @Override
        public String toString() {
            return "Node{" +
                    "name='" + name + '\'' +
                    ", nickName='" + nickName + '\'' +
                    ", no=" + no +
                    '}';
        }
    }

}


 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值