要說排序算法里面比較簡單的,我覺得直接插入排序算是一個(gè)。
直接插入排序的原理很簡單,就是把一個(gè)數(shù)字插入到一個(gè)有序的數(shù)組中。
比如有這么一個(gè)數(shù)組:
1,3,5,7然后要把 4 插進(jìn)去。
過程不難,4跟 7 比,7大,把 7 往后移動(dòng);
4跟 5 比,5大,把 5 往后移動(dòng);
4跟 3 比,3小,于是直接把4放到第三個(gè)位置上。
但是問題又來了,去哪找一個(gè)有序的數(shù)組,排序本來就是沒有順序的。
于是就有了一個(gè)理論,如果一個(gè)數(shù)組中只有一個(gè)元素,那么它一定是有序的。
比如有這么一個(gè)數(shù)組:
6 4 5 3 7先把 6 當(dāng)作一個(gè)單獨(dú)的數(shù)組,那么它一定是有序的。
把 4 插入到這個(gè)有序的數(shù)組中,先把 4 記下來,4跟 6 比,6向后移動(dòng),然后把 4 放到第一個(gè)位置。
4 6 5 3 7接下來再把 5 插入到4 6這個(gè)有序的數(shù)組中,過程一樣。
4 5 6 3 7循環(huán)下去,最終一定會(huì)得到一個(gè)有序的數(shù)組。
代碼也不難。
#include直接插入排序的效率很低,基本上跟冒泡是一個(gè)級(jí)別。 問題就出在移動(dòng)的次數(shù)太多。#include #include #define SIZE 100000 void insert_sort(int *a, int size) { int i, j, num; for (i = 1; i < size; i++) { num = a[i]; for (j = i - 1; j >= 0; j--) { if (num < a[j]) { a[j + 1] = a[j]; } else { break; } } a[j + 1] = num; } } int main() { int num, arr[SIZE] = {0}, i; //隨機(jī)產(chǎn)生數(shù)組 srand(time(NULL)); for (i = 0; i < SIZE; i++) { arr[i] = rand() % 100; } insert_sort(arr, SIZE); for (i = 0; i < SIZE; i++) { printf("%d ", arr[i]); } printf(" "); return 0; }
6 4 5 3 7比如 3 這個(gè)元素,最終應(yīng)該放在 6 這個(gè)位置上,但是這個(gè)過程需要跟每個(gè)數(shù)字比較并且向后移動(dòng)。
于是有個(gè)叫做希爾的人就提出了改進(jìn)思路,如果能讓 3 跳著來,速度就會(huì)提高很多。
后來就有了希爾排序。
第一步,先選取 2 作為步長,就是長度的一半,把原數(shù)組分成了兩個(gè)數(shù)組,一個(gè)是6 5 7,一個(gè)是4 3,對(duì)這兩個(gè)數(shù)組分別做直接插入排序。
6 5 7 4 3你會(huì)發(fā)現(xiàn),這一次 3 直接和 4 交換了位置,一下子跳了兩步。
第二步,步長再縮減一半,就是1。
其實(shí)就是對(duì)整個(gè)數(shù)組做直接插入排序。
有些同學(xué)可能會(huì)有疑問,既然最終也是對(duì)整個(gè)數(shù)組做直接插入排序,為什么不一開始就這樣?
隨著步長的逐漸的縮減,數(shù)組會(huì)變得基本有序,雖然最后一步也是直接插入排序,但是移動(dòng)的元素會(huì)很少。
希爾排序的效率要比直接插入排序高很多。
代碼也只需要做簡單的修改。
#include最后來試下 5 萬個(gè)數(shù)據(jù)排序,兩者的差距肉眼可見。#include #include #define SIZE 100000 void shell_sort(int *a, int size) { int i, j, num, h; for (h = size / 2; h > 0; h /= 2) { for (i = h; i < size; i++) { num = a[i]; for (j = i - h; j >= 0; j = j - h) { if (num < a[j]) { a[j + h] = a[j]; } else { break; } } a[j + h] = num; } } } int main() { int num, arr[SIZE] = {0}, i; //隨機(jī)產(chǎn)生數(shù)組 srand(time(NULL)); for (i = 0; i < SIZE; i++) { arr[i] = rand() % 100; } shell_sort(arr, SIZE); for (i = 0; i < SIZE; i++) { printf("%d ", arr[i]); } printf(" "); return 0; }
root@Turbo:test# time ./insert_sort real 0m1.740s user 0m1.724s sys 0m0.000s root@Turbo:test# time ./shell_sort real 0m0.008s user 0m0.004s sys 0m0.004s root@Turbo:test#
審核編輯:劉清
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。
舉報(bào)投訴
-
printf函數(shù)
+關(guān)注
關(guān)注
0文章
31瀏覽量
5880 -
Printf
+關(guān)注
關(guān)注
0文章
81瀏覽量
13625
原文標(biāo)題:2分鐘看懂直接插入排序和希爾排序
文章出處:【微信號(hào):學(xué)益得智能硬件,微信公眾號(hào):學(xué)益得智能硬件】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
手把手教你排序算法怎么寫
今天以直接插入排序算法,給大家分享一下排序算法的實(shí)現(xiàn)思路,主要包含以下部分內(nèi)容:插入排序介紹插入排序算法實(shí)現(xiàn)手把手教你排序算法怎么寫在添加新
十種常用排序法詳解總結(jié)和比較選擇
,并且不會(huì)出現(xiàn)快速排序可能出現(xiàn)的最壞情況。這兩種排序都是不穩(wěn)定的。 若要求排序穩(wěn)定,則可選用歸并排序。但本章介紹的從單個(gè)記錄起進(jìn)行兩兩歸并的排序
發(fā)表于 10-26 15:11
基于C語言二分查找排序源代碼
本文檔內(nèi)容介紹了C語言歸并、選擇、直接插入、希爾、冒泡、快速、堆排序與順序、二分查找排序源代碼,分享給大家供大家參考。
發(fā)表于 01-04 11:24
?1次下載
幾種c語言程序的排序包括應(yīng)用程序等資料免費(fèi)下載
本文檔的主要內(nèi)容詳細(xì)介紹的是幾種c語言程序的排序包括應(yīng)用程序好資料免費(fèi)下載包括了:堆排序,改進(jìn)冒泡排序,歸并排序,簡單插入排序,簡單選擇
發(fā)表于 09-29 08:00
?6次下載
插入排序和冒泡排序哪個(gè)更牛逼?
對(duì)于時(shí)間復(fù)雜度的分析,要把最好時(shí)間復(fù)雜度、最壞時(shí)間復(fù)雜度、平均時(shí)間復(fù)雜度分析出來,分別對(duì)應(yīng)了排序算法的最好排序情況、最壞排序情況以及平均排序效率。
揭秘冒泡排序、交換排序和插入排序
01 — 冒泡排序 在實(shí)現(xiàn)冒泡排序代碼之前我們先理解一下什么是冒泡排序,我們舉一個(gè)現(xiàn)實(shí)生活中的例子來幫助我們理解。 操場排隊(duì)我們都知道吧,現(xiàn)
解析數(shù)據(jù)結(jié)構(gòu)的常用七大排序算法
為了讓大家掌握多種排序方法的基本思想,本篇文章帶著大家對(duì)數(shù)據(jù)結(jié)構(gòu)的常用七大算法進(jìn)行分析:包括直接插入排序、希爾排序、冒泡排序、快速
光纖直接插入芯片,速度和效率驚人!
TeraPHY是一款光學(xué)I/O小芯片,擁有4Tbps的雙向帶寬,卻只有10W的功耗。這項(xiàng)技術(shù)的重要性在于,擺脫了傳統(tǒng)的PCB和長電氣走線的限制,通過直接插入芯片,實(shí)現(xiàn)了更高效的數(shù)據(jù)傳輸。
評(píng)論