使用双向链表实现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 的双向链表表示:
为了实现双端队列,我们需要跟踪两个指针, front和back 。我们在双端队列的后端或前端入队(推送)一个项目,并从后端和前端出队(弹出)一个项目。
在职的 :
声明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)。