๐ฃ๏ธ ์ ์
์ธํฐ๋ทฐ/C++
์ ์ ๊ฐ๋ฐ์ ๊ธฐ์ ๋ฉด์ : C++ 05 (์์ฝ๋ฉ: Heapify, ์ต๋ํ, ์ด์งํ์)
์ซ๋
2023. 12. 25. 21:15
์๋ ํ์ธ์, ์ซ๋๋ฏธ์ ๋๋ค.
์์ฝ๋ฉ์ ์ฒ์์ด๋ผ์์ ...
ํ๋ฆฐ ๋ด์ฉ์ด ์๋ค๋ฉด ๋๊ธ๋ก ์๋ ค์ฃผ์๋ฉด ๊ฐ์ฌํ๊ฒ ์ต๋๋ค (_ _ )
๐ฃ๏ธ Heapify ์ฝ๋๋ฅผ ์์ฑํด๋ณด์ธ์
#include <iostream>
using namespace std;
void swap(int& a, int& b) {
int temp = a;
a = b;
b = temp;
}
int num = 9;
int heap[9] = {7, 6, 5, 8, 3, 5, 9, 1, 6};
int main() {
for (int i = 1; i < num; i++) {
int c = i;
do {
int root = (c - 1) / 2;
if (heap[root] < heap[c]) {
swap(heap[root], heap[c]);
}
c = root;
} while (c != 0);
}
for (int i = num - 1; i >= 0; i--) {
swap(heap[0], heap[i]);
int root = 0;
int c = 1;
do {
c = 2 * root + 1;
if (c < i - 1 && heap[c] < heap[c + 1]) {
c++;
}
if (c < i && heap[root] < heap[c]) {
swap(heap[root], heap[c]);
}
root = c;
} while (c < i);
}
for (int i = 0; i < num; i++) {
cout << heap[i] << " ";
}
return 0;
}
๐ฃ๏ธ ์ต๋ ํ ๊ตฌํ์ ์ฝ๋๋ก ์์ฑํด๋ณด์ธ์
#include <iostream>
using namespace std;
#include <vector>
#include <queue>
template<typename T>
class PriorityQueue
{
public:
// โฐ O(logN)
void push(const T& data)
{
heap.push_back(data);
// ๐ COUP' ๐
int now = static_cast<int>(heap.size()) - 1;
// ๋ฃจํธ ๋
ธ๋๊น์ง
while (now > 0)
{
// ๋ถ๋ชจ ๋
ธ๋์ ๋น๊ตํด์ heap[now]๊ฐ ๋ ์์ผ๋ฉด COUP ํจ๋ฐฐ, ๋น ์ ธ๋์จ๋ค
int next = (now - 1) / 2;
if(heap[now] < heap[next])
break;
// ๋ถ๋ชจ ๋
ธ๋์ ๋น๊ตํ์ ๋, heap[now] ๊ฐ ๋ ํฌ๋ฉด COUP ์งํ์์ผ, ๋ฐ์ดํฐ ๊ต์ฒด!
::swap(heap[now], heap[next]);
now = next; // ํ๊ณ ํ๊ณ ์ฌ๋ผ๊ฐ๋๋ก ํ๋ค
}
}
// โฐ O(logN)
void pop()
{
// ๐ REVERSE COUP' ๐
// ์ต๋๊ฐ(๋ฃจํธ) ์ ๋จผ์ ์ ๊ฑฐํ๋ค, ๋ง์ง๋ง ๋
ธ๋๋ฅผ ๋ฃจํธ๋ก ์ฎ๊ธด๋ค
// ์ญ๋์ฅ๊นจ๊ธฐ๋ฅผ ํ ๋๋ ๊ทธ๋ฅ ๋์ฅ๊นจ๊ธฐ๋ณด๋ค ์กฐ๊ธ ๋ ๊น๋ค๋ก์ด ์ด์ ๊ฐ,
// ์์์ด ์ผ์ชฝ, ์ค๋ฅธ์ชฝ ๋ ๋ค ๋ด์ผ ํด์
// ๋ ์์ ์ค ๋ ํฐ ์์ด์ ๋ฐ๊ฟ์ค์ผ ํ๋ค๋ ์ ์ ๋ง๋ค์ด์ค์ผ ํ๋ค.
heap[0] = heap.back();
heap.pop_back()
int now = 0;
while true()
{
int left = 2 * now + 1;
int right = 2 * now + 2;
// ๋ฆฌํ์ ๋๋ฌํ ๊ฒฝ์ฐ, ๋น ์ ธ๋์จ๋ค. ๋ ์ด์ ๊ฐ ๊ตฌ์์ด ์๊ธฐ ๋๋ฌธ์ด๋ค.
if (left >= (int)heap.size())
break;
// (1) next ๊ฐ ๋ณํ๊ฐ ์๊ฑด == ์์์ด ๋ค ์๋ค
int next = now;
// (2) next ๊ฐ left ๊ฐ ๋๊ฑด == ์ผ์ชฝ ์์์ด ๋๋ณด๋ค ํฌ๋ค
if (heap[next] < heap[left]) next = left;
// (3) next ๊ฐ right ๊ฐ ๋๊ฑด == ์ค๋ฅธ์ชฝ ์์์ด ๋๋ณด๋ค ํฌ๋ค
if (right < heap.size() && heap[next] < heap[right])
next = right;
// (1) left, right ๋ ๋ค now ๊ฐ๋ณด๋ค ์์ผ๋ฉด ์ข
๋ฃ
if (next == now)
break;
// (2),(3) ๊ทธ๊ฒ ์๋๋ฉด ์ญ์ฟ ๋ฐํ ใฑใฑ
::swap (heap[now], heap[next]);
now = next;
}
}
// โฐ O(1)
T& top()
{
return heap[0];
}
// โฐ O(1)
bool empty()
{
return heap.empty();
}
private:
vector<T> heap;
};
int main()
{
vector<int> v;
PriorityQueue<int> pq;
}
๐ฃ๏ธ ์ด์ง ํ์ ์ฝ๋๋ฅผ ์์ฑํด๋ณด์ธ์
vector<int> numbers;
void BinarySearch(int N) // N ์ ์ฐ๋ฆฌ๊ฐ ์ฐพ์ ๋ฒํธ
{
int left = 0;
int right = numbers.size() - 1;
while (left <= right) // ์ด ์กฐ๊ฑด ์์ง ๋ง๊ธฐ!
{
cout << "ํ์ ๋ฒ์ : " << left << "~" << right << endl;
int mid = (left + right) / 2;
if (N < numbers[mid])
{
right = mid - 1;
}
else if (N > numbers[mid])
{
left = mid + 1;
}
else // ๊ฐ์ด ๊ฐ๋ค๋ ๊ฒ์ด๋, ์ฐพ์๋ค๋ ์๋ฏธ!
{
cout << "์ฐพ์๋ค!" << endl;
break;
}
}
}
int main()
{
numbers = {1, 8, 15, 23, 32, 44, 56, 63, 81, 91};
BinarySearch(81);
}
๐ฃ๏ธ ์ด์ง ํ์ ํธ๋ฆฌ ์ฝ๋๋ฅผ ์์ฑํด๋ณด์ธ์
// BinarySearchTree.h
#pragma once
struct Node
{
Node* parent = nullptr;
Node* left = nullptr; // ์ผ์ชฝ ์์
Node* right = nullptr; // ์ค๋ฅธ์ชฝ ์์
int key = 0; // ๋ฐ์ดํฐ
};
class BinarySearchTree
{
public:
Node* Search(Node* node, int key);
void Insert(int key); // ๋
ธ๋ ์์ฑ ํ ์์น๋ฅผ ๊ณจ๋ผ์ค์ ๋ฃ์ด์ฃผ๋ ํ์
// ์ญ์ ๊ธฐ๋ฅ์ ์ํ ํฌํผ ํจ์๋ค
Node* Min(Node* node); // ์ด๋ ํ ํธ๋ฆฌ ๊ธฐ์ค์ผ๋ก ๊ฐ์ฅ ์์ ๊ฐ์ด ์ด๋?
Node* Max(Node* node); // ์ด๋ ํ ํธ๋ฆฌ ๊ธฐ์ค์ผ๋ก ๊ฐ์ฅ ํฐ ๊ฐ์ด ์ด๋?
Node* Next(Node* node); // ๊ทธ ๋ค์์ผ๋ก ํฐ ?
void Replace(Node* u, Node* v); // ์ญ์ ํ ๋ ์ฌ์ค์
void Delete(int key);
void Delete(Node* node);
private:
Node* _root = nullptr;
}
// BinarySearchTree.cpp
#include "BinarySearchTree.h"
void BinarySearchTree::Insert(int key)
{
Node* newNode = new Node();
newNode->key= key;
if(_root == nullptr) // ๋ง์ฝ ๋ด๊ฐ ์ฒซ ๋ฒ์งธ ๋
ธ๋๋ผ๋ฉด
{
_root = newNode;
return;
}
// ์ถ๊ฐํ ์์น๋ฅผ ์ฐพ๊ธฐ
Node* node = _root;
Node* parent = nullptr;
while (node)
{
parent = node;
if (key < node->key)
node = node->left;
else
node = node->right;
}
newNode->parent = parent;
if (key < parent->key)
parent->left = newNode;
else
parent->right = newNode;
}
Node* BinarySearchTree::Search(Node* node, int key)
{
if (node == nullptr || key == node->key)
return node;
if (key < node->key)
return Search(node->left, key); // ์ฌ๊ท
else
return Search(node->right, key);
}
/* ํธ๋ฆฌ์ ์ต์๊ฐ */
Node* BinarySearchTree::Min(Node* node)
{
if (node == nullptr)
return;
while (node->left)
node = node->left;
return node;
}
/* ํธ๋ฆฌ์ ์ต๋๊ฐ */
Node* BinarySearchTree::Max(Node* node)
{
if (node == nullptr)
return;
while (node->right)
node = node->right;
return node;
}
/* โญ๏ธ GOOGLE: ์ด๋ ํ ๋
ธ๋๋ฅผ ๊ธฐ์ค์ผ๋ก "๊ทธ ๋ค์์ผ๋ก ํฐ ๋ฐ์ดํฐ"๋ ์ด๋ ๋
ธ๋์ ์๋์ง? */
Node* BinarySearchTree::Next(Node* node)
{
// 1๋ฒ์งธ ๊ฒฝ์ฐ: ํ ์นธ ์ค๋ฅธ์ชฝ์ผ๋ก ๊ฐ๊ณ ๊ฑฐ๊ธฐ์ ์ ์ผ ์์ ๊ฐ์ ์ถ์ถ
if (node->right)
return Min(node->right);
// 2๋ฒ์งธ ๊ฒฝ์ฐ: ์กฐ์ ์ค ๋๋ฅผ ์ผ์ชฝ ์์์ผ๋ก ๋ค๊ณ ์๋ ์กฐ์์ ๋ง๋ ๋๊น์ง ์ฌ๋ผ๊ฐ๋ค
Node* parent = node->parent;
while (parent && node == parent->left)
{
node = parent;
parent = parent->parent;
}
return parent;
}
/* ์ฌ๋ฐฐ์น*/
void BinarySearchTree::Replace(Node* u, Node* v)
{
if (u->parent == nullptr)
_root = v;
else if (u == u->parent->left)
u->parent->left = v;
else
u->parent->right = v;
if (v)
v->parent = u->parent;
delete u;
}
/* ํค ์ญ์ */
void BinarySearchTree::Delete(int key)
{
Node* deleteNode = Search(_root, key);
Delete(deleteNode);
}
/* ๋
ธ๋ ์ญ์ */
void BinarySearchTree::Delete(Node* node)
{
if (node == nullptr)
return;
// ์ญ์ ํ ๋
ธ๋์ ์์์ด ์ผ์ชฝ์ ์๊ณ ์ค๋ฅธ์ชฝ์ ์๋ ๊ฒฝ์ฐ
if (node->left == nullptr)
{
Replace(node, node->right);
}
// ์ญ์ ํ ๋
ธ๋์ ์์์ด ์ผ์ชฝ์ ์๊ณ ์ค๋ฅธ์ชฝ์ ์๋ ๊ฒฝ์ฐ
else if (node->right == nullptr)
{
Replace(node, node->left);
}
// ์ญ์ ํ ๋
ธ๋์ ์์์ด ์์ชฝ์ 2๊ฐ์ธ ๊ฒฝ์ฐ
else
{
Node* next = Next(node); // ๊ทธ ๋ค์ ํฐ ๋
์
node->key = next->key; // ํค๋ง ์ด์ง ๋ณต์ฌ
Delete(next); // ์๋ ๊ทธ ๋
์ ์ญ์
}
}