데이터 구조 - 힐 정렬
힐 정렬 기본 사상
기본 사상:
n 보다 작은 정수 d1 을 첫 번 째 증분 으로 하고 파일 의 모든 기록 을 d1 그룹 으로 나 눕 니 다.모든 거 리 는 dl 의 배수 로 같은 그룹 에 기록 되 어 있 습 니 다.먼저 각 그룹 내 에서 직접 삽입 정렬 하기;그 다음 에 두 번 째 증 량 d2 < d1 을 취하 여 상기 그룹 과 정렬 을 반복 합 니 다. 취 하 는 증 량 dt = 1 (dt < dt - l <... < d2 < d1), 즉 모든 기록 을 같은 그룹 에 놓 고 정렬 을 직접 삽입 할 때 까지 합 니 다.
이 방법 은 실질 적 으로 그룹 삽입 방법 이다.
주어진 인 스 턴 스 셸 정렬 과정
정렬 대기 파일 에 10 개의 기록 이 있다 고 가정 하면 키 워드 는 다음 과 같 습 니 다.
49,38,65,97,76,13,27,49,55,04。
증분 시퀀스 의 값 은 다음 과 같 습 니 다.
5,3,1
정렬 과정 은 [애니메이션 시 뮬 레이 션] 과 같 습 니 다.
Shell 정렬 알고리즘 구현
1. 감시초 소 를 설치 하지 않 은 알고리즘 설명
void ShellPass(SeqList R,int d)
{// ,d
for(i=d+1;i<=n;i++) // R[d+1..n]
if(R[i].key<R[i-d].key){
R[0]=R[i];j=i-d; //R[0] ,
do {// R[i]
R[j+d];=R[j]; //
j=j-d; //
}while(j>0&&R[0].key<R[j].key);
R[j+d]=R[0]; // R[i]
} //endif
} //ShellPass
void ShellSort(SeqList R)
{
int increment=n; // , n>0
do {
increment=increment/3+1; //
ShellPass(R,increment); // increment Shell
}while(increment>1)
} //ShellSort
주의:증 량 d = 1 시 셸 패스 와 인 서 트 소 트 는 기본적으로 일치 하지만 보초병 이 없어 서 내 순환 에 순환 판정 조건 인 'j > 0' 을 추가 하여 아래 표 가 경 계 를 넘 지 않도록 한다.
2. 감시초 소 를 설치 한 셸 정렬 알고리즘
구체 적 인 알고리즘 [참고서 목록 [12]]
알고리즘 분석
1. 증분 시퀀스 선택
셸 정렬 의 실행 시간 은 증분 시퀀스 에 의존 합 니 다.
좋 은 증분 시퀀스 의 공 통 된 특징:
① 마지막 증 가 는 1 이 어야 한다.
② 서열 중의 값 (특히 인접 한 값) 이 서로 배수 가 되 는 상황 을 피해 야 한다.
어떤 사람 은 대량의 실험 을 통 해 현재 비교적 좋 은 결 과 를 제시 했다. n 이 비교적 클 때 비교 와 이동 횟수 는 약 nl. 25 에서 1.6n. 25 사이 이다.
2. Shell 정렬 의 시간 성능 은 정렬 을 직접 삽입 하 는 것 보다 좋 습 니 다.
힐 정렬 의 시간 성능 이 정렬 을 직접 삽입 하 는 것 보다 좋 은 이유:
① 파일 의 초기 상태 가 기본적으로 질서 가 있 을 때 정렬 을 직접 삽입 하 는 데 필요 한 비교 와 이동 횟수 가 비교적 적다.
② n 값 이 시간 에 비해 n 과 n2 의 차이 도 비교적 적다. 즉, 정렬 을 직접 삽입 하 는 가장 좋 은 시간 복잡 도 O (n) 와 최 악의 시간 복잡 도 0 (n2) 의 차이 가 크 지 않다.
③ 힐 정렬 을 시작 할 때 증 가 량 이 많 고 그룹 이 많 으 며 각 그룹의 기록 수량 이 적 기 때문에 각 그룹 에 직접 삽입 하 는 것 이 빠 르 고 나중에 증 가 된 di 가 점점 줄 어 들 며 그룹 수 는 점점 줄 어 들 었 으 며 각 그룹의 기록 수량 은 점점 증가 했다. 그러나 di - 1 을 거리 로 배열 하여 파일 이 질서 있 는 상태 에 가 까 워 졌 기 때문에 새로운 정렬 과정 도 비교적 빠르다.
따라서 힐 의 순 서 는 효율 적 으로 직접 삽입 하 는 것 보다 개선 되 었 다.
3. 안정성
힐 의 순 서 는 불안정 하 다.상기 사례 를 참조 하여 이 예 에서 두 개의 같은 키워드 49 는 정렬 전후의 상대 적 인 순서 에 변화 가 생 겼 다.
알고리즘 프로그램
void shellsort(int n,int a[])
//
//
// n d1 ,
// d1 。
// dl 。
// ; ,
// d2<d1 ,
// dt=1(dt<dt-l<…<d2<d1), 。
// 。
// (n*logn)
{
int t=0,s=1,d,i,k,m,x,j;
while(s<n)
{
t++;
s=s*2;
}
d=(n+1)/2;
for(m=1;m<=t;m++)// t
{
k=d;
for(i=k;i<n;i++)//
{
x=a[i];
j=i-k;
while((x<a[j])&&(j>=0))//
{
a[j+k]=a[j];
j=j-k;
}
a[j+k]=x;
}
d=d/2;
}
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 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에 따라 라이센스가 부여됩니다.