File indexing completed on 2024-05-12 16:01:33

0001 /* This file is part of the KDE project
0002    SPDX-FileCopyrightText: 2009 Vera Lukman <shicmap@gmail.com>
0003 
0004    SPDX-License-Identifier: LGPL-2.0-only
0005 */
0006 
0007 #ifndef KIS_MIN_HEAP_H
0008 #define KIS_MIN_HEAP_H
0009 
0010 #include <kis_debug.h>
0011 #include <QList>
0012 
0013 template <typename T> struct PriorityNode {
0014     T data;
0015     int key;
0016     int pos;
0017 };
0018 
0019 template <typename T, int N> class KisMinHeap
0020 {
0021 public:
0022 
0023     KisMinHeap()
0024         : m_last(0),
0025           m_size(N),
0026           m_list(new PriorityNode <T>* [N])
0027     {
0028     }
0029 
0030     inline KisMinHeap(const T& data, int key)
0031         : KisMinHeap()
0032     {
0033         append(data, key);
0034     }
0035 
0036     inline KisMinHeap(PriorityNode<T>* node)
0037         : KisMinHeap()
0038     {
0039         append(node);
0040     }
0041 
0042     ~KisMinHeap() {
0043         delete[] m_list;
0044     }
0045 
0046     inline void changeKey(int pos, int newKey) {
0047         m_list[pos]->key = newKey;
0048         heapifyUp(pos);
0049         heapifyDown(pos);
0050     }
0051 
0052     inline int size() {
0053         return m_last;
0054     }
0055 
0056     inline T valueAt(int pos) {
0057         return m_list[pos]->data;
0058     }
0059 
0060     void append(PriorityNode<T>* node) {
0061         node->pos = m_last;
0062         m_list[m_last] = node;
0063         ++m_last;
0064         heapifyUp(node->pos);
0065 
0066         node = 0;
0067     }
0068 
0069     void append(const T& data, int key) {
0070         if (m_last >= m_size) return;
0071         PriorityNode <T>* node = new PriorityNode<T>;
0072         node->data = data;
0073         node->key = key;
0074 
0075         append(node);
0076     }
0077 
0078     void remove(int pos) {
0079         if (pos < 0) return;
0080         swap(pos, m_last - 1);
0081         --m_last;
0082         delete m_list[m_last];
0083         m_list[m_last] = 0;
0084         heapifyUp(pos);
0085         heapifyDown(pos);
0086     }
0087 
0088     void remove(const T& data) {
0089         int pos = find(data);
0090         if (pos >= 0) remove(pos);
0091     }
0092 
0093     int find(const T& data) {
0094         for (int pos = 0; pos < m_last; pos++) {
0095             if (m_list[pos]->data == data) return pos;
0096         }
0097         return -1;
0098     }
0099 
0100 private:
0101 
0102     int m_last;
0103     int m_size;
0104     PriorityNode <T>* *m_list;
0105 
0106     void swap(int pos1, int pos2) {
0107         PriorityNode <T>* temp(m_list[pos1]);
0108         m_list[pos1] = m_list[pos2];
0109         m_list[pos1]->pos = pos1;
0110         m_list[pos2] = temp;
0111         m_list[pos2]->pos = pos2;
0112         temp = 0;
0113     }
0114 
0115     void heapifyUp(int pos) {
0116         while (pos > 0 && m_list[pos]->key < m_list[parentPos(pos)]->key) {
0117             swap(pos, parentPos(pos));
0118             pos = parentPos(pos);
0119         }
0120     }
0121 
0122     void heapifyDown(int pos) {
0123         if (leftChildPos(pos) >= m_last) return; //no children
0124         else {
0125             int childPos = 0;
0126 
0127             if (rightChildPos(pos) >= m_last) { //1 child
0128                 childPos = leftChildPos(pos);
0129             } else { //2 children
0130                 m_list[leftChildPos(pos)]->key < m_list[rightChildPos(pos)]->key ? childPos = leftChildPos(pos) :
0131                         childPos = rightChildPos(pos);
0132             }
0133 
0134             if (m_list[childPos]->key < m_list[pos]->key) {
0135                 swap(pos, childPos);
0136                 heapifyDown(childPos);
0137             } else return;
0138         }
0139     }
0140 
0141     inline int leftChildPos(int x) {
0142         return 2 * x + 1;
0143     }
0144 
0145     inline int rightChildPos(int x) {
0146         return 2 * x + 2;
0147     }
0148 
0149     inline int parentPos(int x) {
0150         return (x - 1) / 2;
0151     }
0152 
0153 };
0154 
0155 #endif // HEAP_H