【数据结构_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();
    }
}
相关推荐
摄殓永恒7 分钟前
【入门】对角线II
数据结构·c++·算法
俺不是西瓜太郎´•ﻌ•`14 分钟前
二维差分数组(JAVA)蓝桥杯
java·开发语言·蓝桥杯
cainiao08060519 分钟前
Java大数据可视化在城市空气质量监测与污染溯源中的应用:GIS与实时数据流的技术融合
java·开发语言·信息可视化
2685725921 分钟前
Java 23种设计模式 - 行为型模式11种
java·开发语言·设计模式
Coding小公仔21 分钟前
翻转数位题目解释和代码
数据结构·算法
编程点滴路40 分钟前
LinkedList源码解析
java·开发语言
花花鱼1 小时前
spring boot lunar 农历的三方库引用,获取日期的农历值
java·前端·spring boot
一切皆有迹可循1 小时前
Spring Boot 基于 Cookie 实现单点登录:原理、实践与优化详解
java·spring boot·后端
喂我花生(๑•̀ㅂ•́)و✧1 小时前
JAVA中ArrayList的解析
java·开发语言·算法
forestsea1 小时前
Java 基础面试题
java·开发语言