双向链表的相关操作

主要思想

		单链表的缺点是:只能顺序遍历,当查找或修改某个节点时,有时候效率会很低,
因此,双向链表的出现,解决了这个问题。

代码实现

1.节点类
package DoubleLinkList;

/**
 * @program: 3.链表的相关操作
 * @description: 定义节点,一个对象就是一个节点
 * @author: Zhou Jian
 * @create: 2020-07-09 19:56
 */
// 使用双向链表模拟一个案例:将水浒英雄的名字用双向链表链接起来
public class NodesDouble {
    // 成员变量
    public int id; // id
    public String name; // 姓名
    public String NickName; // 昵称
    public NodesDouble pre; // 指向前一个节点的指针
    public NodesDouble next; // 指向下一个节点的指针
    // 构造方法
    public NodesDouble(int id, String name, String nickName) {
        this.id = id;
        this.name = name;
        this.NickName = nickName;
    }
    // 为了显示方便,重写toString方法
    @Override
    public String toString() {
        return "Nodes[" +
                "id=" + id +
                ", name=" + name +
                ", NickName=" + NickName +
                ']';
    }
}
2.双向链表
package DoubleLinkList;

/**
 * @program: 3.链表的相关操作
 * @description: 用于管理双向链表节点
 * @author: Zhou Jian
 * @create: 2020-07-12 20:01
 */
public class NodesManage {
    // 先创建一个头结点,不存放数据
    private NodesDouble head = new NodesDouble(0," "," ");
    // 创建一个方法,用于向外暴露私有的head节点
    public NodesDouble getHead(){
        return head;
    }
    /**
     *  创建双向链表,这里考虑编号的顺序,实现在链表中插入新节点
     * @param nodesDouble 要添加的新节点
     */
    public void AddNodes(NodesDouble nodesDouble){
        // 头结点不能动,因此需要一个辅助的遍历指针
        // 这个指针指向待添加位置的前一个位置
        NodesDouble temp = head;
        boolean flag = false;// 标志位,用来检测要添加的节点是否已经存在,默认不存在
        while (true){
            // 找到了最后
            if(temp.next == null){
                break;
            }
            // 位置找到,在temp的后一个位置插入
            if(temp.next.id > nodesDouble.id){
                break;
            }else if(temp.next.id == nodesDouble.id){ // 新插入的节点在链表中已经存在
                flag = true;
                break;
            }
            // 如果都不符合,则继续往后找
            temp = temp.next;
        }
        // 判断
        if(flag){
            System.out.println("您要添加的节点已经存在,不能重复添加");
        }else{
            temp.next = nodesDouble;
            nodesDouble.pre = temp;
        }
    }

    /**
     * 根据id删除节点
     * @param id 要删除的节点的id
     */
    public void Del(int id){
        // 同理,需要一个辅助变量来遍历链表,和单链表不同,这里指向的是当前节点
        NodesDouble temp = head;
        // 标志位,用于检测是否找到了这个节点
        boolean flag = false;
        while (true){
            // 遍历完毕
            if(temp.next == null){
                System.out.println("链表为空,不能删除节点!");
            }
            // 找到了这个节点
            if(temp.id == id){
                flag = true;
                break;
            }
            // 继续往后找
            temp = temp.next;
        }
        // 判断
        if(flag){
            temp.pre.next = temp.next;
            // 判断删除的是否是最后一个节点
            if(temp.next != null){
                temp.next.pre = temp.pre;
            }
        }else{
            System.out.printf("您要删除的节点id:%d不存在", id);
        }
    }
    /**
     * 根据id来修改节点信息
     * @param modifyNode 要修改的节点
     */
    public void ModifyNodes(NodesDouble modifyNode){
        // 定义一个辅助指针,遍历要修改的节点
        NodesDouble temp = head;
        // 标志位,表示是否找到了该节点
        boolean flag = false;
        while (true){
            // 遍历完毕
            if(temp == null){
                break;
            }
            if(temp.id == modifyNode.id){
                flag = true;
                break;
            }
            // 继续往后找
            temp = temp.next;
        }
        // 判断
        if(flag){
            // 修改信息
            temp.name = modifyNode.name;
            temp.NickName = modifyNode.NickName;
        }else {
            System.out.println("找不到您要修改的节点");
        }
    }

    // 遍历双向链表
    public void list(){
        // 判空
        if(head.next == null){
            System.out.println("链表为空,不能遍历");
            return;
        }
        // 否则,使用一个临时变量来遍历整个链表元素
        NodesDouble temp = head;
        while (true){
            System.out.println(temp);
            // 指针后移
            if(temp.next == null){
                break;
            }
            temp = temp.next;
        }
        return;
    }
}
3.入口
package DoubleLinkList;

import SingleLinkList.ManageNodes;
import SingleLinkList.Nodes;

import java.util.Scanner;

/**
 * @program: 3.链表的相关操作
 * @description: 测试类
 * @author: Zhou Jian
 * @create: 2020-07-12 13:27
 */
public class Main {
    public static void main(String[] args) {
        Scanner s = new Scanner(System.in);

        // 创建几个水浒英雄对象
        NodesDouble n1 = new NodesDouble(1,"宋江","及时雨");
        NodesDouble n2 = new NodesDouble(2,"武松","行者");
        NodesDouble n3 = new NodesDouble(3,"李逵","黑旋风");
        NodesDouble n4 = new NodesDouble(4,"张顺","浪里白条");
        // 将创建的对象添加到链表中
        NodesManage obj = new NodesManage();
        System.out.println("修改之前的链表:");
        obj.AddNodes(n1);
        obj.AddNodes(n2);
        obj.AddNodes(n3);
        obj.AddNodes(n4);
        obj.list();

        // 测试修改节点信息
        System.out.println("请输入您要修改的节点的Id:");
        int Id = s.nextInt();
        System.out.println("请输入您要修改的Id为" + Id + "的姓名:");
        String names = s.next();
        System.out.println("请输入您要修改的Id为" + Id + "的昵称:");
        String nickNames = s.next();
        NodesDouble newNodes = new NodesDouble(Id,names,nickNames);
        obj.ModifyNodes(newNodes);
        System.out.println("修改之后:");
        obj.list();

        // 测试删除修节点信息
        System.out.print("请输入您要删除的节点的Id:");
        int IdDel = s.nextInt();
        obj.Del(IdDel);
        System.out.println("删除之后:");
        obj.list();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值