2021年も出航を続ける~~二重リンクリストの研究

01は、単一リンクリストを調査し、次の欠点を発見しました。

  1. 単一リンクリストの場合、検索方向は一方向のみですが、二重リンクリストは前方または後方に検索できます。
  2. 単一リンクリストはそれ自体では削除できず、補助ノードに依存する必要がありますが、二重リンクリストはそれ自体で削除できるため、単一リンクリストを削除すると、常にtempが見つかります。これはの前のノードです。削除するノード。

02二重リンクリスト

二重にリンクされたリストの構成:データドメイン、次のドメイン(次のノードを指す)、前のドメイン(前のノードを指す)
特定のコードは次のとおりです。

//定义DoubleLinkedList
class DoubleLinkedList {
    
    
    //定义头结点 位置保持不变
    private HeroNode2 head = new HeroNode2(0, "", "");

    //提供头节点的getter构造器
    public HeroNode2 getHead() {
    
    
        return head;
    }
    //增删改查的方法
 }

class HeroNode2 {
    
    
    public int no;
    public String name;
    public String nickname;
    //指向下一个节点
    public HeroNode2 next;
    //指向前一个节点
    public HeroNode2 pre;

    //初始化数据
    public HeroNode2(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 + '\'' +
                '}';
    }
}

03二重リンクリストへの追加、削除、変更

3.1トラバーサル

思考分析:

  • 二重リンクリストトラバーサルは、前方または後方に検索できることを除いて、単一リンクリストと同じです。

特定のコード:

    //显示链表[遍历]
    public void list() {
    
    
        //判断链表是否为空
        if (head.next == null) {
    
    
            System.out.println("链表为空");
            return;
        }
        //因为头节点不能动,需要一个辅助变量来遍历
        HeroNode2 temp = head.next;
        while (true) {
    
    
            //判断是否到链表最后
            if (temp == null) {
    
    
                break;
            }
            //输出节点信息
            System.out.println(temp);
            //循环完第一个节点后应该 指向下一个节点
            temp = temp.next;
        }
    }
3.2追加(デフォルトで二重リンクリストの最後に追加)

思考分析:

  • 最初に、二重にリンクされたリストの最後のノードを見つけます
  • temp.next = newHeroNode;
  • newHeroNode.pre = temp;

特定のコード:

 //添加节点
   public void add(HeroNode2 heroNode) {
    
    
       //定义辅助变量指向头节点
       HeroNode2 temp = head;
       //找到当前链表的最后节点 需要遍历
       while (true) {
    
    
           //判断是否存在下一个节点
           if (temp.next == null) {
    
    
               break;
           }
           //如果没有找到temp后移
           temp = temp.next;
       }
       //将最后这个节点的next 指向新节点
       //形成双向链表
       temp.next = heroNode;
       heroNode.pre = temp;
   }
3.3変更

思考分析:

  • 変更するデータの前のノードを見つけます
  • ノードの名前とニックネームのみを変更できます。ノードの番号は変更できません。ノードを追加するために変更する場合は、

特定のコード:

 public void update(HeroNode2 newHeroNode) {
    
    
        //判断是否为空
        if (head.next == null) {
    
    
            System.out.println("链表为空");
            return;
        }
        //辅助变量
        HeroNode2 temp = head.next;
        boolean flag = false;//标记是找到修改的节点
        //循环判断是否存在要修改的节点信息
        while (true) {
    
    
            if (temp == null) {
    
    
                break;
            }
            if (temp.no == newHeroNode.no) {
    
    
                flag = true;
                break;
            }
            //如果上述条件都不满足,则继续循环遍历查找要修改的节点
            temp = temp.next;
        }
        //判断标记是否为true
        if (flag) {
    
    
            temp.name = newHeroNode.name;
            temp.nickname = newHeroNode.nickname;
        } else {
    
    
            System.out.printf("要修改的节点%d号,不存在\n", newHeroNode.no);
        }
    }
3.4削除

思考分析:

  • 二重リンクリストなので、自分でノードを削除できます
  • tempなど、削除するノードを直接見つけますか
  • temp.pre.next = temp.next;
  • temp.next.pre = temp.pre;

特定のコード:

public void delete(int no) {
    
    
        //判断当前链表是否为空
        if (head.next == null) {
    
    //空链表
            System.out.println("链表为空,无法删除");
            return;
        }
        //辅助变量
        HeroNode2 temp = head.next;
        boolean flag = false;
        //循环遍历找出需要删除的节点位置
        while (true) {
    
    
            if (temp == null) {
    
    
                break;
            }
            if (temp.no == no) {
    
    
                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("要删除的节点%d号,不存在\n", no);
        }
    }

04二重リンクリストの追加、削除、変更をテストします

   HeroNode2 hero1 = new HeroNode2(1, "宋江", "及时雨");
        HeroNode2 hero2 = new HeroNode2(2, "卢俊义", "玉麒麟");
        HeroNode2 hero3 = new HeroNode2(3, "吴用", "智多星");
        HeroNode2 hero4 = new HeroNode2(4, "林冲", "豹子头");
        DoubleLinkedList doubleLinkedList = new DoubleLinkedList();
        System.out.println("添加后的的情况");
        doubleLinkedList.add(hero1);
        doubleLinkedList.add(hero2);
        doubleLinkedList.add(hero3);
        doubleLinkedList.add(hero4);
        doubleLinkedList.list();

        //修改链表
        HeroNode2 newHero = new HeroNode2(4, "公孙胜", "入云龙");
        doubleLinkedList.update(newHero);
        System.out.println("修改过后的情况");
        doubleLinkedList.list();

        //删除链表英雄
        doubleLinkedList.delete(3);
        System.out.println("删除过后的情况");
        doubleLinkedList.list();

結果:

添加後の状況
HeroNodeは{NO = 1、名前= '歌江'、ニックネーム= '適時レイン'}
HeroNode {NO = 2、名前は= '盧俊義'は、ニックネームは'玉=なかっ
麒麟'} 、HeroNode {NO = 3 name = 'Wu Yong'、nickname = 'Zhiduoxing'}
HeroNode(no = 4、name = 'Lin Chong'、nickname = 'Leopard Head')
変更された状況
HeroNode {no = 1、name = 'Song Jiang'、nickname = 'タイムリーな雨'}
HeroNode {no = 2、name = 'Lu Junyi'、nickname = 'Yu
Qilin '} HeroNode {no = 3、name = 'Wu Yong'、nickname = 'Zhiduoxing'}
HeroNode {no = 4、 name = 'Gongsun Victory'、nickname = 'Into the CloudDragon '}
削除後の状況
HeroNode {no = 1、name = 'Song Jiang'、nickname = 'Timely Rain'}
HeroNode {no = 2、name = 'Lu Junyi '、nickname =' Jade
Qilin '} HeroNode {no = 4、name =' Gongsun Sheng '、nickname =' Into the Cloud Dragon '}

おすすめ

転載: blog.csdn.net/lirui1212/article/details/113247030