java 双向链表的示例

  一、简介

  双向链表在查询数据时有一个优势,就是在查询数据时并不像单向链表那样要从头到尾的查,而是可以在链表的某一中间的某一个数据向前或向后查询其它数据,使查询时间进一步缩短了那么一点点。

  二、双向链表的示例代码如下:

/**
  * 包名:linkedlist
  *  文件名:DoubleLinkedListDemo.java
  *  
  * 功能:双链表数据结构的增删改查
  *
  * 作者:冰雪青松
  * 邮箱:946585434@qq.com
  * 日期:2022.10.13
  *
  **/
package linkedlist;

import java.util.*;

/**
  *  一、主类,即入口类,
  *
  * 说明:是对双向链表数据结构的操作,是次要的类
  *
  **/
public class DoubleLinkedListDemo {
    public static void main(String[] args) {
      
        DoubleLinkedList doubleLinkedList = new DoubleLinkedList();
      
 //########## [ 对双向链表的增删改查的操作  ]######################
 //------------------------------------------------------------------------------------------------------------------------------
 // 1.遍历二维数组添加数据进双向链表 begin
 
      //建立数据的二维数组
        String[][] nameArr = {
            {"宋江", "卢俊义", "吴用", "林冲", "公孙胜", "关胜", "秦明", "公孙胜", "呼延灼", "花荣"}, 
            {"及时雨", "玉麒麟", "智多星", "豹子头", "入云龙", "大刀", "霹雳火", "入云龙", "双鞭", "小李广"}
        };
       
        //编号,排序依据此偏号,可修改编号查看排序情况
        int[] noArr = {1, 9, 2, 5, 8, 10, 4, 3, 7, 6};
       
        //true 不排序;false 排序
        boolean tag = false;
       
        //遍历二维数组添加节点进链表
        if(tag){
            //按输入顺序进链表
            for(int i = 0; i < nameArr[0].length; i++){
                doubleLinkedList.add(new DHeroNode(noArr[i] , nameArr[0][i], nameArr[1][i]));
             }
        }else{
             //按排序进链表
            for(int i = 0; i < nameArr[0].length; i++){
                doubleLinkedList.addByOrder(new DHeroNode(noArr[i], nameArr[0][i], nameArr[1][i]));
            }
        }
      
        System.out.println("--------------------------------------");
        System.out.println("一、双向链表添加数据:\n");
      
        //遍历显示
        doubleLinkedList.list();
      
        System.out.println("--------------------------------------");
            
 // 1.遍历二维数组添加数据进双向链表  end.
 //------------------------------------------------------------------------------------------------------------------------------
 // 2.修改双向链表  begin
      
        int upNo1 = 2;
        String upName1 = "孙悟空";
        String upNick1    = "齐天大圣";
      
        int upNo2 = 6;
        String upName2 = "猪八戒";
        String upNick2    = "花心大萝卜";
      
        System.out.printf("\n二、准备修改的内容:\n\n编号:%d,姓名:%s,绰号:%s", upNo1, upName1, upNick1);
        System.out.printf("\n编号:%d,姓名:%s,绰号:%s", upNo2, upName2, upNick2);
        System.out.println("\n\n修改后的数据:\n");
        doubleLinkedList.update(new DHeroNode(upNo1, upName1, upNick1));
        doubleLinkedList.update(new DHeroNode(upNo2, upName2, upNick2));
      
        //遍历显示
        doubleLinkedList.list();
      
        System.out.println("--------------------------------------");
      
 // 2.修改双向链表  end.
 //------------------------------------------------------------------------------------------------------------------------------
 // 3.删除双向链表的节点  begin
 
        int n1 = 2;
        int n2 = 6;
      
        System.out.printf("三、要删除的编号为:%d 和 %d\n\n", n1, n2);
        doubleLinkedList.delete(n1);
        doubleLinkedList.delete(n2);
      
        System.out.println("删除后的数据:\n");
        
        //遍历显示
        doubleLinkedList.list();
        System.out.println("--------------------------------------");
      
 // 3.删除双向链表的节点  end.
 //------------------------------------------------------------------------------------------------------------------------------
 // 4.添加双向链表的节点  begin
      
        String[][] addArr = {
            {"鲁智深", "武松"}, 
            {"花和尚", "行者"}
         };

        System.out.printf("\n四、要添加的数据为:\n\n编号:%d ,姓名:%s,绰号:%s\n", n1, addArr[0][0], addArr[1][0]);
        System.out.printf("编号:%d ,姓名:%s,绰号:%s\n\n", n2, addArr[0][1], addArr[1][1]);
        System.out.println("添加后的数据:\n");
        doubleLinkedList.addByOrder(new DHeroNode(n1, addArr[0][0], addArr[1][0]));
        doubleLinkedList.addByOrder(new DHeroNode(n2, addArr[0][1], addArr[1][1]));
      
        //遍历显示
        doubleLinkedList.list();
        System.out.println("--------------------------------------");
      
 // 4.添加双向链表的节点  end.
 //------------------------------------------------------------------------------------------------------------------------------
 // 5.查询双向链表的一个节点  begin
     
        int qn = 9;  //要查询的位置
     
        System.out.printf("五、要查询的编号为:%d\n\n", qn);
        String[] strArr = doubleLinkedList.query(qn);
     
        if(strArr[0] == "" && strArr[1] == ""){
            System.out.println("error!");
        }else{
            System.out.printf("编号:%d,姓名:%s,绰号:%s\n\n", qn, strArr[0], strArr[1]);
        }
        
        System.out.println("--------------------------------------");

 // 5.查询双向链表的一个节点  end.
 //------------------------------------------------------------------------------------------------------------------------------
 // 6.查询双向链表的一个节点的上一节点的数据,检验双链表是否成功  begin
 
        int qn1 = 8;  //要查询的位置
        
        System.out.printf("六、查询的编号为 %d 的前一数据,\n\t\t\t\t检验双向链表是否成功!\n\n", qn1);
        String[] strArr1 = doubleLinkedList.queryPrev(qn1);
     
        if(strArr1[0] == "" && strArr1[1] == ""){
            System.out.println("error!");
        }else{
            System.out.printf("编号:%d,姓名:%s,绰号:%s\n\n", qn1, strArr1[0], strArr1[1]);
        }
      
 // 6.查询双向链表的一个节点的上一节点的数据,检验双链表是否成功  end.
  //------------------------------------------------------------------------------------------------------------------------------
 //##########################################################
    }
}

/**
  * 二、链表管理类
  *
  *  说明:对双向链表数据结构的算法类,重要的操作类!
  *
  */
class DoubleLinkedList{
    
    //申请一个空白的头节点
    private DHeroNode head = new DHeroNode(0, "", "");
    
    /**
      * 功能:按输入顺序添加
      *
      *  说明:按输入顺序添加数据进双向链表
      *
      * @param DHeroNode heroNode  要添加的数据节点
      * @return void
      **/
    public void add(DHeroNode heroNode){
         DHeroNode temp = head;
         boolean flag = false;
        
         while(true){
              if(temp.next == null) break;
              if(temp.next.no == heroNode.no) flag = true;
              temp = temp.next;
          }
          
          if(flag){
              System.out.printf("编号为%d的数据己经存在!\n", heroNode.no);
              return;
          }else{
              temp.next = heroNode;
              heroNode.prev = temp;
          }
    }
    
    /**
      * 功能:按排序顺序添加
      *
      *  说明:按排序顺序添加数据进双向链表
      *
      * @param DHeroNode heroNode  要添加的数据节点
      * @return void
      **/
    public void addByOrder(DHeroNode heroNode){
         DHeroNode temp = head;
         boolean flag = false;
        
         while(true){
             if(temp.next == null)
                  break;
             else if(temp.next.no > heroNode.no)
                  break;
             else if(temp.next.no == heroNode.no)
                  flag = true;
                
             temp = temp.next;
        }
        
        if(flag){
            System.out.printf("编号为%d的数据已经存在!\n", heroNode.no);
            return;
        }else{
            heroNode.next = temp.next;
            temp.next = heroNode;
            heroNode.prev = temp;
            
            if(heroNode.next != null)
                heroNode.next.prev = heroNode;
        }
    }
        
    /**
      * 功能:修改双向链表的数据
      *
      * @param DHeroNode heroNode  要修改的数据节点
      * @return boolean     返回 true 成功或 false 失败的信息
      **/
    public boolean update(DHeroNode newNode){
          
          if(head.next == null){
              System.out.println("双向链表为空!");
              return false;
          }
          
          DHeroNode temp = head;
          boolean flag = false;
          
          while(true){
              
              if(temp.next == null)
                  break;
              else if(temp.next.no == newNode.no){
                  flag = true;
                  
                  break;
              }
              
              temp = temp.next;
          }
          
          if(flag){
              temp.next.name = newNode.name;
              temp.next.nickname = newNode.nickname;
          }else{
              System.out.printf("没有找到编号为%d的数据!\n", newNode.no);
          }
          
          return true;
    }
    
    /**
      * 功能:删除双向链表的一个节点
      *
      * @param int n   要删除的数据位置
      * @return boolean  返回 true 成功或 false 失败的信息
      **/
    public boolean delete(int n){
        DHeroNode temp = head;
        boolean flag = false;
        
        if(head.next == null){
            System.out.println("链表为空!");
            return false;
        }
        
        while(true){
            
            if(temp.next == null)
                break;
                
            if(temp.next.no == n){
                flag = true;
                break;
            }
            
            temp = temp.next;
        }
        
        if(flag){
            temp.next = temp.next.next;
            
            if(temp.next != null)
                temp.next.prev = temp;
                
            return true;
        }else{
            System.out.printf("编号为%d的数据不存在!", n);
        }
        
        return false;
    }

    /**
      * 功能:查询某一节点的数据
      *
      * @param int n   要查询的数据位置
      * @return String[]  返回  error 空数组或有数据数组的信息
      **/
    public String[] query(int n){
        String[] error = {"", ""};
            
        if(head.next == null){
            System.out.println("链表为空!");
            return error;
        }
        
        DHeroNode temp = head.next;
        boolean flag = false;
        
        while(true){
            
            if(temp.next == null) break;
            
            if(temp.next.no == n){
                flag = true;
                break;
            }
            
            temp = temp.next;
        }
        
        if(temp.next != null)
            temp = temp.next;
        
        if(flag){
            String[] tmp = {temp.name, temp.nickname};
                return tmp;
        }else{
            System.out.printf("编号为%d的数据不存在!", n);
            return error;
        }
    }
    
    /**
      * 功能:查询某一节点的后一数据
      *
      * 说明:检验双向链表是否成功
      *
      * @param int n   要查询的数据位置
      * @return String[]  返回  error 空数组或有数据数组的信息
      **/
    public String[] queryPrev(int n){
        String[] error = {"", ""};
            
        if(head.next == null){
            System.out.println("链表为空!");
            return error;
        }
        
        DHeroNode temp = head.next;
        boolean flag = false;
        
        while(true){
            
            if(temp.next == null) break;
            
            if(temp.next.no == n){
                flag = true;
                break;
            }
            
            temp = temp.next;
        }
        
        if(temp.next != null)
            temp = temp.next;
        
        if(flag){
            String[] tmp = {temp.prev.name, temp.prev.nickname};
                return tmp;
        }else{
            System.out.printf("编号为%d的数据不存在!", n);
            return error;
        }
    }
    
    /**
      * 功能:遍历显示数据
      *
      * @param none
      * @return void
      **/
    public void list(){
        if(head.next == null){
            System.out.println("链表为空!");
            return;
        }
        
        DHeroNode temp = head.next;
        
        while(true){
            if(temp == null) break;
            System.out.println(temp);
            temp = temp.next;
        }
    }
}

/**
  * 三、双向链表的数据结构节点
  *
  * 说明:是重要的数据类
  *
  **/
class DHeroNode{
    public int no;
    public String name;
    public String nickname;
    public DHeroNode prev;  //previous
    public DHeroNode next;
    
    public DHeroNode(int no, String name, String nickname){
        this.no = no;
        this.name = name;
        this.nickname = nickname;
    }
    
    @Override
    public String toString(){
        String str1 = "", str2 = "";
        
        //由于界面显示混乱,排版
        switch(name.length()){
            case 1: str1 = ",...绰号:" ;break;
            case 2: str1 = ",..绰号:" ;break;
            case 3: str1 = ",‍.绰号:" ;break;
            case 4: str1 = ",绰号:" ;break;
            default: str1 = ",绰号:" ;
        }
        
        //由于界面显示混乱,排版
        if(no < 10)
            str2 = ", 姓名:" ;
        else if(no >= 10 && no < 100)
            str2 = ",姓名:" ;
        else if(no >= 100)
            str2 = ",姓名:" ;
            
        return "编号:" + no + str2 + name + str1 + nickname;
    }
}

  三、程序执行后的效果:

  1.检验双向链表是否成功?

8df97c78b5164ad080c6e0443ef7a0bb.jpeg

  2.完整的效果

8e22ea07f3dd40cb80f0d8d992b50023.jpeg

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冰雪青松

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值