日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【啊哈!算法】之二、插入排序

發(fā)布時間:2023/12/9 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【啊哈!算法】之二、插入排序 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

作者:jofranks?原創(chuàng)作品,轉載請標明出處!版權所有,侵權必究!

來源:http://blog.csdn.net/jofranks


插入排序包括:直接插入排序,折半插入排序,希爾排序~!

OK,下面我們就來逐個講解!

一、直接插入排序

直接插入排序屬于穩(wěn)定的排序,時間復雜性為O(n^2),空間復雜度為O(1)。

它的基本思想是: ? ?

假設待排序數(shù)據(jù)存放在數(shù)組A[1..n]中,則A[1]可看作是一個有序序列,讓i從2開始,依次將A[i]插入到有序序列A[1..i-1]中,A[n]插入完畢則整個過程結束,A[1..n]成為有序序列。


OK,現(xiàn)在我們來看一下排序的過程:

待排序數(shù)據(jù):? 25? 54?8? 54? 21?1? 97? 2?73? 15??????????? (n=10)

i=2:?????????????? 25?54? 8?54? 21? 1?97? 2? 73? 15

i=3:?????????????? 8? 25? 54? 54?21? 1? 97?2? 73? 15

i=4:?????????????? 8? 25?54?54? 21?1? 97? 2?73? 15

i=5:?????????????? 8? 21? 25?54? 54? 1?97? 2? 73? 15

i=6:?????????????? 1? 8? 21?25? 54? 54? 97?2? 73? 15

i=7:?????????????? 1? 8?21? 25? 54?54?97? 2?73? 15

i=8:?????????????? 1? 2? 8?21? 25? 54?54? 97? 73? 15

i=9:?????????????? 1? 2?8? 21? 25?54? 54?73? 97? 15

i=10:???????????? 1? 2?8?15? 21?25? 54? 54?73? 97???????????排序結束


可在數(shù)組中增加元素A[0]作為關鍵值存儲器和循環(huán)控制開關。第i趟排序,即A[i]的插入過程為:

① 保存A[i]→A[0]

③ 如果A[j]<=A[0](即待排序的A[i]),則A[0]→A[j+1],完成插入;

?? 否則,將A[j]后移一個位置:A[j]→A[j+1];;繼續(xù)執(zhí)行③

對于上面的數(shù)據(jù)實例,i從2依次變化到10的過程中,j值分別為{1,0,3,1,0,6,1,7,3}



來看一下動畫演示:直接插入排序動畫演示


OK,下面來看一下代碼,本代碼是C語言!

void insert_sort(int a[], int N) {int temp;int j;//從第二個元素開始逐個往下for(int i = 1; i < N; i++){if(a[i] >= a[i - 1])continue;temp = a[i];//與前面的元素比較,看是否需要插入j = i - 1;for(; a[j] > temp; j--){if(j < 0)break;a[j + 1] = a[j]; //后移 }a[j + 1] = temp;} }





ok,現(xiàn)在我們來看一下C++版本的代碼:(本代碼取自維基百科)

#include <iterator>template<typename biIter> void insertion_sort(biIter begin, biIter end){typedef typename std::iterator_traits<biIter>::value_type value_type;biIter bond = begin;std::advance(bond, 1);for(; bond!=end; std::advance(bond, 1)) {value_type key = *bond;biIter ins = bond;biIter pre = ins;std::advance(pre, -1);while(ins!=begin && *pre>key) {*ins = *pre;std::advance(ins, -1);std::advance(pre, -1);}*ins = key;}}





二、折半插入排序

折半插入排序算法是一種穩(wěn)定的排序算法,時間復雜度仍然為o(n^2)!!!

本排序是在直接插入排序的基礎上,減少了比較和移動的次數(shù)形成的!是對插入排序算法的一種改進!

具體操作:在將一個新元素插入已排好序的數(shù)組的過程中,尋找插入點時,將待插入?yún)^(qū)域的首元素設置為a[low],末元素設置為a[high],則輪比較時將待插入元素與a[m],其中m=(low+high)/2相比較,如果比參考元素小,則選擇a[low]到a[m-1]為新的插入?yún)^(qū)域(即high=m-1),否則選擇a[m+1]到a[high]為新的插入?yún)^(qū)域(即low=m+1),如此直至low<=high不成立,即將此位置之后所有元素后移一位,并將新元素插入a[high+1]。


OK,我們來看一下代碼! 這類似于二分法查找,相信大家都不陌生!

void binary_insert_sort(int a[], int N) {int temp;int low, high,mid;for(int i = 1; i < N; i++){if(a[i] >= a[i - 1])continue;//開始二分low = 0;high = i - 1;temp = a[i];for(;low <= high;){mid = (low + high) / 2;if(temp > a[mid])low = mid + 1;else if(temp < a[mid])high = mid - 1;elsebreak;}//開始移動元素for(int j = i; j > low; j--){a[j] = a[j - 1];}a[low] = temp;} }


三、希爾排序

該算法也是對直接插入排序的一種改進!也叫做遞減增量排序算法!

該算法的性能提升至O(n?log2?n)!他的最優(yōu)時間是線性時間!


算法基本思想:

取一個小于n的整數(shù)S1作為增量,把所有元素分成S1個組。所有間距為S1的元素放在同一個組中。

第一組:{A[1],A[S1+1],A[2*S1+1],……}

第二組:{A[2],A[S1+2],A[2*S1+2],……}

第三組:{A[3],A[S1+3],A[2*S1+3],……}

……

第s1組:{A[S1],A[2*S1],A[3*S1],……}

先在各組內進行直接插人排序;然后,取第二個增量S2(<S1)重復上述的分組和排序,直至所取的增量St=1(St<St-1<St-2<…<S2<S1),即所有記錄放在同一組中進行直接插入排序為止。


序號

1

2

3

4

5

6

7

8

9

10

原始數(shù)據(jù)

12

89

57

32

96

37

54

5

79

57

S1=5

組別

排序結果

12

54

5

32

57

37

89

57

79

96

S2=3

組別

排序結果

12

54

5

32

57

37

89

57

79

96

S3=2

組別

排序結果

5

32

12

37

57

54

79

57

89

96

S4=1

組別

排序結果

5

12

32

37

54

57

57

79

89

96


OK,通過上表可以看的清楚是如何排序的,有可能有的童鞋還是不清楚,那沒事,我現(xiàn)在上傳一個短動畫,通過動畫我相信你能夠很好的理解shell排序!

希爾排序動畫演示


ok,我們現(xiàn)在來看代碼吧!

void shell_sort(int a[], int N) {int temp, m;int i = 0;for(; i < N; ){i = i * 4 + 1;}//還是直接插入for(;i > 0;){for(int j = i; j < N; j++){m = j - i;temp = a[j];while(a[m] > temp){a[m + i] = a[m];m -= i;}a[m + i] = temp;}i = (i - 1) / 4;} }



OK,再來看一段C++代碼,來自維基百科!

template<typename T> void sort(std::vector<T>& v) {const size_t s=v.size();for(int gap=s/2;gap>0;gap/=2)for(int i=gap;i<s;++i)for(int j=i-gap;j>=0;j-=gap)if(v[j+gap]<v[j]){T temp=v[j];v[j]=v[j+gap];v[j+gap]=temp;} }



本節(jié)到此結束!



--------2012/7/31

--------jofranks 于南昌


轉載于:https://www.cnblogs.com/java20130723/archive/2012/07/31/3211427.html

總結

以上是生活随笔為你收集整理的【啊哈!算法】之二、插入排序的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內容還不錯,歡迎將生活随笔推薦給好友。