📜  使用双向链表实现Deque

📅  最后修改于: 2022-05-13 01:57:00.882000             🧑  作者: Mango

使用双向链表实现Deque

Deque或Double Ended Queue是Queue数据结构的通用版本,允许在两端插入和删除。在之前的文章中讨论了使用循环数组实现 Deque。现在在这篇文章中,我们将看到如何使用双向链表实现 Deque。

Deque 上的操作:

主要对 queue 进行以下四个基本操作:

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程。

insertFront() : Adds an item at the front of Deque.
insertRear()  : Adds an item at the rear of Deque.
deleteFront() : Deletes an item from front of Deque.
deleteRear()  : Deletes an item from rear of Deque.

除上述操作外,还支持以下操作:



getFront() : Gets the front item from queue.
getRear()  : Gets the last item from queue.
isEmpty()  : Checks whether Deque is empty or not.
size()     : Gets number of elements in Deque.
erase()    : Deletes all the elements from Deque.

Deque 的双向链表表示:
为了实现双端队列,我们需要跟踪两个指针, frontback 。我们在双端队列的后端或前端入队(推送)一个项目,并从后端和前端出队(弹出)一个项目。
在职的 :
声明Node 类型的前后两个指针,其中Node表示双向链表的节点结构。用值 NULL 初始化它们。
前端插入:

1. Allocate space for a newNode of doubly linked list.
2. IF newNode == NULL, then
3.     print "Overflow"
4. ELSE
5.     IF front == NULL, then
6.         rear = front = newNode
7.     ELSE
8.         newNode->next = front
9.       front->prev = newNode
10.        front = newNode 

后端插入:

1. Allocate space for a newNode of doubly linked list.
2. IF newNode == NULL, then
3.     print "Overflow"
4. ELSE
5.     IF rear == NULL, then
6.         front = rear = newNode
7.     ELSE
8.         newNode->prev = rear
9.       rear->next = newNode
10.        rear = newNode 

从前端删除:

1. IF front == NULL
2.     print "Underflow"
3. ELSE
4.     Initialize temp = front
5.     front = front->next
6.     IF front == NULL
7.         rear = NULL
8.     ELSE
9.         front->prev = NULL
10     Deallocate space for temp

从后端删除:

1. IF front == NULL
2.     print "Underflow"
3. ELSE
4.     Initialize temp = rear
5.     rear = rear->prev
6.     IF rear == NULL
7.         front = NULL
8.     ELSE
9.         rear->next = NULL
10     Deallocate space for temp

CPP
// C++ implementation of Deque using
// doubly linked list
#include 
 
using namespace std;
 
// Node of a doubly linked list
struct Node
{
    int data;
    Node *prev, *next;
    // Function to get a new node
    static Node* getnode(int data)
    {
        Node* newNode = (Node*)malloc(sizeof(Node));
        newNode->data = data;
        newNode->prev = newNode->next = NULL;
        return newNode;
    }
};
 
// A structure to represent a deque
class Deque
{
    Node* front;
    Node* rear;
    int Size;
 
public:
    Deque()
    {
        front = rear = NULL;
        Size = 0;
    }
 
    // Operations on Deque
    void insertFront(int data);
    void insertRear(int data);
    void deleteFront();
    void deleteRear();
    int getFront();
    int getRear();
    int size();
    bool isEmpty();
    void erase();
};
 
// Function to check whether deque
// is empty or not
bool Deque::isEmpty()
{
    return (front == NULL);
}
 
// Function to return the number of
// elements in the deque
int Deque::size()
{
    return Size;
}
 
// Function to insert an element
// at the front end
void Deque::insertFront(int data)
{
    Node* newNode = Node::getnode(data);
    // If true then new element cannot be added
    // and it is an 'Overflow' condition
    if (newNode == NULL)
        cout << "OverFlow\n";
    else
    {
        // If deque is empty
        if (front == NULL)
            rear = front = newNode;
 
        // Inserts node at the front end
        else
        {
            newNode->next = front;
            front->prev = newNode;
            front = newNode;
        }
 
        // Increments count of elements by 1
        Size++;
    }
}
 
// Function to insert an element
// at the rear end
void Deque::insertRear(int data)
{
    Node* newNode = Node::getnode(data);
    // If true then new element cannot be added
    // and it is an 'Overflow' condition
    if (newNode == NULL)
        cout << "OverFlow\n";
    else
    {
        // If deque is empty
        if (rear == NULL)
            front = rear = newNode;
 
        // Inserts node at the rear end
        else
        {
            newNode->prev = rear;
            rear->next = newNode;
            rear = newNode;
        }
 
        Size++;
    }
}
 
// Function to delete the element
// from the front end
void Deque::deleteFront()
{
    // If deque is empty then
    // 'Underflow' condition
    if (isEmpty())
        cout << "UnderFlow\n";
 
    // Deletes the node from the front end and makes
    // the adjustment in the links
    else
    {
        Node* temp = front;
        front = front->next;
 
        // If only one element was present
        if (front == NULL)
            rear = NULL;
        else
            front->prev = NULL;
        free(temp);
 
        // Decrements count of elements by 1
        Size--;
    }
}
 
// Function to delete the element
// from the rear end
void Deque::deleteRear()
{
    // If deque is empty then
    // 'Underflow' condition
    if (isEmpty())
        cout << "UnderFlow\n";
 
    // Deletes the node from the rear end and makes
    // the adjustment in the links
    else
    {
        Node* temp = rear;
        rear = rear->prev;
 
        // If only one element was present
        if (rear == NULL)
            front = NULL;
        else
            rear->next = NULL;
        free(temp);
 
        // Decrements count of elements by 1
        Size--;
    }
}
 
// Function to return the element
// at the front end
int Deque::getFront()
{
    // If deque is empty, then returns
    // garbage value
    if (isEmpty())
        return -1;
    return front->data;
}
 
// Function to return the element
// at the rear end
int Deque::getRear()
{
    // If deque is empty, then returns
    // garbage value
    if (isEmpty())
        return -1;
    return rear->data;
}
 
// Function to delete all the elements
// from Deque
void Deque::erase()
{
    rear = NULL;
    while (front != NULL)
    {
        Node* temp = front;
        front = front->next;
        free(temp);
    }
    Size = 0;
}
 
// Driver program to test above
int main()
{
    Deque dq;
    cout << "Insert element '5' at rear end\n";
    dq.insertRear(5);
 
    cout << "Insert element '10' at rear end\n";
    dq.insertRear(10);
 
    cout << "Rear end element: "
        << dq.getRear() << endl;
 
    dq.deleteRear();
    cout << "After deleting rear element new rear"
        << " is: " << dq.getRear() << endl;
 
    cout << "Inserting element '15' at front end \n";
    dq.insertFront(15);
 
    cout << "Front end element: "
        << dq.getFront() << endl;
 
    cout << "Number of elements in Deque: "
        << dq.size() << endl;
 
    dq.deleteFront();
    cout << "After deleting front element new "
        << "front is: " << dq.getFront() << endl;
 
    return 0;
}


Java
// Java implementation of Deque using
// doubly linked list
import java.util.*;
class GFG
{
 
  // Node of a doubly linked list
  static class Node
  {
    int data;
    Node prev, next;
 
    // Function to get a new node
    static Node getnode(int data)
    {
      Node newNode = new Node();
      newNode.data = data;
      newNode.prev = newNode.next = null;
      return newNode;
    }
  };
 
  // A structure to represent a deque
  static class Deque {
    Node front;
    Node rear;
    int Size;
 
    Deque()
    {
      front = rear = null;
      Size = 0;
    }
 
    // Function to check whether deque
    // is empty or not
    boolean isEmpty() { return (front == null); }
 
    // Function to return the number of
    // elements in the deque
    int size() { return Size; }
 
    // Function to insert an element
    // at the front end
    void insertFront(int data)
    {
      Node newNode = Node.getnode(data);
      // If true then new element cannot be added
      // and it is an 'Overflow' condition
      if (newNode == null)
        System.out.print("OverFlow\n");
      else {
        // If deque is empty
        if (front == null)
          rear = front = newNode;
 
        // Inserts node at the front end
        else {
          newNode.next = front;
          front.prev = newNode;
          front = newNode;
        }
 
        // Increments count of elements by 1
        Size++;
      }
    }
 
    // Function to insert an element
    // at the rear end
    void insertRear(int data)
    {
      Node newNode = Node.getnode(data);
      // If true then new element cannot be added
      // and it is an 'Overflow' condition
      if (newNode == null)
        System.out.print("OverFlow\n");
      else {
        // If deque is empty
        if (rear == null)
          front = rear = newNode;
 
        // Inserts node at the rear end
        else {
          newNode.prev = rear;
          rear.next = newNode;
          rear = newNode;
        }
 
        Size++;
      }
    }
 
    // Function to delete the element
    // from the front end
    void deleteFront()
    {
      // If deque is empty then
      // 'Underflow' condition
      if (isEmpty())
        System.out.print("UnderFlow\n");
 
      // Deletes the node from the front end and makes
      // the adjustment in the links
      else {
        Node temp = front;
        front = front.next;
 
        // If only one element was present
        if (front == null)
          rear = null;
        else
          front.prev = null;
 
        // Decrements count of elements by 1
        Size--;
      }
    }
 
    // Function to delete the element
    // from the rear end
    void deleteRear()
    {
      // If deque is empty then
      // 'Underflow' condition
      if (isEmpty())
        System.out.print("UnderFlow\n");
 
      // Deletes the node from the rear end and makes
      // the adjustment in the links
      else {
        Node temp = rear;
        rear = rear.prev;
 
        // If only one element was present
        if (rear == null)
          front = null;
        else
          rear.next = null;
 
        // Decrements count of elements by 1
        Size--;
      }
    }
 
    // Function to return the element
    // at the front end
    int getFront()
    {
      // If deque is empty, then returns
      // garbage value
      if (isEmpty())
        return -1;
      return front.data;
    }
 
    // Function to return the element
    // at the rear end
    int getRear()
    {
 
      // If deque is empty, then returns
      // garbage value
      if (isEmpty())
        return -1;
      return rear.data;
    }
 
    // Function to delete all the elements
    // from Deque
    void erase()
    {
      rear = null;
      while (front != null) {
        Node temp = front;
        front = front.next;
      }
      Size = 0;
    }
  }
 
  // Driver program to test above
  public static void main(String[] args)
  {
    Deque dq = new Deque();
    System.out.print(
      "Insert element '5' at rear end\n");
    dq.insertRear(5);
 
    System.out.print(
      "Insert element '10' at rear end\n");
    dq.insertRear(10);
    System.out.print("Rear end element: " + dq.getRear()
                     + "\n");
    dq.deleteRear();
    System.out.print(
      "After deleting rear element new rear"
      + " is: " + dq.getRear() + "\n");
    System.out.print(
      "Inserting element '15' at front end \n");
    dq.insertFront(15);
    System.out.print(
      "Front end element: " + dq.getFront() + "\n");
 
    System.out.print("Number of elements in Deque: "
                     + dq.size() + "\n");
    dq.deleteFront();
    System.out.print("After deleting front element new "
                     + "front is: " + dq.getFront()
                     + "\n");
  }
}
 
// This code is contributed by gauravrajput1


输出 :

Insert element '5' at rear end
Insert element '10' at rear end
Rear end element: 10
After deleting rear element new rear is: 5
Inserting element '15' at front end
Front end element: 15
Number of elements in Deque: 2
After deleting front element new front is: 5

时间复杂度:insertFront()、insertRear()、deleteFront()、deleteRear()等操作的时间复杂度为O(1)。 erase() 的时间复杂度是 O(n)。