<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
歸併就是把兩個或多個序列合併,這裡只介紹二路歸併,就是不斷的把序列分為2組,直到每個組有一個元素為止,然後再比較合併,直到合為1個序列,完成。
與遞迴不斷分解陣列相反,非遞迴直接從長度為1的子序列開始合併,直到全併為1個整個序列,複用了merge函數
程式碼用非遞迴的方式效率更高一些:
空間複雜度:從O(log2n)變為1個臨時陣列O(n)
時間複雜度:少了遞迴的時間
O(nlogn)
#include <stdio.h> #include <stdbool.h> #define MAXSIZE 9 typedef struct { int r[MAXSIZE+1]; // first index used as tmp, not real data int len; }SqList; void swap(SqList *L, int i, int j) { int tmp = L->r[i]; L->r[i] = L->r[j]; L->r[j] = tmp; } void merge(int sr[], int tr[], int s, int m, int t) { // 本函數的任務就是比對sr中兩個分組(s..m, m+1..t)的元素大小並歸併到tr int j,k,l; j = m + 1; // 第2分組的起始位置 k = s; // k用於tr陣列中的遊標與sr中的起始位置對應起來 while (s<=m && j<=t) { if (sr[s] < sr[j]) { tr[k++] = sr[s++]; } else { tr[k++] = sr[j++]; } } // 只要是合併,就肯定至少是2個序列合併,肯定會在比對後剩下1個未消耗完元素的序列分組 while (s<=m) { tr[k++] = sr[s++]; } while (j<=t) { tr[k++] = sr[j++]; } } void msort(int sr[], int tr[], int s, int t) { /* * 把sr進行歸併排序並有序儲存到(歸併到)tr中 */ int m; int tmpr[MAXSIZE+1]; // 每層遞迴的臨時陣列,存放本次被呼叫時s到t歸併後的下標值(位置與首次傳入的L->r相同) if (s == t) { tr[s] = sr[s]; // 歸併的思想,1個元素的分組為有序 } else { // 不是1個元素的分組,繼續分組 m = (s+t)/2; msort(sr, tmpr, s, m); msort(sr, tmpr, m+1, t); // 合併tmpr到tr完成本層的排序任務 merge(tmpr, tr, s, m, t); } } void merge_sort(SqList *L) { msort(L->r, L->r, 1, L->len); // 因為在msort中第1個引數sr陣列只是讀取,所以這裡這樣傳遞沒有問題 } int main(void) { SqList list = { {999,50,10,90,30,70,40,80,60,20}, MAXSIZE }; merge_sort(&list); printf("after merge_sort:n"); for (int i=0; i<=MAXSIZE; i++) { printf("index: %d, value: %dn",i,list.r[i]); } return 0; }
output
➜ c gcc sort_merge.c&& ./a.out
after merge_sort:
index: 0, value: 999
index: 1, value: 10
index: 2, value: 20
index: 3, value: 30
index: 4, value: 40
index: 5, value: 50
index: 6, value: 60
index: 7, value: 70
index: 8, value: 80
index: 9, value: 90
#include <stdio.h> #include <stdbool.h> #include <stdlib.h> #define MAXSIZE 9 typedef struct { int r[MAXSIZE+1]; // first index used as tmp, not real data int len; }SqList; void merge(int sr[], int tr[], int s, int m, int t) { // 本函數的任務就是比對sr中兩個分組(s..m, m+1..t)的元素大小並歸併到tr int j,k,l; j = m + 1; // 第2分組的起始位置 k = s; // k用於tr陣列中的遊標與sr中的起始位置對應起來 while (s<=m && j<=t) { if (sr[s] < sr[j]) { tr[k++] = sr[s++]; } else { tr[k++] = sr[j++]; } } // 只要是合併,就肯定至少是2個序列合併,肯定會在比對後剩下1個未消耗完元素的序列分組 while (s<=m) { tr[k++] = sr[s++]; } while (j<=t) { tr[k++] = sr[j++]; } } void merge_pass(int sr[], int tr[], int k, int len) { int i=1; // 合併時的遊標 while (i < len-2*k+1) { // 也就是每次迴圈後,當前所剩餘的是否還夠2個完整子序列 merge(sr, tr, i, i+k-1, i+2*k-1); //合併本輪掃描到的2個子序列 i+=2*k; // 賦值後的i為下一輪2個子序列的起始位置 } // 下面是掃尾工作,**可能會**出現2種情況,a. 剩餘1~2個子序列之間的情況, b. 剩餘<=1個子序列的情況 if (i < len-k+1) { merge(sr, tr, i, i+k-1, len); } else { // 這裡加else也可以 如果上面i正好把序列消耗完,則迴圈不會執行 while (i<len) { tr[i] = sr[i]; i++; } } } void merge_sort(SqList *L) { int *tr = (int *)malloc(L->len*sizeof(int)); int k=1; /* * 迴圈k為序列長度,與遞迴的方式相比,正好反過來,非遞迴方式直接從序列為1開始合併,直到序列不小於待排序的陣列長度為止 * 每次迴圈都是子序列*4變長的過程 */ while (k<L->len) { merge_pass(L->r, tr, k, L->len); // 序列1變2 k++; merge_pass(tr, L->r, k, L->len); // 序列2變4 k++; } } int main(void) { SqList list = { {999,50,10,90,30,70,40,80,60,20}, MAXSIZE }; merge_sort(&list); printf("after merge_sort2:n"); for (int i=0; i<=MAXSIZE; i++) { printf("index: %d, value: %dn",i,list.r[i]); } return 0; }
output
➜ c gcc sort_merge_norecursive.c&& ./a.out
after merge_sort2:
index: 0, value: 999
index: 1, value: 10
index: 2, value: 20
index: 3, value: 30
index: 4, value: 40
index: 5, value: 50
index: 6, value: 60
index: 7, value: 70
index: 8, value: 80
index: 9, value: 90
到此這篇關於 c語言排序之歸併排序(遞迴和非遞迴)的文章就介紹到這了,更多相關 c語言排序內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45