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