📜  使用链表的优先队列

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

使用链表的优先队列

使用链表实现优先队列。

  • push():该函数用于向队列中插入新数据。
  • pop():该函数从队列中移除具有最高优先级的元素。
  • peek() / top():该函数用于获取队列中优先级最高的元素,而不将其从队列中移除。

优先队列可以使用数组、链表、堆和二叉树等常见数据结构来实现。

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

先决条件:
链表、优先队列



该列表的创建是为了使最高优先级的元素始终位于列表的开头。该列表根据元素的优先级按元素降序排列。这允许我们在 O(1) 时间内删除最高优先级的元素。要插入一个元素,我们必须遍历列表并找到合适的位置来插入节点,以便保持优先级队列的整体顺序。这使得 push() 操作需要 O(N) 时间。 pop() 和 peek() 操作在恒定时间内执行。

算法 :
推(头,数据,优先级)
第 1 步:使用 DATA 和 PRIORITY 创建新节点
第 2 步:检查 HEAD 是否具有较低的优先级。如果为真,请执行步骤 3-4 并结束。否则转到步骤 5。
第 3 步:新建 -> NEXT = HEAD
第 4 步:头 = 新
第 5 步:将 TEMP 设置为列表的头部
第 6 步:当 TEMP -> NEXT != NULL 和 TEMP -> NEXT -> PRIORITY > PRIORITY
第 7 步:TEMP = TEMP -> NEXT
[循环结束]
第 8 步:新建 -> 下一个 = 温度 -> 下一个
第 9 步:TEMP -> NEXT = NEW
第 10 步:结束
流行(头)
Step 2:将链表的头部设置为链表中的下一个节点。头 = 头 -> 下一个。
第三步:释放链表头部的节点
第 4 步:结束
窥视(头):
第 1 步:返回 HEAD -> DATA
第 2 步:结束

下面是算法的实现:

C++
// C++ code to implement Priority Queue
// using Linked List
#include 
using namespace std;
 
// Node
typedef struct node
{
    int data;
 
    // Lower values indicate
    // higher priority
    int priority;
 
    struct node* next;
 
} Node;
 
// Function to create a new node
Node* newNode(int d, int p)
{
    Node* temp = (Node*)malloc(sizeof(Node));
    temp->data = d;
    temp->priority = p;
    temp->next = NULL;
 
    return temp;
}
 
// Return the value at head
int peek(Node** head)
{
    return (*head)->data;
}
 
// Removes the element with the
// highest priority form the list
void pop(Node** head)
{
    Node* temp = *head;
    (*head) = (*head)->next;
    free(temp);
}
 
// Function to push according to priority
void push(Node** head, int d, int p)
{
    Node* start = (*head);
 
    // Create new Node
    Node* temp = newNode(d, p);
 
    // Special Case: The head of list has
    // lesser priority than new node. So
    // insert newnode before head node
    // and change head node.
    if ((*head)->priority > p)
    {
         
        // Insert New Node before head
        temp->next = *head;
        (*head) = temp;
    }
    else
    {
         
        // Traverse the list and find a
        // position to insert new node
        while (start->next != NULL &&
            start->next->priority < p)
        {
            start = start->next;
        }
 
        // Either at the ends of the list
        // or at required position
        temp->next = start->next;
        start->next = temp;
    }
}
 
// Function to check is list is empty
int isEmpty(Node** head)
{
    return (*head) == NULL;
}
 
// Driver code
int main()
{
     
    // Create a Priority Queue
    // 7->4->5->6
    Node* pq = newNode(4, 1);
    push(&pq, 5, 2);
    push(&pq, 6, 3);
    push(&pq, 7, 0);
 
    while (!isEmpty(&pq))
    {
        cout << " " << peek(&pq);
        pop(&pq);
    }
    return 0;
}
 
// This code is contributed by shivanisinghss2110


C
// C code to implement Priority Queue
// using Linked List
#include 
#include 
 
// Node
typedef struct node {
    int data;
 
    // Lower values indicate higher priority
    int priority;
 
    struct node* next;
 
} Node;
 
// Function to Create A New Node
Node* newNode(int d, int p)
{
    Node* temp = (Node*)malloc(sizeof(Node));
    temp->data = d;
    temp->priority = p;
    temp->next = NULL;
 
    return temp;
}
 
// Return the value at head
int peek(Node** head)
{
    return (*head)->data;
}
 
// Removes the element with the
// highest priority form the list
void pop(Node** head)
{
    Node* temp = *head;
    (*head) = (*head)->next;
    free(temp);
}
 
// Function to push according to priority
void push(Node** head, int d, int p)
{
    Node* start = (*head);
 
    // Create new Node
    Node* temp = newNode(d, p);
 
    // Special Case: The head of list has lesser
    // priority than new node. So insert new
    // node before head node and change head node.
    if ((*head)->priority > p) {
 
        // Insert New Node before head
        temp->next = *head;
        (*head) = temp;
    }
    else {
 
        // Traverse the list and find a
        // position to insert new node
        while (start->next != NULL &&
            start->next->priority < p) {
            start = start->next;
        }
 
        // Either at the ends of the list
        // or at required position
        temp->next = start->next;
        start->next = temp;
    }
}
 
// Function to check is list is empty
int isEmpty(Node** head)
{
    return (*head) == NULL;
}
 
// Driver code
int main()
{
    // Create a Priority Queue
    // 7->4->5->6
    Node* pq = newNode(4, 1);
    push(&pq, 5, 2);
    push(&pq, 6, 3);
    push(&pq, 7, 0);
 
    while (!isEmpty(&pq)) {
        printf("%d ", peek(&pq));
        pop(&pq);
    }
 
    return 0;
}


Java
// Java code to implement Priority Queue
// using Linked List
import java.util.* ;
 
class Solution
{
     
     
// Node
static class Node {
    int data;
     
    // Lower values indicate higher priority
    int priority;
     
    Node next;
     
}
 
static Node node = new Node();
     
// Function to Create A New Node
static Node newNode(int d, int p)
{
    Node temp = new Node();
    temp.data = d;
    temp.priority = p;
    temp.next = null;
     
    return temp;
}
     
// Return the value at head
static int peek(Node head)
{
    return (head).data;
}
     
// Removes the element with the
// highest priority form the list
static Node pop(Node head)
{
    Node temp = head;
    (head) = (head).next;
    return head;
}
     
// Function to push according to priority
static Node push(Node head, int d, int p)
{
    Node start = (head);
     
    // Create new Node
    Node temp = newNode(d, p);
     
    // Special Case: The head of list has lesser
    // priority than new node. So insert new
    // node before head node and change head node.
    if ((head).priority > p) {
     
        // Insert New Node before head
        temp.next = head;
        (head) = temp;
    }
    else {
     
        // Traverse the list and find a
        // position to insert new node
        while (start.next != null &&
            start.next.priority < p) {
            start = start.next;
        }
     
        // Either at the ends of the list
        // or at required position
        temp.next = start.next;
        start.next = temp;
    }
    return head;
}
     
// Function to check is list is empty
static int isEmpty(Node head)
{
    return ((head) == null)?1:0;
}
     
// Driver code
public static void main(String args[])
{
    // Create a Priority Queue
    // 7.4.5.6
    Node pq = newNode(4, 1);
    pq =push(pq, 5, 2);
    pq =push(pq, 6, 3);
    pq =push(pq, 7, 0);
     
    while (isEmpty(pq)==0) {
        System.out.printf("%d ", peek(pq));
        pq=pop(pq);
    }
     
}
}
 
// This code is contributed
// by Arnab Kundu


Python3
# Python3 code to implement Priority Queue
# using Singly Linked List
 
# Class to create new node which includes
# Node Data, and Node Priority
class PriorityQueueNode:
     
  def __init__(self, value, pr):
       
    self.data = value
    self.priority = pr
    self.next = None
         
# Implementation of Priority Queue
class PriorityQueue:
     
    def __init__(self):
         
        self.front = None
         
    # Method to check Priority Queue is Empty
    # or not if Empty then it will return True
    # Otherwise False
    def isEmpty(self):
         
        return True if self.front == None else False
     
    # Method to add items in Priority Queue
    # According to their priority value
    def push(self, value, priority):
         
        # Condition check for checking Priority
        # Queue is empty or not
        if self.isEmpty() == True:
             
            # Creating a new node and assigning
            # it to class variable
            self.front = PriorityQueueNode(value,
                                           priority)
             
            # Returning 1 for successful execution
            return 1
             
        else:
             
            # Special condition check to see that
            # first node priority value
            if self.front.priority > priority:
                 
                # Creating a new node
                newNode = PriorityQueueNode(value,
                                            priority)
                 
                # Updating the new node next value
                newNode.next = self.front
                 
                # Assigning it to self.front
                self.front = newNode
                 
                # Returning 1 for successful execution
                return 1
                 
            else:
                 
                # Traversing through Queue until it
                # finds the next smaller priority node
                temp = self.front
                 
                while temp.next:
                     
                    # If same priority node found then current
                    # node will come after previous node
                    if priority <= temp.next.priority:
                        break
                     
                    temp = temp.next
                 
                newNode = PriorityQueueNode(value,
                                            priority)
                newNode.next = temp.next
                temp.next = newNode
                 
                # Returning 1 for successful execution
                return 1
     
    # Method to remove high priority item
    # from the Priority Queue
    def pop(self):
         
        # Condition check for checking
        # Priority Queue is empty or not
        if self.isEmpty() == True:
            return
         
        else: 
             
            # Removing high priority node from
            # Priority Queue, and updating front
            # with next node
            self.front = self.front.next
            return 1
             
    # Method to return high priority node
    # value Not removing it
    def peek(self):
         
        # Condition check for checking Priority
        # Queue is empty or not
        if self.isEmpty() == True:
            return
        else:
            return self.front.data
             
    # Method to Traverse through Priority
    # Queue
    def traverse(self):
         
        # Condition check for checking Priority
        # Queue is empty or not
        if self.isEmpty() == True:
            return "Queue is Empty!"
        else:
            temp = self.front
            while temp:
                print(temp.data, end = " ")
                temp = temp.next
 
# Driver code
if __name__ == "__main__":
     
    # Creating an instance of Priority
    # Queue, and adding values
    # 7 -> 4 -> 5 -> 6
    pq = PriorityQueue()
    pq.push(4, 1)
    pq.push(5, 2)
    pq.push(6, 3)
    pq.push(7, 0)
     
    # Traversing through Priority Queue
    pq.traverse()
     
    # Removing highest Priority item
    # for priority queue
    pq.pop()
   
# This code is contributed by himanshu kanojiya


C#
// C# code to implement Priority Queue
// using Linked List
using System;
 
class GFG
{
// Node
public class Node
{
    public int data;
 
    // Lower values indicate
    // higher priority
    public int priority;
 
    public Node next;
}
 
public static Node node = new Node();
 
// Function to Create A New Node
public static Node newNode(int d, int p)
{
    Node temp = new Node();
    temp.data = d;
    temp.priority = p;
    temp.next = null;
 
    return temp;
}
 
// Return the value at head
public static int peek(Node head)
{
    return (head).data;
}
 
// Removes the element with the
// highest priority form the list
public static Node pop(Node head)
{
    Node temp = head;
    (head) = (head).next;
    return head;
}
 
// Function to push according to priority
public static Node push(Node head,
                        int d, int p)
{
    Node start = (head);
 
    // Create new Node
    Node temp = newNode(d, p);
 
    // Special Case: The head of list
    // has lesser priority than new node.
    // So insert new node before head node
    // and change head node.
    if ((head).priority > p)
    {
 
        // Insert New Node before head
        temp.next = head;
        (head) = temp;
    }
    else
    {
 
        // Traverse the list and find a
        // position to insert new node
        while (start.next != null &&
            start.next.priority < p)
        {
            start = start.next;
        }
 
        // Either at the ends of the list
        // or at required position
        temp.next = start.next;
        start.next = temp;
    }
    return head;
}
 
// Function to check is list is empty
public static int isEmpty(Node head)
{
    return ((head) == null) ? 1 : 0;
}
 
// Driver code
public static void Main(string[] args)
{
    // Create a Priority Queue
    // 7.4.5.6
    Node pq = newNode(4, 1);
    pq = push(pq, 5, 2);
    pq = push(pq, 6, 3);
    pq = push(pq, 7, 0);
 
    while (isEmpty(pq) == 0)
    {
        Console.Write("{0:D} ", peek(pq));
        pq = pop(pq);
    }
}
}
 
// This code is contributed by Shrikant13


Javascript


输出:
7 4 5 6

时间复杂度和与二叉堆的比较

peek()    push()    pop()
-----------------------------------------
Linked List |   O(1)      O(n)      O(1)
            |
Binary Heap |   O(1)    O(Log n)   O(Log n)