Dsa Using Java 简明教程

DSA using Java - Doubly Linked List

Doubly Linked List Basics

双向链表是链表的一种变体,与单向链表相比,它可以在两个方向(向前或向后)轻松地导航。以下是理解双向链表概念的重要术语

  1. Link − 链表的每个链接可以存储一个称为元素的数据。

  2. Next − 链表的每个链接都包含到下一个链接的链接,称为 Next。

  3. Prev − 链表的每个链接都包含到前一个链接的链接,称为 Prev。

  4. LinkedList − 一个 LinkedList 包含指向第一个称为 First 的链接的链接链接和指向最后一个链接(称为 Last)的链接链接。

Doubly Linked List Representation

dsa doublylinkedlist

根据以上所示的说明,以下是要考虑的重要要点。

  1. 双重 LinkedList 包含一个称为 First 和 Last 的链元素。

  2. 每个链接都包含一个数据字段(多个字段)和一个称为 Next 的链接字段。

  3. 每个链接使用其 Next 链接与其下一个链接链接。

  4. 每个链接使用其 Prev 链接与其上一个链接链接。

  5. 最后一个链接包含一个空链接来标记链表的结尾。

Basic Operations

以下是由链表支持的基本操作。

  1. Insertion − 在链表的开头添加元素。

  2. Deletion − 删除链表开头的元素。

  3. Insert Last − 在链表的末尾添加元素。

  4. Delete Last − 从链表的末尾删除元素。

  5. Insert After − 在链表项后添加元素。

  6. Delete − 使用键从链表删除元素。

  7. Display forward − 以正向方式显示完整链表。

.

  1. Display backward − 以反向方式显示完整链表。

Insertion Operation

以下代码演示在双向链表的开头执行插入操作。

//insert link at the first location
public void insertFirst(int key, int data){
   //create a link
   Link link = new Link(key,data);

   if(isEmpty()){
      //make it the last link
      last = link;
   }else {
      //update first prev link
      first.prev = link;
   }

   //point it to old first link
   link.next = first;
   //point first to new first link
   first = link;
}

Deletion Operation

以下代码演示在双向链表的开头执行删除操作。

//delete link at the first location
public Link deleteFirst(){
   //save reference to first link
   Link tempLink = first;
   //if only one link
   if(first.next == null){
      last = null;
   }else {
      first.next.prev = null;
   }
   first = first.next;
   //return the deleted link
   return tempLink;
}

Insertion at End Operation

以下代码演示在双向链表的末尾执行插入操作。

//insert link at the last location
public void insertLast(int key, int data){
   //create a link
   Link link = new Link(key,data);

   if(isEmpty()){
      //make it the last link
      last = link;
   }else {
      //make link a new last link
      last.next = link;
      //mark old last node as prev of new link
      link.prev = last;
   }

   //point last to new last node
   last = link;
}

Demo

Link.java

package com.tutorialspoint.list;

public class Link {
   public int key;
   public int data;
   public Link next;
   public Link prev;

   public Link(int key, int data){
      this.key = key;
      this.data = data;
   }

   public void display(){
      System.out.print("{"+key+","+data+"}");
   }
}

DoublyLinkedList.java

package com.tutorialspoint.list;

public class DoublyLinkedList {

   //this link always point to first Link
   private Link first;
   //this link always point to last Link
   private Link last;

   // create an empty linked list
   public DoublyLinkedList(){
      first = null;
      last = null;
   }

   //is list empty
   public boolean isEmpty(){
      return first == null;
   }

   //insert link at the first location
   public void insertFirst(int key, int data){
      //create a link
      Link link = new Link(key,data);

      if(isEmpty()){
         //make it the last link
         last = link;
      }else {
         //update first prev link
         first.prev = link;
      }

      //point it to old first link
      link.next = first;
      //point first to new first link
      first = link;
   }

   //insert link at the last location
   public void insertLast(int key, int data){
      //create a link
      Link link = new Link(key,data);

      if(isEmpty()){
         //make it the last link
         last = link;
      }else {
         //make link a new last link
         last.next = link;
         //mark old last node as prev of new link
         link.prev = last;
      }

      //point last to new last node
      last = link;
   }

   //delete link at the first location
   public Link deleteFirst(){
      //save reference to first link
      Link tempLink = first;
      //if only one link
      if(first.next == null){
         last = null;
      }else {
         first.next.prev = null;
      }
      first = first.next;
      //return the deleted link
      return tempLink;
   }

   //delete link at the last location
   public Link deleteLast(){
      //save reference to last link
      Link tempLink = last;
      //if only one link
      if(first.next == null){
         first = null;
      }else {
         last.prev.next = null;
      }
      last = last.prev;
      //return the deleted link
      return tempLink;
   }

   //display the list in from first to last
   public void displayForward(){
      //start from the beginning
      Link current = first;
      //navigate till the end of the list
      System.out.print("[ ");
      while(current != null){
         //print data
         current.display();
         //move to next item
         current = current.next;
         System.out.print(" ");
      }
      System.out.print(" ]");
   }

   //display the list from last to first
   public void displayBackward(){
      //start from the last
      Link current = last;
      //navigate till the start of the list
      System.out.print("[ ");
      while(current != null){
         //print data
         current.display();
         //move to next item
         current = current.prev;
         System.out.print(" ");
      }
      System.out.print(" ]");
   }

   //delete a link with given key
   public Link delete(int key){
      //start from the first link
      Link current = first;
      //if list is empty
      if(first == null){
         return null;
      }

      //navigate through list
      while(current.key != key){
      //if it is last node
      if(current.next == null){
            return null;
         }else{
            //move to next link
            current = current.next;
         }
      }

      //found a match, update the link
      if(current == first) {
         //change first to point to next link
            first = current.next;
         }else {
            //bypass the current link
            current.prev.next = current.next;
         }

         if(current == last){
            //change last to point to prev link
            last = current.prev;
         }else {
            current.next.prev = current.prev;
         }
         return current;
      }

   public boolean insertAfter(int key, int newKey, int data){
      //start from the first link
      Link current = first;
      //if list is empty
      if(first == null){
         return false;
      }

      //navigate through list
      while(current.key != key){
         //if it is last node
         if(current.next == null){
            return false;
         }else{
            //move to next link
            current = current.next;
         }
      }

      Link newLink = new Link(newKey,data);
      if(current==last) {
         newLink.next = null;
         last = newLink;
      }
      else {
         newLink.next = current.next;
         current.next.prev = newLink;
      }
      newLink.prev = current;
      current.next = newLink;
      return true;
   }
}

DoublyLinkedListDemo.java

package com.tutorialspoint.list;

public class DoublyLinkedListDemo {
    public static void main(String args[]){
        DoublyLinkedList list = new DoublyLinkedList();

        list.insertFirst(1, 10);
        list.insertFirst(2, 20);
        list.insertFirst(3, 30);

        list.insertLast(4, 1);
        list.insertLast(5, 40);
        list.insertLast(6, 56);

        System.out.print("\nList (First to Last): ");
        list.displayForward();
        System.out.println("");
        System.out.print("\nList (Last to first): ");
        list.displayBackward();

        System.out.print("\nList , after deleting first record: ");
        list.deleteFirst();
        list.displayForward();

        System.out.print("\nList , after deleting last record: ");
        list.deleteLast();
        list.displayForward();

        System.out.print("\nList , insert after key(4) : ");
        list.insertAfter(4,7, 13);
        list.displayForward();

        System.out.print("\nList  , after delete key(4) : ");
        list.delete(4);
        list.displayForward();

    }
}

如果我们编译并运行上述程序,它将生成以下结果 -

List (First to Last): [ {3,30} {2,20} {1,10} {4,1} {5,40} {6,56}  ]

List (Last to first): [ {6,56} {5,40} {4,1} {1,10} {2,20} {3,30}  ]
List (First to Last) after deleting first record: [ {2,20} {1,10} {4,1} {5,40} {6,56}  ]
List  (First to Last) after deleting last record: [ {2,20} {1,10} {4,1} {5,40}  ]
List  (First to Last) insert after key(4) : [ {2,20} {1,10} {4,1} {7,13} {5,40}  ]
List  (First to Last) after delete key(4) : [ {2,20} {1,10} {7,13} {5,40}  ]