7 2 C void select int data int

  • Slides: 79
Download presentation

7 -2 內部排序法 • 選擇排序法的C演算法 void select (int data[]) { int i, j, tmp,

7 -2 內部排序法 • 選擇排序法的C演算法 void select (int data[]) { int i, j, tmp, k; for(i=0; i<n; i++) /*掃描n次*/ { for(j=i+1; j<n+1; j++) /*由i+1比較起,比較n次*/ { if(data[i]>data[j]) /*比較第i及第j個元素*/ { tmp=data[i]; data[i]=data[j]; data[j]=tmp; } } } printf("n"); } 19

#include <stdio. h> #include <stdlib. h> void select (int *); /*宣告排序法副程序*/ void showdata (int

#include <stdio. h> #include <stdlib. h> void select (int *); /*宣告排序法副程序*/ void showdata (int *); /*宣告列印陣列副程序*/ int main() { int data[8]={16, 25, 39, 27, 12, 8, 45, 63}; printf("原始資料為:"); int i; for (i=0; i<8; i++) printf("%3 d", data[i]); 16, 25, 39, 27, 12, 8, 45, 63 printf("n-------------------"); select (data); printf("排序後資料:"); for (i=0; i<8; i++) printf("%3 d", data[i]); printf("n"); system("pause"); return 0; } void showdata (int data[]) { int i; for (i=0; i<8; i++) 7 -2 內部排序法 • 範例 7. 2. 3 – 請設計一C程式,並使用選擇排序法來將以下的 數列排序: 21

printf("%3 d", data[i]); printf("n"); } void select (int data[]) { int i, j, tmp,

printf("%3 d", data[i]); printf("n"); } void select (int data[]) { int i, j, tmp, k; for(i=0; i<7; i++) /*掃描 5次*/ { for(j=i+1; j<8; j++) /*由i+1比較起,比較5次*/ { if(data[i]>data[j]) /*比較第i及第j個元素*/ { tmp=data[i]; data[i]=data[j]; data[j]=tmp; } } } printf("n"); } 7 -2 內部排序法 22

#include <stdio. h> #include <stdlib. h> #define SIZE 8 /*定義陣列大小*/ void inser (int *);

#include <stdio. h> #include <stdlib. h> #define SIZE 8 /*定義陣列大小*/ void inser (int *); /*宣告插入排序法副程式*/ void showdata (int *); /*宣告列印陣列副程式*/ int main() { int data[SIZE]={16, 25, 39, 27, 12, 8, 45, 63}; printf("原始陣列是:"); showdata(data); printf("n"); 16, 25, 39, 27, 12, 8, 45, 63 inser(data); printf("排序後陣列是:"); showdata(data); system("pause"); return 0; } void showdata(int data[]) { int i; for (i=0; i<SIZE; i++) printf("%3 d", data[i]); /*列印陣列資料*/ printf("n"); } 7 -2 內部排序法 • 範例 7. 2. 4 – 請設計一C程式,並使用選擇排序法來將以下的 數列排序: 26

7 -2 內部排序法 while (jmp != 0) { } } for (i=jmp ; i<size

7 -2 內部排序法 while (jmp != 0) { } } for (i=jmp ; i<size ; i++) { tmp=data[i]; j=i-jmp; while(tmp<data[j] && j>=0) /*插入排序法*/ { data[j+jmp] = data[j]; j=j-jmp; } data[jmp+j]=tmp; } jmp=jmp/2; /*控制迴圈數*/ 31

#include <stdio. h> #include <stdlib. h> #define SIZE 8 void shell (int *, int);

#include <stdio. h> #include <stdlib. h> #define SIZE 8 void shell (int *, int); /*宣告排序法副程式*/ void showdata (int *); /*宣告列印陣列副程式*/ int main(void) { int data[SIZE]={16, 25, 39, 27, 12, 8, 45, 63}; printf("原始陣列是: "); showdata (data); printf("---------------------n"); 16, 25, 39, 27, 12, 8, 45, 63 shell(data, SIZE); system("pause"); return 0; } void showdata(int data[]) { int i; for (i=0; i<SIZE; i++) printf("%3 d", data[i]); printf("n"); } void shell(int data[], int size) { 7 -2 內部排序法 • 範例 7. 2. 5 – 請設計一C程式,並使用謝耳排序法來將以下的 數列排序: 32

7 -2 內部排序法 • 快速排序法的C演算法 void quick(int d[], int size, int lf, int rg)

7 -2 內部排序法 • 快速排序法的C演算法 void quick(int d[], int size, int lf, int rg) { int i, j, tmp; int lf_idx; int rg_idx; int t; /*1: 第一筆鍵值為d[lf]*/ if(lf<rg) { lf_idx=lf+1; rg_idx=rg; step 2: printf("[處理過程%d]=> ", process++); for(t=0; t<size; t++) printf("[%2 d] ", d[t]); printf("n"); for(i=lf+1; i<=rg; i++) /*2: 由左向右找出一個鍵值大於d[lf]者*/ { if(d[i]>=d[lf]) { lf_idx=i; break; } 39

7 -2 內部排序法 lf_idx++; } for(j=rg; j>=lf+1; j--) /*3: 由右向左找出一個鍵� 小於d[lf]者*/ { if(d[j]<=d[lf]) {

7 -2 內部排序法 lf_idx++; } for(j=rg; j>=lf+1; j--) /*3: 由右向左找出一個鍵� 小於d[lf]者*/ { if(d[j]<=d[lf]) { rg_idx=j; break; } rg_idx--; } if(lf_idx<rg_idx) /*4 -1: 若lf_idx<rg_idx*/ { /*則d[lf_idx]和d[rg_idx]互換*/ tmp = d[lf_idx]; d[lf_idx] = d[rg_idx]; d[rg_idx] = tmp; goto step 2; /*4 -2: 並繼續執行步驟 2*/ } if(lf_idx>=rg_idx) /*5 -1: 若lf_idx大於等於rg_idx*/ { /*則將d[lf]和d[rg_idx]互換*/ tmp = d[lf]; d[lf] = d[rg_idx]; d[rg_idx] = tmp; /*5 -2: 並以rg_idx為基準點分成左右兩半*/ quick(d, size, lf, rg_idx-1); /*以遞迴方式分別為左 右兩半進行排序*/ quick(d, size, rg_idx+1, rg); /*直至完成排序*/ } } } 40

#include <stdio. h> #include <stdlib. h> #include <time. h> void inputarr(int*, int); void showdata(int*,

#include <stdio. h> #include <stdlib. h> #include <time. h> void inputarr(int*, int); void showdata(int*, int); void quick(int*, int, int); int process = 0; int main(void) { int size, data[100]={0}; srand((unsigned)time(NULL)); printf("請輸入陣列大小(100以下):"); scanf("%d", &size); printf("您輸入的原始資料是:"); inputarr (data, size); showdata (data, size); quick(data, size, 0, 9); printf("n排序結果:"); showdata(data, size); system("pause"); return 0; } void inputarr(int data[], int size) { int i; 7 -2 內部排序法 • 範例 7. 2. 6 – 請設計一C程式,並使用快速排序法將數字排序。 41

for (i=0; i<size; i++) data[i]=(rand()%99)+1; 7 -2 內部排序法 } void showdata(int data[], int size)

for (i=0; i<size; i++) data[i]=(rand()%99)+1; 7 -2 內部排序法 } void showdata(int data[], int size) { int i; for (i=0; i<size; i++) printf("%3 d", data[i]); printf("n"); } void quick(int d[], int size, int lf, int rg) { int i, j, tmp; int lf_idx; int rg_idx; int t; /*1: 第一筆鍵值為d[lf]*/ if(lf<rg) { lf_idx=lf+1; rg_idx=rg; step 2: printf("[處理過程%d]=> ", process++); for(t=0; t<size; t++) printf("[%2 d] ", d[t]); 42

printf("n"); for(i=lf+1; i<=rg; i++) 7 -2 內部排序法 { /*2: 由左向右找出一個鍵值大於d[lf]者*/ if(d[i]>=d[lf]) { lf_idx=i; break;

printf("n"); for(i=lf+1; i<=rg; i++) 7 -2 內部排序法 { /*2: 由左向右找出一個鍵值大於d[lf]者*/ if(d[i]>=d[lf]) { lf_idx=i; break; } lf_idx++; } for(j=rg; j>=lf+1; j--) /*3: 由右向左找出一個鍵值小於d[lf]者*/ { if(d[j]<=d[lf]) { rg_idx=j; break; } rg_idx--; } if(lf_idx<rg_idx) /*4 -1: 若lf_idx<rg_idx*/ { /*則d[lf_idx]和d[rg_idx]互換*/ tmp = d[lf_idx]; d[lf_idx] = d[rg_idx]; d[rg_idx] = tmp; 43

7 -2 內部排序法 printf("[%2 d] ", data[i]); printf("n"); for(i=size-2; i>0; i--)/*堆積排序*/ { tmp=data[i+1]; /*頭尾節點交換*/

7 -2 內部排序法 printf("[%2 d] ", data[i]); printf("n"); for(i=size-2; i>0; i--)/*堆積排序*/ { tmp=data[i+1]; /*頭尾節點交換*/ data[i+1]=data[1]; data[1]=tmp; ad_heap(data, 1, i); /*處理剩餘節點*/ printf("n處理過程:"); for(j=1; j<size; j++) printf("[%2 d] ", data[j]); } } void ad_heap(int *data, int i, int size) { int j, tmp, post; j=2*i; tmp=data[i]; post=0; while(j<=size && post==0) { if(j<size) { 50

#include <stdio. h> void heap(int*, int); void ad_heap(int*, int); int main(void) { int i,

#include <stdio. h> void heap(int*, int); void ad_heap(int*, int); int main(void) { int i, size, data[9]={0, 5, 6, 4, 8, 3, 2, 7, 1}; /*原始陣列內容*/ size=9; printf("原始陣列:"); for(i=1; i<size; i++) printf("[%2 d] ", data[i]); heap(data, size); /*建立堆積樹*/ printf("n排序結果:"); for(i=1; i<size; i++) printf("[%2 d] ", data[i]); printf("n"); system("pause"); return 0; } void heap(int *data, int size) { int i, j, tmp; for(i=(size/2); i>0; i--) /*建立堆積樹節點*/ ad_heap(data, i, size-1); printf("n堆積內容:"); for(i=1; i<size; i++) /*原始堆積樹內容*/ 7 -2 內部排序法 • 範例 7. 2. 7 – 請設計一C程式,並使用堆積排序法來排序。 52

printf("[%2 d] ", data[i]); printf("n"); for(i=size-2; i>0; i--)/*堆積排序*/ { tmp=data[i+1]; /*頭尾節點交換*/ data[i+1]=data[1]; data[1]=tmp; ad_heap(data,

printf("[%2 d] ", data[i]); printf("n"); for(i=size-2; i>0; i--)/*堆積排序*/ { tmp=data[i+1]; /*頭尾節點交換*/ data[i+1]=data[1]; data[1]=tmp; ad_heap(data, 1, i); /*處理剩餘節點*/ printf("n處理過程:"); for(j=1; j<size; j++) printf("[%2 d] ", data[j]); } 7 -2 內部排序法 } void ad_heap(int *data, int i, int size) { int j, tmp, post; j=2*i; tmp=data[i]; post=0; while(j<=size && post==0) { if(j<size) { if(data[j]<data[j+1])/*找出最大節點*/ j++; 53

/* 基數排序法 由小到大排序 */ #include <stdio. h> #include <stdlib. h> #include <time. h> void

/* 基數排序法 由小到大排序 */ #include <stdio. h> #include <stdlib. h> #include <time. h> void radix (int *, int); /* 基數排序法副程式 */ void showdata (int *, int); void inputarr (int *, int); int main(void) { int size, data[100]={0}; printf("請輸入陣列大小(100以下):"); scanf("%d", &size); printf("您輸入的原始資料是:n"); inputarr (data, size); showdata (data, size); radix (data, size); system("pause"); return 0; } void inputarr(int data[], int size) { int i; srand((unsigned)time(NULL)); for (i=0; i<size; i++) data[i]=(rand()%999)+1; /*設定data值最大為 3位數*/ 7 -2 內部排序法 • 範例 7. 2. 8 – 請設計一C程式,並使用基數排序法來排序。 60

n 2=getc(fp 2); if(feof(fp 2)) break; putc(n 2, fp); 7 -3 外部排序法 } }

n 2=getc(fp 2); if(feof(fp 2)) break; putc(n 2, fp); 7 -3 外部排序法 } } else if (feof(fp 2)) { putc(n 1, fp); while(feof(fp 1)) { n 1=getc(fp 1); putc(n 1, fp); } } } int main(void) { char n; FILE *fp=fopen("data. txt", "w+"); /*宣告、並開啟建立新檔主檔指標 fp*/ FILE *fp 1=fopen("data 1. txt", "r"); /*宣告資料檔 1指標 fp 1*/ FILE *fp 2=fopen("data 2. txt", "r"); /*宣告資料檔 2指標 fp 2*/ FILE *f, *f 1, *f 2; if(fp==NULL) printf("開啟主檔失敗n"); else if(fp 1==NULL) 67

printf("開啟資料檔 1 失敗n"); /*開啟檔案成功時,指標會傳回FILE檔案*/ else if(fp 2==NULL)/*指標,開啟失敗則傳回NULL值*/ printf("開啟資料檔 2 失敗n"); else { printf("資料排序中. .

printf("開啟資料檔 1 失敗n"); /*開啟檔案成功時,指標會傳回FILE檔案*/ else if(fp 2==NULL)/*指標,開啟失敗則傳回NULL值*/ printf("開啟資料檔 2 失敗n"); else { printf("資料排序中. . . n"); merge(fp, fp 1, fp 2); printf("資料處理完成!!n"); } fclose(fp); /*關閉檔案*/ fclose(fp 1); fclose(fp 2); printf("data 1. txt資料內容為:n"); f 1=fopen("data 1. txt", "r"); while(1) { n=getc(f 1); if(feof(f 1)) break; printf("[%c] ", n); } printf("n"); printf("data 2. txt資料內容為:n"); f 2=fopen("data 2. txt", "r"); while(1) { 7 -3 外部排序法 68

n=getc(f 2); if(feof(f 2)) break; printf("[%c] ", n); } printf("n"); printf("排序後data. txt資料內容為:n"); f=fopen("data. txt",

n=getc(f 2); if(feof(f 2)) break; printf("[%c] ", n); } printf("n"); printf("排序後data. txt資料內容為:n"); f=fopen("data. txt", "r"); while(1) { n=getc(f); if(feof(f)) break; printf("[%c] ", n); } printf("n"); fclose(f); /*關閉檔案*/ fclose(f 1); fclose(f 2); system("pause"); return 0; 7 -3 外部排序法 } 69

printf("檔案排序中. . . n"); printf("資料處理完成!!n"); } rewind(fp); /*重設各檔案指標*/ rewind(fp 1); rewind(ff 2); /*列印檔案內容*/ printf("原始檔datafile.

printf("檔案排序中. . . n"); printf("資料處理完成!!n"); } rewind(fp); /*重設各檔案指標*/ rewind(fp 1); rewind(ff 2); /*列印檔案內容*/ printf("原始檔datafile. txt資料內容為:n"); showdata(fp); printf("n分割檔sort 1. txt資料內容為:n"); showdata(ff 1); printf("n分割檔sort 2. txt資料內容為:n"); showdata(ff 2); printf("n排序後sortdata. txt資料內容為:n"); showdata(fp 1); fclose(fp); /*關閉檔案*/ fclose(fp 1); fclose(ff 2); system("pause"); return 0; 7 -3 外部排序法 } void me(FILE *fp, FILE *fp 1, FILE *ff 2) { 71

int n 1=0, n 2=0; char da 1, da 2; while(1) { da 1=getc(fp);

int n 1=0, n 2=0; char da 1, da 2; while(1) { da 1=getc(fp); if(feof(fp)) break; n 1++; /*計數,n 1為datafile的總筆數*/ } rewind(fp); for(n 2=0; n 2<(n 1/2); n 2++) { da 2=getc(fp); /*把一半的檔案*/ putc(da 2, ff 1); /*分割到ff 1去*/ } rewind(ff 1); bubble(ff 1, n 2); /*分割完後呼叫bubble副程式進行排序*/ while(1) { da 2=getc(fp); /*把其他的datafile檔案*/ if(feof(fp)) break; putc(da 2, ff 2); /*內容分割到ff 2去*/ } rewind(ff 2); bubble(ff 2, (n 1/2)); /*分割完後呼叫bubble副程式進行排序*/ rewind(ff 1); 7 -3 外部排序法 72

{ n 2=getc(fp 2); 7 -3 外部排序法 if(feof(fp 2)) break; putc(n 2, fp); }

{ n 2=getc(fp 2); 7 -3 外部排序法 if(feof(fp 2)) break; putc(n 2, fp); } } else if (feof(fp 2)) { putc(n 1, fp); while (feof(fp 1)) { n 1=getc(fp 1); putc(n 1, fp); } } } void bubble (FILE *ff, int size) { int ii=0, j, i, tmp, flag; char n; char data[100]={0}; for(i=0; i<size; i++) { n=getc(ff); if(feof(ff)) break; data[i]=n; ii++; 74

} for(i=size; i>0; i--) { flag=0; /*flag用來判斷是否有執行交換的動作*/ for (j=0; j<i; j++) { if(data[j+1]<data[j]) {

} for(i=size; i>0; i--) { flag=0; /*flag用來判斷是否有執行交換的動作*/ for (j=0; j<i; j++) { if(data[j+1]<data[j]) { tmp=data[j]; data[j]=data[j+1]; data[j+1]=tmp; flag++; }/*如果有執行過交換,則flag不為 0*/ } if(flag==0)break; } rewind(ff); for(i=1; i<=size; i++) putc(data[i], ff); 7 -3 外部排序法 } void showdata (FILE *ff) { char n; while(1) { n=getc(ff); if(feof(ff)) break; printf("[%c]", n); } printf("n"); } 75