데이터 구조 학습 - 셸 정렬 의 C 언어 구현
12704 단어 shell
p, li { white-space: pre-wrap; }
-->
셸 정렬:
이 정렬 의 이름 은 발명자 의 이름 으로 정렬 하 는 방법 과 글자 상의 관계 가 없다.그 러 니까 이름 때문에 어려워 하지 마.K & R 의 C 프로 그래 밍 언어 에서 책 은 몇 줄 의 코드 만 사용 하여 이 정렬 알고리즘 을 간결 하 게 실현 했다.그럼 이 정렬 이 어떻게 이 루어 졌 는 지 살 펴 보 자.
<!--
p, li { white-space: pre-wrap; }
-->
원리:
우 리 는 정렬 할 서열 (크기 는 n) 을 그룹 으로 나 눌 것 입 니 다. 그룹의 수량 은 보통 이 서열 의 크기 의 절반 으로 정의 할 수 있 습 니 다 (즉 d = n/2). 그리고 계속 반 으로 접 을 수 있 습 니 다. 그룹의 구성원 은 간격 이 d 인 수 를 한 그룹 으로 나 눌 수 있 습 니 다.예 를 들 어 여기 길이 가 8 인 숫자 서열 이 정렬 되 어야 한다 면 우 리 는 먼저 이 서열 을 d = 4 조로 나 눌 수 있다. 각 조 는 두 개의 숫자 가 있다. (이쪽 의 4 는 8 의 절반 이다.)이 네 조 는 (R1, R5), (R2, R6), (R3, R7), (R4, R8) 입 니 다. 그 다음 에 그룹 내 비교 입 니 다. 전자 가 크 면 그들의 위 치 를 교환 합 니 다.차례로 유추 하 다.프로그램 을 작성 할 때 우리 가 가 진 수 와 그 와 d 크기 의 위 치 를 비교 하 는 것 입 니 다.여기 서 첫 번 째 조 의 수 는 4 이다. 그러면 첫 번 째 수 와 그 사이 의 간격 을 4 로 비교 하 는 것 이다.첫 번 째 정렬 후에 우 리 는 이 간격 을 줄 이 는 것 은 바로 이전 그룹의 d 를 반 으로 접 는 것 이다.그럼 이번 팀 은 2 개 밖 에 없어 요.각 조 는 4 개의 수가 있 습 니 다. 똑 같이 위 와 같 습 니 다. 간격 이 d = 2 인 위치 상의 수 를 비교 합 니 다. (실제로 조작 은 이 렇 지만 우 리 는 그들 이 이미 한 조 안에 있다 고 생각 할 수 있 습 니 다. 그룹 내 비교 라 고 할 수 있 습 니 다)우 리 는 d 가 마지막 에 1 이 될 것 이라는 것 을 알 고 있다. 그 때 는 인접 한 두 개의 수 를 비교 하고 모든 숫자 는 정확 한 위치 에 놓 일 것 이다.원 리 는 기본적으로 이렇다.
<!--
p, li { white-space: pre-wrap; }
-->
실현:
우 리 는 원 리 를 알 게 되 었 습 니 다. 그러면 익숙 한 언어 로 작성 하 세 요. 우 리 는 C 언어 로 작 성 했 습 니 다.
<!--
p, li { white-space: pre-wrap; }
-->
우 리 는 상술 한 원리 에 따라 그것 을 한 걸음 한 걸음 실현 한다.
1 //函数的参数包含两个,一个是要排序的数组,一个是数组的大小
2 //函数不使用额外的空间,只用到数组本身。这就要求数组在输入时候保留出
3 //R[0],R[0]就相当是一个temp。用于互换两个数时的一个临时数。
4 void shellsort(int R[],int n)
5 {
6 int i,j,d;
7 d = n/2;
8 while(d >= 1)
9 {
10 //注意i的起始和最后的那个“=,我们的第一个数是R[1],所以i-d要从1开始
11 for(i = d + 1;i <= n;i++)
12 {
13 j = i - d;
14 //将R[i]暂存
15 R[0] = R[i];
16 //这边的R[0]就是R[j+d]也就是R[i]
17 while(j>0 && R[j] > R[0])
18 {
19 //将j位置的值给j+d位置
20 R[j+d] = R[j];
21 j -= d;
22 }
23 //这边就是对应着上面的j-=d,如果上面的while执行了,j
24 //位置的值已经给了j+d位置了,那么j+d的值也要给j位置,互换
25 //这就要求下标必须是对应的。所以要将j-d才能满足这边是R[j]
26 //如果while没有执行,那么还将原来的R[i]的值放到原来位置上
27 R[j+d] = R[0];
28 }
29 //d减半
30 d/=2;
31 }
32 }
위 에서 말 한 원리 에 따라 이 루어 진 것 입 니 다. 코드 도 많 지 않 지만 좀 어 지 러 워 보 입 니 다. 그럼 개선 할 수 있 을까요?다음 에 오 네.
<!--
p, li { white-space: pre-wrap; }
-->
간소화:
우 리 는 일반적으로 프로그램의 읽 을 수 있 도록 프로그램 을 정교 하 게 만든다.이것 도 K & R 의 한 사상 이 죠.우 리 는 while 와 for 가 일정한 상황 에서 대체 할 수 있다 는 것 을 안다.그래서 우 리 는 상술 한 절 차 를 더욱 치밀 하 게 만 들 수 있다. 우 리 는 세 개의 for 순환 을 사용 하면 된다.다음은 간소화 후의 실현 이다.
1 #include<stdio.h>
2
3 #define N 100
4 void shellsort(int *,int);
5
6 int main(void)
7 {
8 int v[N];
9 int n,i;
10
11 printf("输入你数组的大小:");
12 scanf("%d",&n);
13
14 printf("输入%d个数,空格隔开:
",n);
15 for(i = 0;i < n; i++)
16 {
17 scanf("%d",&v[i]);
18 }
19
20 shellsort(v,n);
21
22 printf("shell排序后:");
23 for(i =0;i < n;i++)
24 {
25 printf("%3d",v[i]);
26 }
27
28 printf("
");
29 return 0;
30 }
31
32 void shellsort(int v[],int n)
33 {
34 int i,j,temp,gap;
35
36 for(gap = n/2;gap > 0;gap /=2)
37 for(i =gap ;i < n ;i++)
38 for(j = i - gap;j>=0 && v[j] >v[j+gap]; j-=gap)
39 {
40 temp = v[j];
41 v[j] = v[j+gap];
42 v[j+gap] = temp;
43 }
44 }
<!--
p, li { white-space: pre-wrap; }
-->
여기 서 나 는 완전한 프로그램 을 제 시 했 지만, 우 리 는 함수 의 실현 만 을 보 았 다.위의 함수 에서 첫 번 째 for 순환 은 비교 수 간 의 간격 을 제어 하 는 것 이 고 그룹의 근거 라 고 할 수 있 습 니 다.중간의 순환 은 원소 의 이동 위 치 를 제어 하 는 것 이다.마지막 순환 은 그룹 내 비교 이 며 순서 가 맞지 않 으 면 위 치 를 바 꾸 는 것 이다.첫 번 째 함수 에 있 는 while 를 for 로 통합 하면 프로그램 이 간단 해 보 입 니 다. 우 리 는 이해 에 있어 서 약간 막 힐 수 있 습 니 다. while 와 for 사이 의 전환 에 익숙 하면 많이 좋아 질 것 입 니 다.
보충:
for (표현 식 1; 표현 식 2; 표현 식 3)
문장
while 와 같은 값 은:
표현 식 1;
while (표현 식 2)
{
문장
표현 식 3;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
ZSH에서 물고기까지ZSH는 수년 동안 내 기본 셸이었습니다. 이제 몇 달 동안 사용하면서 ZSH 구성에 대해 몇 가지 사항을 발견했습니다. 우리는 을 제공하는 시스템과 더 빨리 상호 작용하는 경향이 있습니다. 내.zshrc 구성에는 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.