4 빠른 정렬

Quicksort는 분할 및 정복 재귀 알고리즘으로 기본적으로 병합 정렬의 내부 버전입니다. 원래 주문에 속합니다.

 

(1) 아이디어 :

         정렬 할 데이터를 두 개의 하위 열로 나누고 숫자 열에서 "벤치 마크"로 숫자를 선택한 다음 다른 데이터를 순회하여 "벤치 마크"와 비교하여 더 작은 데이터를 앞에 놓고 뒤에있는 것보다 큽니다. 이후 재귀를 통해 각 하위 시퀀스는 기준 값보다 작은 요소의 하위 시퀀스와 참조 값보다 큰 요소의 하위 시퀀스가 ​​정렬 될 때까지 더 작은 시퀀스로 분할됩니다.

 

(2) 복잡성 분석 :

(2.1) 시간 복잡성 :

         가장 좋은 경우는 피벗 요소가 중간에 있습니다. 시퀀스가 ​​두 부분 (두 부분)으로 나눌 때마다 O (nlogn)이기 때문입니다.

         최악의 경우 : pivot 요소는 기본적으로 순서대로 항상 가장 작은 요소이며 거의 열등한 거품 정렬로 퇴화 n ^ {2}되므로 O ( n ^ {2})입니다.

         평균 상황 : O (nlogn).

(2.2) 공간 복잡성 :

         일반적으로 O (logn)입니다. 빠른 정렬은 시퀀스 작업 중 일정한 수준의 공간 만 필요합니다. 공간 복잡도는 O (1)입니다. 그러나 재귀 스택은 최소한 O (logn) 및 최대 O (n) 공간을 소비해야합니다. 빠른 정렬의 공간 복잡성은 일반적인 경우에만 O (logn)이며, 최악의 경우라면 분명히 O (n) 공간입니다.

 

(3) 안정성 :

         빠른 정렬에는 두 가지 방향이 있습니다. a [i] <= a [center_index] 인 경우 왼쪽 i 아래 첨자가 오른쪽으로 곧바로 이동합니다. 여기서 center_index는 중앙 요소의 배열 첨자이며 일반적으로의 0 번째 요소로 간주됩니다. 배열. a [j]> a [center_index] 일 때 오른쪽 j 개의 첨자가 왼쪽으로 가고, i와 j가 움직일 수 없으면 i <= j, a [i]와 a [j]를 교환하고 위의 과정에서 i> j까지 a [j]와 a [center_index]를 교환하여 빠른 정렬을 완료합니다.

중앙 요소가 a [j]로 교환되면 이전 요소의 안정성을 방해 할 가능성이 있으므로 quicksort는 불안정한 정렬 알고리즘이며, 중앙 요소가 a [j]와 교환하는 순간에 불안정성이 발생합니다.

예 : 정렬 할 배열 : int a [] = {1, 2, 2, 3, 4, 5, 6};

빠른 정렬의 비교기 (예 : 피벗) 단계의 무작위 선택에서 :

a [2] (즉, 배열의 두 번째 2)가 비교기로 선택되고 비교기보다 크거나 같은 숫자가 큰 숫자 배열에 배치되면 a [1] (즉, 배열의 처음 2 개)) 피벗의 오른쪽으로 이동하면 배열의 2 개 2 개가 원래 순서가 아닙니다 ( "불안정"함). a [1]이 비교기로 선택되고 비교기보다 작거나 같은 숫자가 십진 배열에 배치되면 배열의 두 2 차수가 원래 순서가 아닙니다.

 

코드 세그먼트 :

void quick_sort(int* arr,int left,int right)
{
	int i;
	if(left<right)
	{
		i=partition(arr,left,right);		//划分两个子区间(最左端-->枢纽元)
		quick_sort(arr,left,i-1);			//左区间递归快速排序
		quick_sort(arr,i+1,right);			//右区间递归快速排序
	}
}

int partition(int* arr,int left,int right)
{
	int base=arr[left];
	while(left<right)
	{
		//要有left<right!!!
		while( left<right&&arr[right]>base )//从右往左找出第一个比基准小的数据时退出while
		{
			right--;
		}
		arr[left]=arr[right];				//将这个数放到基准的左边
		while( left<right&&arr[left]<base )	//从左往右找出第一个比基准大的数据时退出while
		{
			left++;
		}
		arr[right]=arr[left];				//将这个数放到基准的右边
	}
	arr[left]=base;
	for(int h=0;h<SIZE;h++)
	{
		printf("%d ",arr[h]);
	}
	printf("一趟排序完成------------------\n");
	return left;							//返回基准的位置
}

 

추천

출처blog.csdn.net/u012906122/article/details/103593859