카테고리 없음

퀵 정렬(Quick Sort) 구현

sudo 2021. 8. 8. 00:33

 

 

// QuickSort.h

#pragma once
template <typename T>
class CQuickSort
{

public:
	CQuickSort()
	{
		m_Capacity = 10;
		m_Data = new T[m_Capacity];
		m_Size = 0;
	}
	~CQuickSort()
	{
		delete[] m_Data;
	}

private:
	T* m_Data;
	int m_Size;
	int m_Capacity;

public:
	int GetSize()	const
	{
		return m_Size;
	}

	int GetCapacity()	const
	{
		return m_Capacity;
	}

	const T& GetData(int Index)	const
	{
		return m_Data[Index];
	}

public:
	void PushData(const T& Data)
	{
		if (m_Capacity == m_Size)
		{
			m_Capacity *= 2;
			T* tmp = new T[m_Capacity];

			memcpy(tmp, m_Data, sizeof(T) * m_Capacity);

			delete[] m_Data;
			
			m_Data = tmp;
		}

		m_Data[m_Size] = Data;
		++m_Size;
	}
	int Partition(int Left, int Right)
	{
		int Pivot = m_Data[Right];
		int i = Left - 1;

		for (int j = Left; j < Right; ++j)
		{
			if (Pivot >= m_Data[j])
			{
				++i;
				T temp = m_Data[i];
				m_Data[i] = m_Data[j];
				m_Data[j] = temp;
			}
		}

		T temp2 = m_Data[i + 1];
		m_Data[i + 1] = m_Data[Right];
		m_Data[Right] = temp2;

		return i + 1;
	}

	void Sort(int Left, int Right)
	{
		// 만약에 정렬해야할 데이터가 1,2,3,4,5 이렇게 있다면
		// parition은 pivot으로 5를 리턴하고 2번째 sort에서는
		// pivot + 1(= right + 1), right를 인자로 Sort를 호출
		// 이때는 말이 안되는 상황이므로 걸러줘야 한다.
		// 따라서 이런 if문을 빼먹으면 안된다.
		if (Left < Right)
		{
			int NewPivot = Partition(Left, Right);
			Sort(Left, NewPivot - 1);
			Sort(NewPivot + 1, Right);
		}
	}
};

 

#include <iostream>
#include <time.h>
#include <crtdbg.h>
#include "QuickSort.h"

int main()
{
	_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);

	srand((unsigned int)time(0));
	rand();


	CQuickSort<int> qs;

	for (int i = 0; i < 20; ++i)
	{
		int random = rand();
		std::cout << "Push Data : " << random << std::endl;
		qs.PushData(random);
	}

	qs.Sort(0, qs.GetSize() - 1);

	std::cout << "==================== Sort ====================" << std::endl;

	for (int i = 0; i < 20; ++i)
	{
		std::cout << qs.GetData(i) << std::endl;
	}


}

 

main.cpp 출력 결과

최적의 경우(Pivot이 딱 데이터를 반으로 가르는 경우) 에는 T(n) = 2T(n/2) + θ(n)이므로 마스터 정리를 이용하면 T(n) = θ(nlogn) 이 나온다. 하지만 최악의 경우(ex. 오름차순, 내림차순으로 정렬되어 있는 데이터를 퀵 정렬로 정렬해야 하는 경우)는 θ(n^2)이 나온다.