数据结构——>链表

单链表内存结构
在这里插入图片描述
单链表的逻辑结构
在这里插入图片描述

单向链表

单向链表定义

1、链表是以节点方式储存,是链式储存
2、每个节点包含data域,next域(指向下一个节点)
3、链表的各个节点不一定是连续储存
4、链表分为带头节点的链表和不带头节点的链表
5、链表的内存结构

单向链表应用

使用链表对池塘鱼儿的增删改查

1、增

/**
     * 思路:
     * 1、找到当前链表的最后节点
     * 2、将最后这个节点的next指向新的节点
     */
    public void add(girlfriendsNode gfNode) {
    
    

        //因为头节点(head)不能动,因此我们需要一个辅助
        girlfriendsNode temp = head;
        //遍历链表,找到最后
        while (true) {
    
    
            //找到链表的最后
            if (temp.next == null) {
    
    
                break;
            }
            //如果没有找到最后,将temp后移
            temp = temp.next;
        }
        //当退出循环时,temp就指向了链表的最后
        temp.next = gfNode;
    }

2、删

/**
     * 思路
     * 1、head头节点不能动,因此我们需要一个temp辅助节点找到待删除的前一个节点
     * 2、说明我们在比较时,是temp.next.no和需要删除的节点的no比较
     */
    public void delete(int no) {
    
    
        girlfriendsNode temp = head;
        //是否找到节点
        boolean flag = false;
        //判空
        while (true) {
    
    
            if (temp.next == null) {
    
    //已经找到链表最后
                break;
            }
            if (temp.no == no) {
    
    
                //找到的待删除节点的前一个节点temp
                flag = true;
                break;
            }
            temp = temp.next;//后移
        }
        //判断flag
        if (flag) {
    
    //找到
            //删除
            temp.next = temp.next.next;//相当于下一个节点下标赋给前一个节点下标
        } else {
    
    
            System.out.printf("无法删除%d号节点",no);
        }
    }

3、改

//修改节点信息,根据no编号来修改,跟数据库的修改操作是一个意思
    public void update(girlfriendsNode newgirlfriendsNode) {
    
    
        //判空
        if (head.next == null) {
    
    
            System.out.println("链表为空");
            return;
        }
        //定义辅助节点,找到需要修改的节点,根据no编号
        girlfriendsNode temp = head;
        Boolean flag = false;//表示是否找到该节点,没找到就不能修改
        while (true) {
    
    
            if (temp == null) {
    
    
                break;//说明此时指针在链表最后
            }
            if (temp.no == newgirlfriendsNode.no) {
    
    
                //找到节点
                flag = true;
                break;
            }
            temp = temp.next;
        }
        //根据flag,判断是否找到要修改的节点
        if (flag) {
    
    
            temp.name = newgirlfriendsNode.name;
            temp.nickname = newgirlfriendsNode.nickname;
        } else {
    
    //没找到节点
            System.out.printf("没有找到编号%d的节点", newgirlfriendsNode.no);
        }
    }

4、查

    //显示链表
    public void list() {
    
    
        //判断链表是否为空
        if (head.next == null) {
    
    
            System.out.println("链表为空");
            return;
        }
        //因为头节点不能动,需要用上面的辅助节点来遍历
        girlfriendsNode temp = head.next;
        while (true) {
    
    
            //判断是否到了链表的最后
            if (temp == null) {
    
    
                break;
            }
            //输出节点信息
            System.out.println(temp);
            //将节点后移
            temp = temp.next;
        }
    }

完整代码

package linkedlist;

/**
 * @author shkstart
 * @create 2021-07-27 14:34
 */
public class SingleLinkListDemo {
    
    
    public static void main(String[] args) {
    
    
        //测试
        //创建节点
        girlfriendsNode gf1 = new girlfriendsNode(1, "莺莺", "肤白");
        girlfriendsNode gf2 = new girlfriendsNode(2, "燕燕", "貌美");
        girlfriendsNode gf3 = new girlfriendsNode(3, "红红", "大长腿");
        girlfriendsNode gf4 = new girlfriendsNode(4, "绿绿", "傻白甜");

        //创建链表
        SingleLinkedlist singleLinkedlist = new SingleLinkedlist();
        //把节点加入链表
        singleLinkedlist.add(gf1);
        singleLinkedlist.add(gf2);
        singleLinkedlist.add(gf3);
        singleLinkedlist.add(gf4);
        //显示链表
        System.out.println("修改前");
        singleLinkedlist.list();

        //测试修改节点的代码
        girlfriendsNode newgf = new girlfriendsNode(3, "豆豆", "大长腿");
        System.out.println("修改后");
        singleLinkedlist.update(newgf);
        singleLinkedlist.list();


        //删除一个节点的方法
        System.out.println("删除节点之后");
        singleLinkedlist.delete(3);
        singleLinkedlist.list();
    }
}

//定义链表,管理备胎
class SingleLinkedlist {
    
    
    //初始化头节点
    private girlfriendsNode head = new girlfriendsNode(0, "", "");

    //添加节点到链表

    /**
     * 思路:
     * 1、找到当前链表的最后节点
     * 2、将最后这个节点的next指向新的节点
     */
    public void add(girlfriendsNode gfNode) {
    
    

        //因为头节点(head)不能动,因此我们需要一个辅助
        girlfriendsNode temp = head;
        //遍历链表,找到最后
        while (true) {
    
    
            //找到链表的最后
            if (temp.next == null) {
    
    
                break;
            }
            //如果没有找到最后,将temp后移
            temp = temp.next;
        }
        //当退出循环时,temp就指向了链表的最后
        temp.next = gfNode;
    }

    //修改节点信息,根据no编号来修改,跟数据库的修改操作是一个意思
    public void update(girlfriendsNode newgirlfriendsNode) {
    
    
        //判空
        if (head.next == null) {
    
    
            System.out.println("链表为空");
            return;
        }
        //定义辅助节点,找到需要修改的节点,根据no编号
        girlfriendsNode temp = head;
        Boolean flag = false;//表示是否找到该节点,没找到就不能修改
        while (true) {
    
    
            if (temp == null) {
    
    
                break;//说明此时指针在链表最后
            }
            if (temp.no == newgirlfriendsNode.no) {
    
    
                //找到节点
                flag = true;
                break;
            }
            temp = temp.next;
        }
        //根据flag,判断是否找到要修改的节点
        if (flag) {
    
    
            temp.name = newgirlfriendsNode.name;
            temp.nickname = newgirlfriendsNode.nickname;
        } else {
    
    //没找到节点
            System.out.printf("没有找到编号%d的节点", newgirlfriendsNode.no);
        }
    }
    //删除节点

    /**
     * 思路
     * 1、head头节点不能动,因此我们需要一个temp辅助节点找到待删除的前一个节点
     * 2、说明我们在比较时,是temp.next.no和需要删除的节点的no比较
     */
    public void delete(int no) {
    
    
        girlfriendsNode temp = head;
        //是否找到节点
        boolean flag = false;
        //判空
        while (true) {
    
    
            if (temp.next == null) {
    
    //已经找到链表最后
                break;
            }
            if (temp.no == no) {
    
    
                //找到的待删除节点的前一个节点temp
                flag = true;
                break;
            }
            temp = temp.next;//后移
        }
        //判断flag
        if (flag) {
    
    //找到
            //删除
            temp.next = temp.next.next;//相当于下一个节点下标赋给前一个节点下标
        } else {
    
    
            System.out.printf("无法删除%d号节点",no);
        }
    }

    //显示链表
    public void list() {
    
    
        //判断链表是否为空
        if (head.next == null) {
    
    
            System.out.println("链表为空");
            return;
        }
        //因为头节点不能动,需要用上面的辅助节点来遍历
        girlfriendsNode temp = head.next;
        while (true) {
    
    
            //判断是否到了链表的最后
            if (temp == null) {
    
    
                break;
            }
            //输出节点信息
            System.out.println(temp);
            //将节点后移
            temp = temp.next;
        }
    }
}

//定义girlfriendsNode节点,每一个girlfriendsNode 对象被称为一个节点
class girlfriendsNode {
    
    
    public int no;//备胎编号
    public String name;//备胎名字
    public String nickname;//备胎昵称
    public girlfriendsNode next;//指向下一个节点

    //构造器
    public girlfriendsNode(int no, String name, String nickname) {
    
    
        this.no = no;
        this.name = name;
        this.nickname = nickname;
    }

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

双向链表

双向链表定义

双向链表也叫双链表,它的每个数据节点中都有两个指针这里与单向链表是不同的,分别指向直接后继和直接前驱。(形成一个完整闭环)所以,从双向链表中的任意一个节点开始,都可以很方便地访问它的前节点和后节点

双向链表逻辑结构
在这里插入图片描述

双向链表应用

1、增

   public void add(girlfriendsNode1 gfNode) {
    
    
        //因为头节点(head)不能动,因此我们需要一个辅助
        girlfriendsNode1 temp = head;
        //遍历链表,找到最后
        while (true) {
    
    
            //找到链表的最后
            if (temp.next == null) {
    
    
                break;
            }
            //如果没有找到最后,将temp后移
            temp = temp.next;
        }
        //当退出循环时,temp就指向了链表的最后
        temp.next=gfNode;
        gfNode.piror=temp;

    }

2、删

    public void delete(int no) {
    
    

        //判断当前链表是否为空
        if(head.next==null){
    
    //空链表
            System.out.println("空链表,不能删除");
            return;
        }
        girlfriendsNode1 temp = head.next;
        //是否找到节点
        boolean flag = false;
        //判空
        while (true) {
    
    
            if (temp == null) {
    
    //已经找到链表最后
                break;
            }
            if (temp.no == no) {
    
    
                //找到的待删除节点的前一个节点temp
                flag = true;
                break;
            }
            temp = temp.next;//后移
        }
        //判断flag
        if (flag) {
    
    //找到
            //删除
           //temp.next = temp.next.next;//单向链表的删除方式
            temp.piror.next=temp.next;
            //如果最后一个节点不为空
            if(temp.next!=null){
    
    
                temp.next.piror=temp.piror;
            }
        } else {
    
    
            System.out.printf("无法删除%d号节点",no);
        }
    }

3、改

public void update(girlfriendsNode1 newgirlfriendsNode) {
    
    
        //判空
        if (head.next == null) {
    
    
            System.out.println("链表为空");
            return;
        }
        //定义辅助节点,找到需要修改的节点,根据no编号
        girlfriendsNode1 temp = head;
        Boolean flag = false;//表示是否找到该节点,没找到就不能修改
        while (true) {
    
    
            if (temp == null) {
    
    
                break;//说明此时指针在链表最后
            }
            if (temp.no == newgirlfriendsNode.no) {
    
    
                //找到节点
                flag = true;
                break;
            }
            temp = temp.next;
        }
        //根据flag,判断是否找到要修改的节点
        if (flag) {
    
    
            temp.name = newgirlfriendsNode.name;
            temp.nickname = newgirlfriendsNode.nickname;
        } else {
    
    //没找到节点
            System.out.printf("没有找到编号%d的节点", newgirlfriendsNode.no);
        }
    }

4、查

public void list() {
    
    
        //判断链表是否为空
        if (head.next == null) {
    
    
            System.out.println("链表为空");
            return;
        }
        //因为头节点不能动,需要用上面的辅助节点来遍历
        girlfriendsNode1 temp = head.next;
        while (true) {
    
    
            //判断是否到了链表的最后
            if (temp == null) {
    
    
                break;
            }
            //输出节点信息
            System.out.println(temp);
            //将节点后移
            temp = temp.next;
        }
    }

完整代码

package linkedlist;

/**
 * 双链表
 * @author shkstart
 * @create 2021-07-28 13:03
 */
public class DoubleLinkedListDemo {
    
    
    public static void main(String[] args) {
    
    
        //创建节点
        girlfriendsNode1 gf1 = new girlfriendsNode1(1, "莺莺", "肤白");
        girlfriendsNode1 gf2 = new girlfriendsNode1(2, "燕燕", "貌美");
        girlfriendsNode1 gf3 = new girlfriendsNode1(3, "红红", "大长腿");
        girlfriendsNode1 gf4 = new girlfriendsNode1(4, "绿绿", "傻白甜");

        //创建一个双向链表对象
        DoubleLinkedList doubleLinkedList = new DoubleLinkedList();
        doubleLinkedList.add(gf1);
        doubleLinkedList.add(gf2);
        doubleLinkedList.add(gf3);
        doubleLinkedList.add(gf4);
        System.out.println("双向链表");
        doubleLinkedList.list();


        //修改
        System.out.println("修改节点后的双向链表");
        girlfriendsNode1 newgf1 = new girlfriendsNode1(3, "小不点", "长发飘飘");
        doubleLinkedList.update(newgf1);
        doubleLinkedList.list();

        //删除节点
        System.out.println("删除一个指定节点后");
        doubleLinkedList.delete(1);
        doubleLinkedList.list();
    }
}
//创建一个双链表类
class DoubleLinkedList{
    
    
    //先初始化一个头节点,头节点不动,不存放数据
    private girlfriendsNode1 head=new girlfriendsNode1(0,"","");

    //返回头节点
    public girlfriendsNode1 getHead(){
    
    
        return head;
    }

    //查看双链表(遍历)
    public void list() {
    
    
        //判断链表是否为空
        if (head.next == null) {
    
    
            System.out.println("链表为空");
            return;
        }
        //因为头节点不能动,需要用上面的辅助节点来遍历
        girlfriendsNode1 temp = head.next;
        while (true) {
    
    
            //判断是否到了链表的最后
            if (temp == null) {
    
    
                break;
            }
            //输出节点信息
            System.out.println(temp);
            //将节点后移
            temp = temp.next;
        }
    }

    //添加节点到双向链表最后
    public void add(girlfriendsNode1 gfNode) {
    
    
        //因为头节点(head)不能动,因此我们需要一个辅助
        girlfriendsNode1 temp = head;
        //遍历链表,找到最后
        while (true) {
    
    
            //找到链表的最后
            if (temp.next == null) {
    
    
                break;
            }
            //如果没有找到最后,将temp后移
            temp = temp.next;
        }
        //当退出循环时,temp就指向了链表的最后
        temp.next=gfNode;
        gfNode.piror=temp;

    }


    //修改一个节点的内容
    public void update(girlfriendsNode1 newgirlfriendsNode) {
    
    
        //判空
        if (head.next == null) {
    
    
            System.out.println("链表为空");
            return;
        }
        //定义辅助节点,找到需要修改的节点,根据no编号
        girlfriendsNode1 temp = head;
        Boolean flag = false;//表示是否找到该节点,没找到就不能修改
        while (true) {
    
    
            if (temp == null) {
    
    
                break;//说明此时指针在链表最后
            }
            if (temp.no == newgirlfriendsNode.no) {
    
    
                //找到节点
                flag = true;
                break;
            }
            temp = temp.next;
        }
        //根据flag,判断是否找到要修改的节点
        if (flag) {
    
    
            temp.name = newgirlfriendsNode.name;
            temp.nickname = newgirlfriendsNode.nickname;
        } else {
    
    //没找到节点
            System.out.printf("没有找到编号%d的节点", newgirlfriendsNode.no);
        }
    }


    //从双链表中删除一个节点
    //直接找到要删除的节点
    //找到之后直接删除
    public void delete(int no) {
    
    

        //判断当前链表是否为空
        if(head.next==null){
    
    //空链表
            System.out.println("空链表,不能删除");
            return;
        }
        girlfriendsNode1 temp = head.next;
        //是否找到节点
        boolean flag = false;
        //判空
        while (true) {
    
    
            if (temp == null) {
    
    //已经找到链表最后
                break;
            }
            if (temp.no == no) {
    
    
                //找到的待删除节点的前一个节点temp
                flag = true;
                break;
            }
            temp = temp.next;//后移
        }
        //判断flag
        if (flag) {
    
    //找到
            //删除
           //temp.next = temp.next.next;//单向链表的删除方式
            temp.piror.next=temp.next;
            //如果最后一个节点不为空
            if(temp.next!=null){
    
    
                temp.next.piror=temp.piror;
            }
        } else {
    
    
            System.out.printf("无法删除%d号节点",no);
        }
    }
}

//定义girlfriendsNode1,每个girlfriendsNode1对象就是一个节点
class girlfriendsNode1 {
    
    
    public int no;//备胎编号
    public String name;//备胎名字
    public String nickname;//备胎昵称
    public girlfriendsNode1 next;//指向下一个节点
    public girlfriendsNode1 piror;//指向前一个节点

    //构造器
    public girlfriendsNode1(int no, String name, String nickname) {
    
    
        this.no = no;
        this.name = name;
        this.nickname = nickname;
    }
    //重写tostring
    @Override
    public String toString() {
    
    
        return "girlfriendsNode1{" +
                "no=" + no +
                ", name='" + name + '\'' +
                ", nickname='" + nickname + '\'' +
                '}';
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_46457946/article/details/119152302