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