Search code examples
javadata-structuresqueuepriority-queue

How can I change the add order in my Priority Queue


I've been working a little on Priority queues and I have a problem. I have a string and I add the letters in this string with their frequencies as Node to the priority queue. When I pull a node from my Priority queue, I get the node of the highest frequency letter. But I want the lowest to come. How can I do that? If you can help, I would be appreciated.

Here is my custom PriorityQueue Class:

class PriorityQueue
{
    private Node[] heap;
    private int heapSize, capacity;

    /** Constructor **/
    public PriorityQueue(int capacity)
    {
        this.capacity = capacity + 1;
        heap = new Node[this.capacity];
        heapSize = 0;
    }
    /** function to clear **/
    public void clear()
    {
        heap = new Node[capacity];
        heapSize = 0;
    }
    /** function to check if empty **/
    public boolean isEmpty()
    {
        return heapSize == 0;
    }
    /** function to check if full **/
    public boolean isFull()
    {
        return heapSize == capacity - 1;
    }
    /** function to get Size **/
    public int size()
    {
        return heapSize;
    }
    public boolean isIncluded(Node element){
        if(isEmpty())
            return false;
        for(int i = 1; i<=heapSize; i++){
            if(heap[i].character == element.character){
                return true;
            }
        }
        return false;
    }
    /** function to insert task **/
    public void add(char character, int frequency)
    {
        Node newElement = new Node(frequency, character);
        if(!isIncluded(newElement)){
            heap[++heapSize] = newElement;
            int pos = heapSize;
            while (pos != 1 && newElement.freq > heap[pos/2].freq)
            {
                heap[pos] = heap[pos/2];
                pos /=2;
            }
            heap[pos] = newElement;
        }
    }
    /** function to remove task **/
    public Node poll()
    {
        int parent, child;
        Node item, temp;
        if (isEmpty() )
        {
            System.out.println("Heap is empty");
            return null;
        }

        item = heap[1];
        temp = heap[heapSize--];

        parent = 1;
        child = 2;
        while (child <= heapSize)
        {
            if (child < heapSize && heap[child].freq < heap[child + 1].freq)
                child++;
            if (temp.freq >= heap[child].freq)
                break;

            heap[parent] = heap[child];
            parent = child;
            child *= 2;
        }
        heap[parent] = temp;

        return item;
    }
}

Here is my test Main class:

import java.util.Scanner;
import java.util.Stack;

public class Main {
    static final int SIZE = 256;

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        PriorityQueue pq = new PriorityQueue(256);
        Stack<Node> myStack = new Stack<>();

        System.out.print("Enter your message: ");
        String input = scanner.nextLine();

        detectCharWithFreq(input,pq);

        for (int i = 0; i < pq.size();) {
            Node newNode = pq.poll();
            System.out.println("Character: " + newNode.character + " Freq: " + newNode.freq);
        }
    }

    static void detectCharWithFreq(String str, PriorityQueue pq)
    {
        int sizeOfString = str.length();
        int[] freq = new int[SIZE];

        for (int i = 0; i < sizeOfString; i++)
            freq[str.charAt(i)]++;

        for (int i = 0; i < sizeOfString; i++) {
            int frequency = freq[str.charAt(i)];
            char character = str.charAt(i);

            if (frequency != 0) {
                pq.add(character,frequency);
                frequency = 0;
            }
        }
    }
}

Here is my output:

"C:\Program Files\Java\jdk-15.0.1\bin\java.exe" "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2020.3.1\lib\idea_rt.jar=55573:C:\Program Files\JetBrains\IntelliJ IDEA 2020.3.1\bin" -Dfile.encoding=UTF-8 -classpath C:\Users\ayber\Desktop\Huffman\out\production\Huffman Main
Enter your message: hello
Character: l Freq: 2
Character: o Freq: 1
Character: h Freq: 1
Character: e Freq: 1

Process finished with exit code 0

The output that I want:

"C:\Program Files\Java\jdk-15.0.1\bin\java.exe" "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2020.3.1\lib\idea_rt.jar=55573:C:\Program Files\JetBrains\IntelliJ IDEA 2020.3.1\bin" -Dfile.encoding=UTF-8 -classpath C:\Users\ayber\Desktop\Huffman\out\production\Huffman Main
Enter your message: hello
Character: o Freq: 1
Character: h Freq: 1
Character: e Freq: 1
Character: l Freq: 2

Process finished with exit code 0


Solution

  • You simply need to reverse your conditions. If more than one has the same frequency, the result may vary, the frequencies will be in ascending order.

        public void add(char character, int frequency) {
            Node newElement = new Node(frequency, character);
            if (!isIncluded(newElement)) {
                heap[++heapSize] = newElement;
                int pos = heapSize;
                while (pos != 1 && newElement.freq < heap[pos / 2].freq) {  // ***HERE***
                    heap[pos] = heap[pos / 2];
                    pos /= 2;
                }
                heap[pos] = newElement;
            }
        }
        
        /** function to remove task **/
        public Node poll() {
            int parent, child;
            Node item, temp;
            if (isEmpty()) {
                System.out.println("Heap is empty");
                return null;
            }
            
            item = heap[1];
            temp = heap[heapSize--];
            
            parent = 1;
            child = 2;
            while (child <= heapSize) {
                if (child < heapSize
                        && heap[child].freq >= heap[child + 1].freq)  // ***HERE***
                    child++;
                if (temp.freq < heap[child].freq)                     // and ***HERE***
                    break;
                
                heap[parent] = heap[child];
                parent = child;
                child *= 2;
            }
            heap[parent] = temp;
            
            return item;
        }
    }