퀵정렬 을 기반으로 한 정렬 알고리즘입니다. 분할 정복 알고리즘 요소를 피벗으로 선택하고 정렬된 배열의 올바른 위치에 피벗을 배치하여 선택한 피벗 주위에 주어진 배열을 분할합니다.
QuickSort는 어떻게 작동하나요?
추천 연습 퀵 정렬 사용해 보세요!의 핵심 프로세스 퀵정렬 는 분할() . 파티션의 목표는 정렬된 배열의 올바른 위치에 피벗(모든 요소를 피벗으로 선택할 수 있음)을 배치하고 모든 작은 요소를 피벗 왼쪽에 배치하고 모든 더 큰 요소를 피벗 오른쪽에 배치하는 것입니다. .
분할은 피벗이 올바른 위치에 배치된 후 피벗의 각 측면에서 반복적으로 수행되며 최종적으로 배열이 정렬됩니다.
퀵소트 작동 방식
배열 슬라이싱 자바
피벗 선택:
피벗을 선택하는 데는 다양한 선택이 있습니다.
- 항상 첫 번째 요소를 피벗으로 선택합니다. .
- 항상 마지막 요소를 피벗으로 선택합니다(아래 구현됨).
- 임의의 요소를 피벗으로 선택 .
- 가운데를 피벗으로 선택합니다.
파티션 알고리즘:
논리는 간단합니다. 가장 왼쪽 요소부터 시작하여 더 작은(또는 동일한) 요소의 인덱스를 다음과 같이 추적합니다. 나 . 순회하는 동안 더 작은 요소를 찾으면 현재 요소를 arr[i]로 바꿉니다. 그렇지 않으면 현재 요소를 무시합니다.
다음 예를 통해 파티션의 작동과 빠른 정렬 알고리즘을 이해해 보겠습니다.
고려해보세요: arr[] = {10, 80, 30, 90, 40}.
- 10을 피벗과 비교하여 피벗보다 작으므로 적절하게 배열합니다.
QuickSort의 파티션: 피벗을 10과 비교
- 80을 피벗과 비교합니다. 피벗보다 큽니다.
QuickSort의 파티션: 피벗을 80과 비교
자바 형식 문자열
- 30을 피벗과 비교합니다. 피벗보다 작으므로 적절하게 배열하십시오.
QuickSort의 파티션: 피벗을 30과 비교
- 90을 피벗과 비교합니다. 피벗보다 큽니다.
QuickSort의 파티션: 피벗을 90과 비교
- 올바른 위치에 피벗을 배열합니다.
QuickSort의 파티션: 피벗을 올바른 위치에 배치
퀵소트 예시:
파티션 프로세스는 재귀적으로 수행되므로 정렬된 배열의 실제 위치에 피벗을 계속 배치합니다. 반복적으로 피벗을 실제 위치에 놓으면 배열이 정렬됩니다.
아래 이미지를 따라 파티션 알고리즘의 재귀 구현이 배열 정렬에 어떻게 도움이 되는지 이해하세요.
소프트웨어 테스팅
- 기본 어레이의 초기 파티션:
Quicksort: 파티션 수행
- 하위 배열 분할:
Quicksort: 파티션 수행
Quick Sort의 코드 구현:
C++ #include using namespace std; int partition(int arr[],int low,int high) { //choose the pivot int pivot=arr[high]; //Index of smaller element and Indicate //the right position of pivot found so far int i=(low-1); for(int j=low;j<=high-1;j++) { //If current element is smaller than the pivot if(arr[j] 씨 // C program for QuickSort #include // Utility function to swap tp integers void swap(int* p1, int* p2) { int temp; temp = *p1; *p1 = *p2; *p2 = temp; } int partition(int arr[], int low, int high) { // choose the pivot int pivot = arr[high]; // Index of smaller element and Indicate // the right position of pivot found so far int i = (low - 1); for (int j = low; j <= high - 1; j++) { // If current element is smaller than the pivot if (arr[j] < pivot) { // Increment index of smaller element i++; swap(&arr[i], &arr[j]); } } swap(&arr[i + 1], &arr[high]); return (i + 1); } // The Quicksort function Implement void quickSort(int arr[], int low, int high) { // when low is less than high if (low < high) { // pi is the partition return index of pivot int pi = partition(arr, low, high); // Recursion Call // smaller element than pivot goes left and // higher element goes right quickSort(arr, low, pi - 1); quickSort(arr, pi + 1, high); } } int main() { int arr[] = { 10, 7, 8, 9, 1, 5 }; int n = sizeof(arr) / sizeof(arr[0]); // Function call quickSort(arr, 0, n - 1); // Print the sorted array printf('Sorted Array
'); for (int i = 0; i < n; i++) { printf('%d ', arr[i]); } return 0; } // This Code is Contributed By Diwakar Jha> 자바 // Java implementation of QuickSort import java.io.*; class GFG { // A utility function to swap two elements static void swap(int[] arr, int i, int j) { int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } // This function takes last element as pivot, // places the pivot element at its correct position // in sorted array, and places all smaller to left // of pivot and all greater elements to right of pivot static int partition(int[] arr, int low, int high) { // Choosing the pivot int pivot = arr[high]; // Index of smaller element and indicates // the right position of pivot found so far int i = (low - 1); for (int j = low; j <= high - 1; j++) { // If current element is smaller than the pivot if (arr[j] < pivot) { // Increment index of smaller element i++; swap(arr, i, j); } } swap(arr, i + 1, high); return (i + 1); } // The main function that implements QuickSort // arr[] -->정렬할 배열, // low --> 시작 인덱스, // high --> 끝 인덱스 static void QuickSort(int[] arr, int low, int high) { if (low< high) { // pi is partitioning index, arr[p] // is now at right place int pi = partition(arr, low, high); // Separately sort elements before // partition and after partition quickSort(arr, low, pi - 1); quickSort(arr, pi + 1, high); } } // To print sorted array public static void printArr(int[] arr) { for (int i = 0; i < arr.length; i++) { System.out.print(arr[i] + ' '); } } // Driver Code public static void main(String[] args) { int[] arr = { 10, 7, 8, 9, 1, 5 }; int N = arr.length; // Function call quickSort(arr, 0, N - 1); System.out.println('Sorted array:'); printArr(arr); } } // This code is contributed by Ayush Choudhary // Improved by Ajay Virmoti> 파이썬 # Python3 implementation of QuickSort # Function to find the partition position def partition(array, low, high): # Choose the rightmost element as pivot pivot = array[high] # Pointer for greater element i = low - 1 # Traverse through all elements # compare each element with pivot for j in range(low, high): if array[j] <= pivot: # If element smaller than pivot is found # swap it with the greater element pointed by i i = i + 1 # Swapping element at i with element at j (array[i], array[j]) = (array[j], array[i]) # Swap the pivot element with # the greater element specified by i (array[i + 1], array[high]) = (array[high], array[i + 1]) # Return the position from where partition is done return i + 1 # Function to perform quicksort def quicksort(array, low, high): if low < high: # Find pivot element such that # element smaller than pivot are on the left # element greater than pivot are on the right pi = partition(array, low, high) # Recursive call on the left of pivot quicksort(array, low, pi - 1) # Recursive call on the right of pivot quicksort(array, pi + 1, high) # Driver code if __name__ == '__main__': array = [10, 7, 8, 9, 1, 5] N = len(array) # Function call quicksort(array, 0, N - 1) print('Sorted array:') for x in array: print(x, end=' ') # This code is contributed by Adnan Aliakbar> 씨# // C# implementation of QuickSort using System; class GFG { // A utility function to swap two elements static void swap(int[] arr, int i, int j) { int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } // This function takes last element as pivot, // places the pivot element at its correct position // in sorted array, and places all smaller to left // of pivot and all greater elements to right of pivot static int partition(int[] arr, int low, int high) { // Choosing the pivot int pivot = arr[high]; // Index of smaller element and indicates // the right position of pivot found so far int i = (low - 1); for (int j = low; j <= high - 1; j++) { // If current element is smaller than the pivot if (arr[j] < pivot) { // Increment index of smaller element i++; swap(arr, i, j); } } swap(arr, i + 1, high); return (i + 1); } // The main function that implements QuickSort // arr[] -->정렬할 배열, // low --> 시작 인덱스, // high --> 끝 인덱스 static void QuickSort(int[] arr, int low, int high) { if (low< high) { // pi is partitioning index, arr[p] // is now at right place int pi = partition(arr, low, high); // Separately sort elements before // and after partition index quickSort(arr, low, pi - 1); quickSort(arr, pi + 1, high); } } // Driver Code public static void Main() { int[] arr = { 10, 7, 8, 9, 1, 5 }; int N = arr.Length; // Function call quickSort(arr, 0, N - 1); Console.WriteLine('Sorted array:'); for (int i = 0; i < N; i++) Console.Write(arr[i] + ' '); } } // This code is contributed by gfgking> 자바스크립트 // Function to partition the array and return the partition index function partition(arr, low, high) { // Choosing the pivot let pivot = arr[high]; // Index of smaller element and indicates the right position of pivot found so far let i = low - 1; for (let j = low; j <= high - 1; j++) { // If current element is smaller than the pivot if (arr[j] < pivot) { // Increment index of smaller element i++; [arr[i], arr[j]] = [arr[j], arr[i]]; // Swap elements } } [arr[i + 1], arr[high]] = [arr[high], arr[i + 1]]; // Swap pivot to its correct position return i + 1; // Return the partition index } // The main function that implements QuickSort function quickSort(arr, low, high) { if (low < high) { // pi is the partitioning index, arr[pi] is now at the right place let pi = partition(arr, low, high); // Separately sort elements before partition and after partition quickSort(arr, low, pi - 1); quickSort(arr, pi + 1, high); } } // Driver code let arr = [10, 7, 8, 9, 1, 5]; let N = arr.length; // Function call quickSort(arr, 0, N - 1); console.log('Sorted array:'); console.log(arr.join(' '));> PHP // code ?>// 이 함수는 마지막 요소를 피벗으로 사용합니다. // 피벗을 올바른 위치로 배치합니다. // 정렬된 배열에서 작은 요소는 모두 // 왼쪽에 배치하고 // 더 큰 요소는 피벗 함수 오른쪽에 배치합니다. partition(&$arr, $low,$high) { // 피벗 요소 선택 $pivot= $arr[$high]; // 더 작은 요소의 인덱스이며 // 피벗의 오른쪽 위치를 나타냅니다. $i=($low-1); for($j=$low;$j<=$high-1;$j++) { if($arr[$j]<$pivot) { // Increment index of smaller element $i++; list($arr[$i],$arr[$j])=array($arr[$j],$arr[$i]); } } // Pivot element as correct position list($arr[$i+1],$arr[$high])=array($arr[$high],$arr[$i+1]); return ($i+1); } // The main function that implement as QuickSort // arr[]:- Array to be sorted // low:- Starting Index //high:- Ending Index function quickSort(&$arr,$low,$high) { if($low<$high) { // pi is partition $pi= partition($arr,$low,$high); // Sort the array // Before the partition of Element quickSort($arr,$low,$pi-1); // After the partition Element quickSort($arr,$pi+1,$high); } } // Driver Code $arr= array(10,7,8,9,1,5); $N=count($arr); // Function Call quickSort($arr,0,$N-1); echo 'Sorted Array:
'; for($i=0;$i<$N;$i++) { echo $arr[$i]. ' '; } //This code is contributed by Diwakar Jha> 산출
Sorted Array 1 5 7 8 9 10>
퀵 정렬의 복잡성 분석 :
시간 복잡도:
- 최선의 경우 :Ω(N로그(N))
퀵 정렬의 가장 좋은 시나리오는 각 단계에서 선택된 피벗이 배열을 대략 동일한 절반으로 나눌 때 발생합니다.
이 경우 알고리즘은 균형 잡힌 파티션을 만들어 효율적인 정렬을 수행합니다. - 평균 사례: θ ( N log (N))
Quicksort의 평균 사례 성능은 일반적으로 실제로 매우 우수하여 가장 빠른 정렬 알고리즘 중 하나입니다. - 최악의 경우: O(N2)
Quicksort의 최악의 시나리오는 각 단계의 피벗이 일관되게 매우 불균형한 파티션을 초래할 때 발생합니다. 배열이 이미 정렬되어 있고 피벗이 항상 가장 작거나 가장 큰 요소로 선택되는 경우. 최악의 시나리오를 완화하기 위해 좋은 피벗(예: 중앙값 3)을 선택하고 무작위 알고리즘(Randomized Quicksort)을 사용하여 정렬 전에 요소를 섞는 등 다양한 기술이 사용됩니다. - 보조 공간: O(1), 재귀 스택 공간을 고려하지 않으면. 재귀 스택 공간을 고려하면 최악의 경우 퀵 정렬은 다음과 같은 결과를 초래할 수 있습니다. 영형 ( N ).
퀵 정렬의 장점:
- 문제 해결을 더 쉽게 해주는 분할 정복 알고리즘입니다.
- 대규모 데이터 세트에서는 효율적입니다.
- 작동하는 데 적은 양의 메모리만 필요하므로 오버헤드가 낮습니다.
빠른 정렬의 단점:
- 최악의 경우 O(N)의 시간 복잡도를 갖습니다.2), 이는 피벗을 잘못 선택했을 때 발생합니다.
- 작은 데이터 세트에는 좋은 선택이 아닙니다.
- 이는 안정적인 정렬이 아닙니다. 즉, 두 요소가 동일한 키를 갖는 경우 빠른 정렬의 경우 정렬된 출력에서 상대 순서가 유지되지 않습니다. 여기서는 피벗 위치에 따라 요소를 교체하기 때문입니다(원본을 고려하지 않음). 위치).
