【数据结构_6】双向链表的实现

一、实现MyDLinkedList(双向链表)

java 复制代码
package LinkedList;

public class MyDLinkedList {

    //首先我们要创建节点(因为双向链表和单向链表的节点不一样!!)
    static class Node{
        public String val;
        public Node prev = null;
        public Node next = null;
        //给一个构造方法

        public Node(String val) {
            this.val = val;
        }
    }
    //表示整个链表,此处不引入傀儡节点,使用Null表示空的链表
    public Node head = null;
    //为了方便后续的尾插曹祖
    public Node tail = null;

    //给一个toStirng的打印


    @Override
    public String toString() {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("[");
        //进行链表的遍历
        for(Node cur = head;cur!= null ;cur = cur.next){

           stringBuilder.append(cur.val);
           if(cur.next != null) {
               stringBuilder.append(",");
           }
        }
        stringBuilder.append("]");
        return stringBuilder.toString();
    }

    //接下来来实现一些双向链表的核心操作
    //1.实现头插操作
    public void addFirst(String val){
        Node newNode = new Node(val);
        //首先判断链表是否为空的情况
        if(head == null){
            head = newNode;
            tail = newNode;
        }else {
        //再来看看一般情况
        newNode.next = head;
        head. prev = newNode;
        //2.让head指向新节点
        head = newNode;
    }
    }

    //2.实现链表的尾插操作
    public void addLast(String val){
        Node newNode = new Node(val);
        //1.首先判断链表为空的情况,可知与头插操作一样
        if(head == null){
            head = newNode;
            tail = newNode;
        }else {
            //2.考虑一般情况
            tail.next = newNode;
            newNode.prev = tail;
            tail = newNode;
        }
    }

    //实现链表长度的计算
    public int size(){
        int size =0;
        for(Node cur = head;cur != null;cur = cur.next){
            size++;
        }
        return size;
    }

    //3.实现双向链表的按位置插入
    public void add(int index,String val){
        int size = size();
        //1.首先判断index的值是否合法
        if( index < 0 || index > size ){
            throw  new IndexOutOfBoundsException("Index:"+index+",Size:"+size);
        }
        //2.判断特殊位置
        if(index ==0 ){
            //此时就是头插操作
            addFirst(val);
            return;
        }
        if(index== size){
            //此时就是尾插
            addLast(val);
            return;
        }
        //3.进行一般的插入
        //先找到要插入节点的前一个节点
        Node prev = head;
        for(int i =0;i<index-1;i++){
            prev = prev.next;
        }
        //此时我们已经找到了要插入节点的前一个节点
        Node newNode = new Node(val);
        Node next = prev.next;
        //首先建立新节点与上一个节点之间的关系
        prev.next = newNode;
        newNode.prev = prev;
        //再建立新节点与下一个节点之间的关系
        newNode.next = next;
        next.prev = newNode;
    }

    //4.实现包含查找操作
    public Boolean contains(String val){
        for (Node cur = head ; cur != null;cur = cur.next){
            if(cur.val.equals(val)) {
                return true;
            }
        }
        return false;
    }

    //5.查找元素,返回该元素的下标,如果没有找到,返回-1
    public int indexOf(String val){
        int index =0;
        for (Node cur = head;cur != null;cur =cur.next){
            if(cur.val.equals(val)){
                return  index;
            }
            index++;
        }
        return -1;
    }

    //6.头删
    public void removeFirst(){
     //1.首先考虑是否为空链表
     if(head == null){
         return;//空链表无法进行删除操作
     }
     //2.考虑只有一个节点的情况
     if(head.next == null){
         head = null;
         tail = null;
         return;
     }
     //3.考虑一般情况
        head = head.next;
     head.prev = null;
    }

    //7.尾部删除
    public void removeLast(){
        //1.考虑空链表
        if (head == null){
            return;
        }
        //2.考虑只有一个节点
        if(head.next == null){
            head = null;
            tail = null;
            return;
        }
        //3.考虑一般情况
        tail = tail.prev;
        tail.next = null;
    }

    //8.指定位置删除
    public void remove(int index){
        int size = size();
        //对index做判断
        if(index <0 || index >= size){
            throw  new IndexOutOfBoundsException("index:"+index+",size:"+size);
        }
        //2.如果是删除index=0
        if(index ==0){
            removeFirst();
            return;
        }
        if(index ==size-1){
            removeLast();
            return;
        }
        //3.考虑一般情况的删除
        //先找到前一个节点
        Node prev = head;
        for(int i =0;i<index-1;index++){
            prev = prev.next;
        }
        Node toRemove = prev.next;
        Node next = toRemove.next;
        //4.进行删除操作
        prev.next = next;
        next.prev =prev;

    }

    //9.指定值删除
    public void remove(String val){
        //1.首先考虑空的链表
        if(head == null){
            return ;
        }
        //2.判定头删/尾删操作
        if(val.equals(head.val)){
            removeFirst();
            return;
        }
        if(val.equals(tail.val)){
            removeLast();
            return;
        }
        //3.一般情况 先找到前一个节点
        Node toRemove = head;
        for (;toRemove!=null;toRemove= toRemove.next){
            if(toRemove.val.equals(val)){
                break;
            }
        }
        //循环之外有两种情况一种是找到了打破循环 另一种是循环走完了!
        if(toRemove == null){
            return ;
        }

        Node prev = toRemove.prev;
        Node next = toRemove.next;
        prev.next = next;
        next.prev = prev;

    }

    //10.链表的清空操作
    public void clear(){
        head = null;
        tail = null;
    }


    public static void test(){
        MyDLinkedList list = new MyDLinkedList();
        list.addFirst("a");
        list.addFirst("b");
        list.addFirst("c");
        System.out.println(list);
    }

    public static  void test1(){
        MyDLinkedList list = new MyDLinkedList();
        list.addLast("c");
        list.addLast("b");
        list.addLast("a");
        System.out.println(list);
    }

    public static void test3(){
        MyDLinkedList list = new MyDLinkedList();
        list.addFirst("a");
        list.addFirst("a");
        list.addFirst("a");
        list.addFirst("a");
        list.add(0,"b");
        list.add(2,"c");
        System.out.println(list);
    }

    public static void test4(){
        MyDLinkedList list = new MyDLinkedList();
        list.addFirst("a");
        list.addFirst("a");
        list.addFirst("a");
        list.addFirst("a");
        list.add(0,"b");
        list.add(2,"c");
        System.out.println(list);

        System.out.println(list.indexOf("a"));
        System.out.println(list.contains("b"));
        System.out.println(list.contains("d"));

    }
    public static void test5() {
        MyDLinkedList list = new MyDLinkedList();
        list.addFirst("a");
        list.addFirst("a");
        list.addFirst("a");
        list.addFirst("a");
        list.add(0, "b");
        list.add(2, "c");
        System.out.println(list);
        list.removeFirst();
        list.removeFirst();
        System.out.println(list);
    }

    public static void test6() {
        MyDLinkedList list = new MyDLinkedList();
        list.addFirst("a");
        list.addFirst("a");
        list.addFirst("a");
        list.addFirst("a");
        list.add(0, "b");
        list.add(2, "c");
        System.out.println(list);
        list.removeLast();
        list.removeLast();
        System.out.println(list);
    }
    public static void test7() {
        MyDLinkedList list = new MyDLinkedList();
        list.addFirst("a");
        list.addFirst("a");
        list.addFirst("a");
        list.addFirst("a");
        list.add(0, "b");
        list.add(2, "c");
        System.out.println(list);
        list.remove(1);
        list.remove(4);
        System.out.println(list);
    }

    public static void test8() {
        MyDLinkedList list = new MyDLinkedList();
        list.addLast("a");
        list.addLast("b");
        list.addLast("c");
        System.out.println(list);
        list.remove("a");
        System.out.println(list);
    }
    public static void main(String[] args) {
      //  test();
       // test1();
        //test3();
       // test4();
        //test5();
        //test6();
        //test7();
        //test8();
    }
}
相关推荐
MZ_ZXD0014 分钟前
springboot旅游信息管理系统-计算机毕业设计源码21675
java·c++·vue.js·spring boot·python·django·php
PP东6 分钟前
Flowable学习(二)——Flowable概念学习
java·后端·学习·flowable
ManThink Technology12 分钟前
如何使用EBHelper 简化EdgeBus的代码编写?
java·前端·网络
invicinble16 分钟前
springboot的核心实现机制原理
java·spring boot·后端
人道领域24 分钟前
SSM框架从入门到入土(AOP面向切面编程)
java·开发语言
大模型玩家七七44 分钟前
梯度累积真的省显存吗?它换走的是什么成本
java·javascript·数据库·人工智能·深度学习
CodeToGym1 小时前
【Java 办公自动化】Apache POI 入门:手把手教你实现 Excel 导入与导出
java·apache·excel
凡人叶枫1 小时前
C++中智能指针详解(Linux实战版)| 彻底解决内存泄漏,新手也能吃透
java·linux·c语言·开发语言·c++·嵌入式开发
JMchen1232 小时前
Android后台服务与网络保活:WorkManager的实战应用
android·java·网络·kotlin·php·android-studio
阔皮大师2 小时前
INote轻量文本编辑器
java·javascript·python·c#