好玩的数据结构与算法——单链表

单链表

链表在内存中的示意图
好玩的数据结构与算法——单链表_第1张图片

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

单链表的逻辑结构示意图
好玩的数据结构与算法——单链表_第2张图片

单链表实例

4.直接添加

直接添加到单链表的尾部
好玩的数据结构与算法——单链表_第3张图片.代码实现:

    /**
     * @Description: 添加节点
     * 思路:
     * 1.先找到当前链表的最后节点
     * 2.将最后这个节点的next域指向新的节点
     */
    public void add(HeroNode  heroNode){
        // 辅助遍历变量
        HeroNode temp = head;
        // 遍历链表,找到最后
        while (true){
            //找到链表最后,并添加
            if (temp.getNext() == null){
                temp.setNext(heroNode);
                break;
            }
            // 如果没有找到最后,将temp后移
            temp = temp.getNext();
        }
    }

2.按照顺序添加

按照顺序添加
好玩的数据结构与算法——单链表_第4张图片
代码实现:

/**
* @Description: addOrder  按照编号顺序添加
*/
public void addOrder(HeroNode heroNode){
   HeroNode temp = head;
   // 标识英雄是否找到
   boolean flag = false;
   while (true){
       // 到了链表最后
       if (temp.getNext() == null){
           break;
       }
       //找到位置
       if (temp.getNext().getNo() > heroNode.getNo()){
           break;
       }else if (temp.getNext().getNo() == heroNode.getNo()){
           // 说明需要添加的heroNode的标号已经存在
           flag = true;
           break;
       }
       // 如果没有找到最后,将temp后移
       temp = temp.getNext();
   }
   if (flag){// 不能添加,编号已存在
       System.out.printf("准备插入的英雄编号%d已经存在,不能加入",temp.getNext().getNo());
   }else {// 添加
       heroNode.setNext(temp.getNext());
       temp.setNext(heroNode);
   }
}

3.修改节点

  1. 遍历找到节点信息
  2. 进行修改

代码实现:

/**
 * @Description: update 根据no更新信息
 */
public void update(HeroNode heroNode){
    HeroNode temp = head;
    if (temp.getNext() == null){
        System.out.println("链表为空~~~~~~~");
        return;
    }
    // 标识是否找到该节点
    boolean flag = false;
    while (true){
        if (temp.getNext() == null){
            break;
        }
        if (temp.getNext().getNo() == heroNode.getNo()){// 找到要修改的节点的前一个位置
            flag = true;
            break;
        }
        // 如果没有找到最后,将temp后移
        temp = temp.getNext();
    }
    if (flag){
        // 更新信息
        HeroNode next = temp.getNext();
        next.setName(heroNode.getName());
        next.setNckName(heroNode.getNckName());
    }else {
        System.out.printf("没有找到编号%d的节点,不能修改\n",heroNode.getNo());
    }
}

4. 删除节点信息

思路图
好玩的数据结构与算法——单链表_第5张图片
代码实现:

/**
 * @Description: deleteNode 删除节点,从要删除节点的上一个位置直接指向要删除节点的下一个位置,该节点会被垃圾回收机制回收
 */
public void deleteNode(HeroNode heroNode){
    HeroNode temp = head;
    // 表示是否找到节点信息
    boolean flag = false;
    while (true){
        if (temp.getNext() == null){
            break;
        }
        if (temp.getNext().getNo() == heroNode.getNo()){
            flag = true;
            break;
        }
        // 如果没有找到最后,将temp后移
        temp = temp.getNext();
    }
    if (flag){
        // 从要删除节点的上一个位置直接指向要删除节点的下一个位置,该节点会被垃圾回收机制回收
        temp.setNext(temp.getNext().getNext());
    }else {
        System.out.println("未找到该节点信息");
    }
}

全部代码

节点:

public class HeroNode {

    private int no;
    private String name;
    private String nckName;
    private HeroNode next;//下一个节点

    public int getNo() {
        return no;
    }

    public void setNo(int no) {
        this.no = no;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getNckName() {
        return nckName;
    }

    public void setNckName(String nckName) {
        this.nckName = nckName;
    }

    public HeroNode getNext() {
        return next;
    }

    public void setNext(HeroNode next) {
        this.next = next;
    }

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

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

链表实现代码:

public class SingleLinkedList {

    private HeroNode head = new HeroNode(0,"","");

    /**
     * @Description: 添加节点
     * 思路:
     * 1.先找到当前链表的最后节点
     * 2.将最后这个节点的next域指向新的节点
     */
    public void add(HeroNode  heroNode){
        // 辅助遍历变量
        HeroNode temp = head;
        // 遍历链表,找到最后
        while (true){
            //找到链表最后,并添加
            if (temp.getNext() == null){
                temp.setNext(heroNode);
                break;
            }
            // 如果没有找到最后,将temp后移
            temp = temp.getNext();
        }
    }

    /**
     * @Description: addOrder  按照编号顺序添加
     */
    public void addOrder(HeroNode heroNode){
        HeroNode temp = head;
        // 标识英雄是否找到
        boolean flag = false;
        while (true){
            // 到了链表最后
            if (temp.getNext() == null){
                break;
            }
            //找到位置
            if (temp.getNext().getNo() > heroNode.getNo()){
                break;
            }else if (temp.getNext().getNo() == heroNode.getNo()){
                // 说明需要添加的heroNode的标号已经存在
                flag = true;
                break;
            }
            // 如果没有找到最后,将temp后移
            temp = temp.getNext();
        }
        if (flag){// 不能添加,编号已存在
            System.out.printf("准备插入的英雄编号%d已经存在,不能加入",temp.getNext().getNo());
        }else {// 添加
            heroNode.setNext(temp.getNext());
            temp.setNext(heroNode);
        }
    }

    /**
     * @Description: update 根据no更新信息
     */
    public void update(HeroNode heroNode){
        HeroNode temp = head;
        if (temp.getNext() == null){
            System.out.println("链表为空~~~~~~~");
            return;
        }
        // 标识是否找到该节点
        boolean flag = false;
        while (true){
            if (temp.getNext() == null){
                break;
            }
            if (temp.getNext().getNo() == heroNode.getNo()){// 找到要修改的节点的前一个位置
                flag = true;
                break;
            }
            // 如果没有找到最后,将temp后移
            temp = temp.getNext();
        }
        if (flag){
            // 更新信息
            HeroNode next = temp.getNext();
            next.setName(heroNode.getName());
            next.setNckName(heroNode.getNckName());
        }else {
            System.out.printf("没有找到编号%d的节点,不能修改\n",heroNode.getNo());
        }
    }

    /**
     * @Description: deleteNode 删除节点,从要删除节点的上一个位置直接指向要删除节点的下一个位置,该节点会被垃圾回收机制回收
     */
    public void deleteNode(HeroNode heroNode){
        HeroNode temp = head;
        // 表示是否找到节点信息
        boolean flag = false;
        while (true){
            if (temp.getNext() == null){
                break;
            }
            if (temp.getNext().getNo() == heroNode.getNo()){
                flag = true;
                break;
            }
            // 如果没有找到最后,将temp后移
            temp = temp.getNext();
        }
        if (flag){
            // 从要删除节点的上一个位置直接指向要删除节点的下一个位置,该节点会被垃圾回收机制回收
            temp.setNext(temp.getNext().getNext());
        }else {
            System.out.println("未找到该节点信息");
        }
    }


    /**
     * @Description: 显示链表
     */
    public void show(){
        if(head.getNext() == null){
            System.out.println("链表为空");
            return;
        }
        HeroNode temp = head.getNext();
        while (true){
            if (temp == null){
                break;
            }
            // 输出节点信息
            System.out.println(temp);
            // 将temp后后移
            temp = temp.getNext();
        }
    }
}

测试链表代码

public class TestSingleLinkedList {
    public static void main(String[] args) {

        SingleLinkedList singleLinkedList = new SingleLinkedList();

        HeroNode heroNode1 = new HeroNode(1, "宋江", "及时雨");
        HeroNode heroNode2 = new HeroNode(2, "卢俊义", "玉麒麟");
        HeroNode heroNode3 = new HeroNode(3, "无用", "智多星");
        HeroNode heroNode4 = new HeroNode(4, "林冲", "豹子头");

//        System.out.println("按照顺序添加的顺序");

//        singleLinkedList.add(heroNode1);
//        singleLinkedList.add(heroNode2);
//        singleLinkedList.add(heroNode3);
//        singleLinkedList.add(heroNode4);
//        singleLinkedList.show();

        System.out.println("不按照顺序添加的顺序");
        singleLinkedList.addOrder(heroNode1);
        singleLinkedList.addOrder(heroNode4);
        singleLinkedList.addOrder(heroNode3);
        singleLinkedList.addOrder(heroNode2);
        singleLinkedList.show();

        System.out.println("修改节点信息");
        heroNode3.setName("吴用");
        singleLinkedList.update(heroNode3);
        singleLinkedList.show();

        System.out.println("删除节点");
        singleLinkedList.deleteNode(heroNode3);
        singleLinkedList.show();

    }
}

你可能感兴趣的:(数据结构与算法)