<선택정렬> -> 느릴수 있으나 16개 이하에서는 오히려 더 빠름
- 데이터 중 가장 작은 값부터 하나씩 선택하여 정렬
시간복잡도 - O(n²)
공간복잡도 - O(1)
불안정정렬
public static void SelectionSort(int[] array)
{
for (int i=0; i<array.Length; i++)
{
int minIndex = i;
for (int j=0; j<array.Length; j++)
{
if (array[j] < array[minIndex])
{
minIndex = j;
}
}
Swep(array, i, minIndex);
}
}
<삽입정렬>
- 데이터를 하나씩 꺼내어 정렬된 자료 중 적합한 위치에 삽입하여 정렬
시간복잡도 - O(n²)
공간복잡도 - O(1)
안정정렬 - O
public static void InsertionSort(int[] array)
{
for (int i = 1; i < array.Length; i++)
{
for (int j = i; j > 0; j--)
{
if (array[j - 1] > array[j])
{
Swep(array, j - 1, j);
}
else
{
break;
}
}
}
}
<버블정렬> -> 인덱스 사용이 불가능 할때 사용가능
- 서로 인접한 데이터를 비교하여 정렬
시간복잡도 - O(n²)
공간복잡도 - O(1)
안정정렬 - O
public static void BubbleSort(int[] array)
{
for (int i = 1; i < array.Length; i++)
{
for (int j = 0; j < array.Length - i; j++)
{
if (array[j] > array[j + 1])
{
Swep(array, j, j + 1);
}
}
}
}
<병합정렬>
- 데이터를 2분할하여 정렬 후 합병
- 데이터 갯수만큼의 추가적인 메모리가 필요
시간복잡도 - O(nlogn)
공간복잡도 - O(n)
안정정렬 - O
public static void MergeSort(int[] array) => MergeSort(array, 0, array.Length - 1);
public static void MergeSort(int[] array, int start, int end)
{
if (start == end)
return;
int mid = (start + end) / 2;
MergeSort(array, start, mid);
MergeSort(array, mid + 1, end);
Merge(array, start, mid, end);
}
}
public static void Merge(int[] array, int start, int mid, int end)
{
List<int> sortedList = new List<int>();
int leftIndex = start;
int rightIndex = mid + 1;
while (leftIndex <= mid && rightIndex <= end)
{
if (array[leftIndex] < array[rightIndex])
{
sortedList.Add(array[leftIndex]);
leftIndex++;
}
else
{
sortedList.Add(array[rightIndex]);
rightIndex++;
}
}
if (leftIndex <= mid)
{
while (leftIndex <= mid)
{
sortedList.Add(array[leftIndex]);
leftIndex++;
}
}
else
{
while (rightIndex <= end)
{
sortedList.Add(array[rightIndex]);
rightIndex++;
}
}
for (int i = 0; i < sortedList.Count; i++)
{
array[start + i] = sortedList[i];
}
}
<퀵정렬>
- 하나의 기준(피벗)을 기준으로 작은값과 큰값을 2분할하여 정렬
- 최악의 경우(피벗이 최소값 또는 최대값)인 경우 시간복잡도가 O(n²)
시간복잡도 - 평균 : O(nlogn) 최악 : O(n²)
공간복잡도 - O(1)
불안정정렬
public static void QuickSort(int[] array) => QuickSort(array, 0, array.Length - 1);
public static void QuickSort(int[] array, int start, int end)
{
if (start >= end)
{
return;
}
int pivot = start;
int left = pivot + 1;
int right = end;
while (left <= right)
{
while (array[pivot] >= array[left] && left < right)
{
left++;
}
while (array[pivot] < array[right] && left <= right)
{
right--;
}
if (left < right)
{
Swep(array, left, right);
}
else
{
Swep(array, pivot, right);
break;
}
}
QuickSort(array, start, right - 1);
QuickSort(array, right + 1, end);
}
<힙정렬>
- 힙을 이용하여 우선순위가 가장 높은 요소가 가장 마지막 요소와 교체된 후 제거되는 방법을 이용
- 배열에서 연속적인 데이터를 사용하지 않기 때문에 캐시 메모리를 효율적으로 사용할 수 없어 상대적으로 느림
시간복잡도 - O(nlogn)
공간복잡도 - O(1)
불안정정렬
public static void HeapSort(int[] array)
{
MakeHeap(array);
for (int i = array.Length - 1; i > 0; i--)
{
Swep(array, 0, i);
Heapify(array, 0, i);
}
}
private static void MakeHeap(int[] array)
{
for (int i = array.Length / 2 - 1; i >= 0; i--)
{
Heapify(array, i, array.Length);
}
}
private static void Heapify(int[] array, int index, int size)
{
int left = index * 2 + 1;
int right = index * 2 + 2;
int max = index;
if (left < size && array[left] > array[max])
{
max = left;
}
if (right < size && array[right] > array[max])
{
max = right;
}
if (max != index)
{
Swep(array, index, max);
Heapify(array, max, size);
}
}
static void Main(string[] args)
{
int num = 200;
Console.WriteLine($"{num, 5}");
Console.WriteLine(num);
Random random = new Random();
int count = 100;
int[] selectArray = new int[count];
int[] insertArray = new int[count];
int[] bubbleArray = new int[count];
int[] mergeArray = new int[count];
int[] quickArray = new int[count];
Array.Sort(selectArray);
Console.WriteLine("랜덤 데이터: ");
for (int i = 0; i < count; i++)
{
int rand = random.Next(0, 100);
Console.Write($"{rand, 3}");
selectArray[i] = rand;
insertArray[i] = rand;
bubbleArray[i] = rand;
mergeArray[i] = rand;
quickArray[i] = rand;
}
Console.WriteLine();
Console.WriteLine();
SelectionSort(selectArray);
Console.WriteLine("선택 정렬 결과 : ");
foreach (int value in selectArray)
{
Console.Write($"{value,3}");
}
Console.WriteLine();
InsertionSort(insertArray);
Console.WriteLine("삽입 정렬 결과 : ");
foreach (int value in insertArray)
{
Console.Write($"{value,3}");
}
Console.WriteLine();
Stopwatch sw1 = new Stopwatch();
sw1.Start();
BubbleSort(bubbleArray);
sw1.Stop();
Console.WriteLine("버블 정렬 결과: { 0}", sw1.ElapsedTicks);
foreach (int value in bubbleArray)
{
Console.Write($"{value,3}");
}
Console.WriteLine();
Stopwatch sw2 = new Stopwatch();
sw2.Start();
MergeSort(mergeArray);
sw2.Stop();
Console.WriteLine("병합 정렬 결과: { 0}", sw2.ElapsedTicks);
foreach (int value in mergeArray)
{
Console.Write($"{value,3}");
}
Console.WriteLine();
QuickSort(quickArray);
Console.WriteLine("퀵 정렬 결과: ");
foreach (int value in quickArray)
{
Console.Write($"{ value,3}");
}
Console.WriteLine();
}
public static void Swep(int[] array, int left, int right)
{
int temp = array[left];
array[left] = array[right];
array[right] = temp;
}