๐Ÿ—ฃ๏ธ ์‹ ์ž… ์ธํ„ฐ๋ทฐ/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); // ์›๋ž˜ ๊ทธ ๋…€์„ ์‚ญ์ œ
  	} 
}