1. 컨셉
퀵 정렬(Quick Sort)의 기본 개념은 정렬할 레코드를 한 번의 정렬을 통해 독립적인 두 부분으로 나누는 것입니다. 레코드의 한 부분의 키워드가 레코드의 다른 부분의 키워드보다 작을 경우 두 부분은 기록의 개별적으로 계속될 수 있습니다. 전체 순서를 정렬하는 목적을 달성하기 위해 정렬합니다.
2. 알고리즘 아이디어에 대한 설명
1. 나누기 수행: 벤치마크(피벗)를 찾아 순회한 후 벤치마크보다 작은 레코드를 뒤에서 앞으로 검색하고, 발견되면 앞으로 이동한 다음 벤치마크보다 큰 레코드를 앞에서 뒤로 검색하고, 벤치마크를 중심으로 사용하기 전까지 시퀀스는 두 부분으로 나뉘는데, 즉 벤치마크 왼쪽의 레코드가 벤치마크 오른쪽의 레코드보다 작습니다.
2. 시퀀스를 더 이상 나눌 수 없고 전체 시퀀스가 순서대로 될 때까지 시퀀스를 계속해서 두 부분으로 나누고, 하위 시퀀스도 각각 두 부분으로 나눕니다.
하나의 부서에 대한 아이디어:
3.코드
#include<iostream>
using namespace std;
int Partition(int* arr, int low, int high)//O(n)
{
int pivot = arr[low];//用子序列的第一个记录作为基准(枢轴)
while (low < high)//从序列的两端交替向中间扫描
{
//从后往前找比基准小的记录,找到往前移
while (low < high && arr[high] >= pivot) high--;
if (low < high)
{
arr[low++] = arr[high];
}
//从前往后找比基准大的记录,找到往后移
while (low < high && arr[low] <= pivot) low++;
if (low < high)
{
arr[high--] = arr[low];
}
}
arr[low] = pivot;//经过一次划分,将基准数字放在他该在的位置上(即基准左边的记录都小于基准右边的记录)
return low;//返回基准(枢轴)所在的位置
}
void Quick(int* arr, int low, int high)//O(nlogn)
{
if (low >= high) return;
int pivot = Partition(arr, low, high);//将基准进行一次划分,序列分为两份
Quick(arr, low, pivot - 1);//基准左边进行排序
Quick(arr, pivot + 1, high);//基准右边进行排序
}
void QuickSort(int* arr, int len)
{
Quick(arr, 0, len - 1);
}
void Show(int* arr, int len)
{
for (int i = 0; i < len; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
}
int main()
{
int arr[] = { 9,3,12,6,7,10,5,8,21,4 };//待排序序列
int len = sizeof(arr) / sizeof(arr[0]);
QuickSort(arr, len);
printf("快速排序结果为:");
Show(arr, sizeof(arr) / sizeof(arr[0]));
return 0;
}
4. 효율성 분석
시간 복잡도: O(nlogn)
공간 복잡도: 재귀 호출 스택으로 인해 O(logn), 재귀 로그 횟수
안정성: 불안정
빠른 정렬의 단점
순서가 많을수록 속도가 느려지고 공간 복잡도가 높아지며 불안정합니다.
순서가 오름차순 또는 내림차순이면 퀵 정렬의 시간 및 공간 복잡도가 높습니다.
시간 복잡도: O(n²) 단일 정렬의 경우 O(n), 재귀 호출의 경우 O(n)
공간 복잡도: O(n) 재귀 트리로 그리면 편향 트리입니다.