정렬 - 사고방식 간략 분석 (一)
이 글 은 최근 에 배 운 정렬 알고리즘 을 정리 하여 그 사상 과 차이 점 을 추출 해 냈 다.병합 정렬, 빠 른 정렬, 쌓 기 정렬 및 거품 정렬 이 있 습 니 다.
정렬 병합 (Merging Sort)
두 개의 분해 와 병합 전략 을 사용 하여 간단 하고 실행 하기 쉬 우 며 이러한 병합 순 서 는 2 - 도로 병합 정렬 이 라 고 합 니 다.
병합 정렬 의 실현
다른 표기 법:
// a[i..m] a[m+1..n] b[i..n] n
void Merge(int a[], int i,int m, int n, int b[]){
int k,j;
for(k = i, j = m+1; k <= m && j <= n;k++){
if(a[i] < a[j]){
b[k] = a[i++];
}else{
b[k] = a[j++];
}
}
while(i<=m) b[k++] = a[i++];
while(j<=n) b[k++] = a[j++];
}
// i: ( 0)-- MSort a,b :
// i , a[s..t] b[s..t]
// b[s..t] a[s..t]
void MSort(int a[], int b[], int i,int s,int t){
int m;
if( s == t ){
if( 1 == i%2 ) b[s] = a[s];
}else{
m = (s+t)/2;
MSort(a,b,i+1,s,m);
MSort(a,b,i+1,m+1,t);
if( 1 == i%2 ) Merge(a,s,m,t,b);
else Merge(b,s,m,t,a);
}
}
void MergeSort(int a[],int len){
int b[len];
MSort(a,b,0,0,len-1);
free(b); //
}
간단 한 분석: 전체 병합 정렬 과정 은 전체 8968 ° logn * 8969 ° 층 의 재 귀 분해 와 병합 을 해 야 합 니 다. 이 를 통 해 정렬 된 알고리즘 시간 복잡 도 는 O (n * logn) 입 니 다.
병합 정렬 은 안정 적 인 정렬 입 니 다.
빠 른 정렬 (빠 른 정렬)
가장 간단 한 교환 정렬 은 거품 정렬 이 고 빠 른 정렬 은 거품 정렬 에 대한 개선 입 니 다.
먼저 대기 서열 에서 하나의 키 워드 를 선택 하여 추축 이 라 고 한다. 키워드 와 추축 의 비 교 를 통 해 대기 서열 을 추축 전후 에 있 는 두 개의 하위 서열 로 나눈다. 그 중에서 추축 전의 하위 서열 의 모든 키 워드 는 추축 보다 크 지 않 고 추축 뒤의 하위 서열 은 모두 추축 보다 작 지 않다. 이때 추축 이 이미 도착 했다.다시 같은 방법 에 따라 이 두 개의 하위 서열 을 각각 귀속 시 켜 빠 른 정렬 을 하여 최종 적 으로 전체 서열 을 질서 있 게 한다
빠 른 정렬 의 구체 적 인 과정:
// a[low..high] ,
// ,
int Partition(int a[],int low, int high){
a[0] = a[low];
while(low<high){
while(low < high && a[high] >= a[0]) high --;
a[low] = a[high];
while(low < high && a[low] <= a[0]) low++;
a[high] = a[low];
}
a[low] = a[0];
return low;
}
void QSort(int a[],int s,int t){
int pivotloc;
//
if( s<t ){
pivotloc = Partition(a,s,t);
// pivotloc
QSort(a,s,pivotloc-1);
QSort(a,pivotloc+1,t);
}
}
// a[1..len]
void QuickSort(int a[],int len){
QSort(a,1,len);
}
추축 키워드 가 가장 크 거나 가장 작은 상황 을 피하 기 위해 '삼자 취 중' 의 방법 을 사용 할 수 있다. 즉, a [s], a [t], a [(s + t) / 2] 삼자 중 키워드 의 크기 가 중심 에 있 는 기록 을 추축 으로 하고 a [s] 와 교환 할 수 있다.
쌓 기 정렬 의 기본 동작
더 미 는 완전 이 진 트 리 로 쌓 여 있 는 모든 비 잎 결점 이 좌우 부분 보다 크 지 않 으 면 작은 지붕 더미 라 고 부른다.만약 에 쌓 인 모든 비 잎 결점 이 좌우 부분 보다 작 지 않 으 면 큰 지붕 더미 라 고 부른다.
퇴적 구조 유형
typedef struct{
int *rcd; // ,0
int n; //
int size; //
int tag; //
int (*prior)(int a,int b); // ,
} Heap;
int greatPrior(int x,int y) { return x>=y; }
int lessPrior(int x,int y) { return x<=y; }
int SwapHeapElem(Heap &H,int i, int j){
if( i < 0 || i > H.n || j < 0 || j > H.n ) return 0;
int t;
t = H.rcd[i];
H.rcd[i] = H.rcd[j];
H.rcd[j] = t;
return 1;
}
// , pos , pos
void ShiftDown(Heap &H,int pos){
int c, rc;
while(pos<=H.n/2){
c = pos*2;
rc = pos*2+1;
if(rc<=H.n && H.prior(H.rcd[rc],H.rcd[c])) c = rc; //
if(H.prior(H.rcd[pos],H.rcd[c]))
return ;
SwapHeapElem(H,pos,c);
pos = c;
}
}
int RemoveFirsHeap(Heap &H, int &e){
if(H.n<=0) return 0;
e = H.rcd[1];
SwapHeapElem(H,1,H.n);
if(H.n>1) ShiftDown(H,1);
return 1;
}
void MakeHeap(Heap &H,int a[],int n,int size,int tag,int (*prior)(int a,int b)){
H.rcd = a;
H.n = n;
H.size = size;
H.tag = tag;
H.prior = prior;
int i;
// ,
for( i = H.n/2; i > 0; i -- ){
ShiftDown(H,i);
}
}
더미 정렬 (히트 정렬)
void HeapSort(int a[],int n){
Heap H;
MakeHeap(H,a,n,n+2,1,lessPrior);
int e;
for( int i = H.n; i > 0; i -- ){
if(RemoveFirsHeap(H,e) )
printf("%d ",e);
}
}
거품 정렬 (Bubble Sort)
void BubbleSort(int a[], int len){
int t;
int i, j;
// i
for( i = 0; i < len; i ++ ){
// len-i,len-i
for( j = 1; j < len-i; j ++ ){
if( a[j-1] < a[j] ){
t = a[j-1];
a[j-1] = a[j];
a[j] = t;
}
}
}
}
개선:
void BubbleSort(int a[], int len){
int t;
int i, j, flag;
flag = -1;
// i ,( )
// flag a[flag-1,flag..len-1] , flag
for( i = 0; i < len; i ++ ){
if( flag != -1 ){
i = len - flag; //
flag = -1;
}
for( j = 1; j < len-i; j ++ ){
if( a[j-1] > a[j] ){
flag = j;
t = a[j-1];
a[j-1] = a[j];
a[j] = t;
}
}
}
}
기타 학습 링크 거품 정렬 의 세 가지 실현
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
정수 반전Udemy 에서 공부 한 것을 중얼거린다 Chapter3【Integer Reversal】 (예) 문자열로 숫자를 반전 (toString, split, reverse, join) 인수의 수치 (n)가 0보다 위 또는 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.