카테고리 없음

정렬 #2 병합정렬, 힙 정렬

원클릭쓰리버그 2022. 3. 11. 19:58
728x90
#include <iostream>
#include <vector>
#include <queue>
#include <stack>
#include <list>
using namespace std;
#include <thread>
// 오늘의 주제 : 정렬

// 힙 정렬
//O(Nlog(N))
void HeapSort(vector<int>& v)
{
	priority_queue<int, vector<int>,greater<int>> pq;

	for (int num : v)
	{
		pq.push(num);
	}

	v.clear();
	while (pq.empty() == false)
	{
		v.push_back(pq.top());
		pq.pop();
	}
}

// 병합 정렬
// 분할 정복(Divide and Conquer)
// - 분할(Divide)		문제를 더 단순하게 분할한다.
// - 정복(Conquer)		분할된 문제를 해결
// - 결합(Combine)		결과를 취합하여 마무리

// [3][K][7][2][J][4][8][9]			분할한다.
// [3][K][7][2] [J][4][8][9]		정복한다.
// [2][3][7][K] [4][8][9][J]		결합한다.
// [2][3][4][7][8][9][J][K]

// [3][K][7][2][J][4][8][9]			8개 * 1
// [3][K][7][2] [J][4][8][9]		4개 * 2
// [3][K] [7][2] [J][4] [8][9]		2개 * 4
// [3] [K] [7] [2] [J] [4] [8] [9]	1개 * 8
// [3][K] [2][7] [4][J] [8][9]		2개 * 4


// O(NlogN)
void MergeResult(vector<int>& v, int left, int mid, int right)
{
	// [2][3][7][K] [4][8][9][J]

	int leftIdx = left;
	int rightIdx = mid + 1;

	vector<int> temp;

	while (leftIdx <= mid && rightIdx <= right)
	{
		if (v[leftIdx] <= v[rightIdx])
		{
			temp.push_back(v[leftIdx]);
			leftIdx++;
		}
		else
		{
			temp.push_back(v[rightIdx]);
			rightIdx++;
		}

	}

	// 왼쪽이 먼저 끝났으면, 오른쪽 나머지 데이터 복사
	if (leftIdx > mid)
	{
		while (rightIdx <= right)
		{
			temp.push_back(v[rightIdx]);
			rightIdx++;
		}
	}
	else
	{
		while (leftIdx <= mid)
		{
			temp.push_back(v[leftIdx]);
			leftIdx++;
		}
	}
	
	for (int i = 0; i < temp.size(); i++)
	{
		// 시작점이 left이라서
		v[left + i] = temp[i];
	}
}




void MergeSort(vector<int>& v, int left, int right)
{
	if (left >= right)
		return;

	int mid = (left + right) / 2;

	MergeSort(v, left, mid);	// 4
	MergeSort(v, mid+1,right);	// 4

	//결과를 합친다.
	MergeResult(v, left, mid, right);
}

int main()
{
	vector<int> b;
	
	srand(time(0));

	for (int i = 0; i < 50; i++)
	{
		int randValue = rand() % 100;
		b.push_back(randValue);
	}
	
	MergeSort(b,0,b.size()-1);

}