数据结构(java版)

链表(linkedList)

是一种常见的基础数据结构,是一种线性表,但是并不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的地址。

链表可分为单向链表和双向链表。

一个单向链表包含两个值: 当前节点的值和一个指向下一个节点的链接。 

一个双向链表有三个整数值: 数值、向后的节点链接、向前的节点链接。

Java LinkedList(链表) 类似于 ArrayList,是一种常用的数据容器。

与 ArrayList 相比,LinkedList 的增加和删除的操作效率更高,而查找和修改的操作效率较低。

以下情况使用 ArrayList :

  • 频繁访问列表中的某一个元素。
  • 只需要在列表末尾进行添加和删除元素操作。

以下情况使用 LinkedList :

  • 你需要通过循环迭代来访问列表中的某些元素。
  • 需要频繁的在列表开头、中间、末尾等位置进行添加和删除元素操作。

LinkedList 继承了 AbstractSequentialList 类。

LinkedList 实现了 Queue 接口,可作为队列使用。

LinkedList 实现了 List 接口,可进行列表的相关操作。

LinkedList 实现了 Deque 接口,可作为队列使用。

LinkedList 实现了 Cloneable 接口,可实现克隆。

LinkedList 实现了 java.io.Serializable 接口,即可支持序列化,能通过序列化去传输。

LinkedList 类位于 java.util 包中

但这里我跟着老韩实现了单链表的增删改

package com.czy.linkedlist;

/**
 * 1.
 * 2.
 * 3.单链表的创建
 **/
public class SingleLinkedListDemo {
    public static void main(String[] args) {

        /*
        * 进行测试
        * 先创建节点
        * */

        HeroNode people1 = new HeroNode(1, "tom", "boss");
        HeroNode people2 = new HeroNode(2, "jack", "worker");
        HeroNode people3 = new HeroNode(3, "luo", "worker2");
        HeroNode people4 = new HeroNode(4, "adt", "worker3");
        HeroNode people5 = new HeroNode(5, "klo", "worker4");

        //创建要给链表
        SingleLinkedList singleLinkedList = new SingleLinkedList();
        //加入add
        /*singleLinkedList.add(people1);
        singleLinkedList.add(people2);
        singleLinkedList.add(people3);
        singleLinkedList.add(people4);
        singleLinkedList.add(people5);
*/

        //加入addByOrder
        singleLinkedList.addByOrder(people1);
        singleLinkedList.addByOrder(people4);
        singleLinkedList.addByOrder(people5);
        singleLinkedList.addByOrder(people3);
        singleLinkedList.addByOrder(people2);
        //打印出来
        singleLinkedList.list();

        //测试修改节点的代码
        HeroNode wsw = new HeroNode(2, "WSW", "007");
        singleLinkedList.update(wsw);

        System.out.println("修改后的链表:");
        singleLinkedList.list();


        //测试删除节点的代码
        singleLinkedList.del(1);
        singleLinkedList.del(4);
        System.out.println("删除后的链表:");
        singleLinkedList.list();


    }
}

class SingleLinkedList{
    //先初始化一个头结点,头结点不要动,不存放具体的数据
    private HeroNode head = new HeroNode(0,"","");

    //添加节点到单向链表
    //思路,当不考虑编号顺序时
    //1.找到链表的最后节点
    //2.将最后这个节点的next域 指向 新的节点
    public void add(HeroNode heroNode){
        //因为头结点不能动,因此我们需要一个辅助遍历指针 temp
        HeroNode temp = head;
        //遍历链表,找到最后
        while (true) {
            //找到链表的最后
            if (temp.next == null){
                break;
            }
            //如果没有找到最后,将temp后移
            temp = temp.next;
        }
        //当退出while循环时,temp就指向了链表的最后
        //将最后这个节点的next,指向新的节点
        temp.next = heroNode;
    }

    //第二种方式在添加英雄时,根据排名将英雄插入到指定位置
    //(如果有排名,则添加失败,并给出提示)
    public void addByOrder(HeroNode heroNode){
        //因为头结点不能动,因此我们仍然通过一个辅助指针(变量)来帮助找到添加的位置
        //因为单链表,我们找的temp 是位于 添加位置前一个节点,否则插入不了
        HeroNode temp = head;
        boolean flag = false;  // flag标志添加的编号是否存在,默认为false
        while (true){
            if (temp.next == null){ //说明temp已在链表的最后
                break;
            }
            if (temp.next.no > heroNode.no){  //位置找到,就在temp的后面插入
                break;
            }else if (temp.next.no == heroNode.no){//说明希望添加的heroNode的编号依然存在
                flag = true;//说明编号存在
                break;
            }
            temp = temp.next;
        }
        //判断flag的值
        if (flag){//不能添加,说明编号已经存在
            System.out.printf("准备插入的编号已经存在,不能加入\n",heroNode.no);
        }else {
            //插入到链表中,temp的后面
            heroNode.next = temp.next;
            temp.next = heroNode;
        }
    }

    //修改节点的信息,根据no编号来修改,即no编号不能修改
    //说明
    //1.根据newHeroNode 的 no 来修改即可
    public void update(HeroNode newHeroNode){
        //判断是否为空
        if (head.next == null){
            System.out.println("链表为空~~~~");
            return;
        }
        //找到需要修改的节点,根据no来编写
        //定义一个辅助变量
        HeroNode temp = head.next;
        boolean flag = false; //表示是否找到该节点
        while (true){
            if (temp==null){
                break;//已经遍历完链表
            }
            if (temp.no == newHeroNode.no){
                //找到
                flag = true;
                break;
            }
            temp = temp.next;
        }
        //根据flag 判断是否找到要修改的节点
        if (flag){
            temp.name = newHeroNode.name;
            temp.nickname = newHeroNode.nickname;
        }else {
            System.out.printf("没有找到编号 d%的节点,不能修改\n",newHeroNode.no );
        }
    }

    //删除节点
    //思路
    //1.head节点不能动 因此我们仍然通过一个辅助指针(变量)来帮助找到待删除节点的前一个节点
    //2.说明我们在比较时,是temp.next.no 和 需要删除的节点的no比较
    public void del(int no){
        HeroNode temp = head;
        boolean flag = false; // 标志是否找到待删除节点
        while (true){
            if (temp == null){ //已经到链表的最后
                break;
            }
            if (temp.next.no == no){
                //找到的待删除节点的前一个节点
                flag = true;
                break;
            }
            temp = temp.next; // temp后移,遍历
        }
        if (flag){//找到
            //可以删除
            temp.next = temp.next.next;
        }else {
            System.out.printf("要删除的%d 节点不存在\n",no);
        }
    }
    //显示链表[遍历]
    public void list(){
        //判断链表是否为空
        if (head.next == null){
            System.out.println("链表为空");
            return;
        }
        //因为头结点不能动,我们需要一个赋值遍历来遍历
        HeroNode temp = head.next;
        while (true){
            //判断是否到链表的最后
            if (temp == null){
                break;
            }
            //输出节点的信息
            System.out.println(temp);
            //将temp后移
            temp = temp.next;
        }
    }
    //
}

//定义头结点HeroNode,每个HeroNode 对象就是一个节点
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;
    }
    //为了显示方法,我们重新toString

    @Override
    public String toString() {
        return "HeroNode{" +
                "no=" + no +
                ", name='" + name + '\'' +
                ", nickname='" + nickname + '\'' +
                '}';
    }
}

更具体一点,去下方链接

Java LinkedList | 菜鸟教程 (runoob.com)

猜你喜欢

转载自blog.csdn.net/weixin_46511995/article/details/125629784
今日推荐