c++實(shí)現(xiàn)排序算法之希爾排序方式
排序算法之希爾排序
基本思想
將相距某個(gè)“增量”的記錄組成一個(gè)子序列,這樣才能保證在子序列內(nèi)分別進(jìn)行直接插入排序后得到的結(jié)果是基本有序的而不是局部有序。
進(jìn)一步理解:
先將整個(gè)待排元素序列分割成若干個(gè)子序列(由相隔某個(gè)“增量”的元素組成的)分別進(jìn)行直接插入排序,然后依次縮減增量再進(jìn)行排序,待整個(gè)序列中的元素基本有序(增量足夠?。r(shí),再對(duì)全體元素進(jìn)行一次直接插入排序。
希爾排序算法
#include <iostream> using namespace std;? void shellSort(int arr[], int n) { ?? ?int tmp = 0; ?? ?int step = n / 2; ?? ?while (step) ?? ?{ ?? ??? ?for (int i = step; i < n; i++) ?? ??? ?{ ?? ??? ??? ?tmp = arr[i]; ?? ??? ??? ?int j = i; ?? ??? ??? ?while (j >= step && tmp < arr[j - step]) ? //采用直接插入排序 ?? ??? ??? ?{ ?? ??? ??? ??? ?arr[j] = arr[j - step]; ?? ??? ??? ??? ?j -= step; ?? ??? ??? ?} ? ?? ??? ??? ?arr[j] = tmp; ?? ??? ?} ? ?? ??? ?step = step / 2; ?? ?} } ? int main() { ?? ?int arr[]{ 3, 14, 25, -22, -3, 87, 126, 34, 64, -70, 15, 17, 78 }; ?? ?int n = sizeof(arr) / sizeof(arr[0]); ?? ?shellSort(arr, n); ?? ?for (int i = 0; i < n; i++) ?? ??? ?cout << arr[i] << " "; ? ?? ?system("pause"); ? ? return 0; }
復(fù)雜度分析
當(dāng)增量為1(step = 1)時(shí),希爾排序退化成了直接插入排序,此時(shí)的時(shí)間復(fù)雜度為O(N²);
Hibbard增量的希爾排序的時(shí)間復(fù)雜度O(n^3/2);
關(guān)于希爾排序的問題分析
排序算法之希爾排序及時(shí)間復(fù)雜度分析
希爾排序
算法思想:將整個(gè)待排序列分割成若干個(gè)子序列(由相隔增量個(gè)元素組成),分別進(jìn)行直接插入排序,然后依次縮小增量再進(jìn)行排序,待整個(gè)序列中的元素基本有序時(shí),再對(duì)全體元素進(jìn)行一次直接插入排序。
希爾排序的實(shí)現(xiàn)應(yīng)該由三個(gè)循環(huán)完成
(1)第一次循環(huán),將增量d依次折半,直到增量d=1
(2)第二三層循環(huán),也就是直接插入排序所需要的兩次循環(huán)。
算法實(shí)現(xiàn):
#include <stdio.h> #define N 9 int main(void) { int arr[N] = {9,1,5,8,3,7,4,6,2}; int d = N / 2; //增量先取一半 int i,j,insertVal; //希爾排序三層循環(huán) while(d>=1) //當(dāng)增量大于等于1,不斷進(jìn)行插入排序 { //一下兩層for循環(huán)是直接插入排序代碼 for(i=d; i<N; i++) { insertVal = arr[i]; j = i - d; while(j>=0 && arr[j]>insertVal) { arr[j+d] = arr[j]; j = j - d; } arr[j+d] = insertVal; } d = d / 2; } for(i=0; i<N; i++) { printf("%d ",arr[i]); } return 0; }
由如上代碼知,希爾排序的關(guān)鍵并不是隨便分組后各自排序,而是將相隔某個(gè)增量的記錄組成一個(gè)子序列,實(shí)現(xiàn)跳躍式移動(dòng),使得排序的效率高。
時(shí)間復(fù)雜度
時(shí)間復(fù)雜度為O(n^1.5),要好于直接排序的O(n ^ 2),需要注意的是增量序列的最后一個(gè)增量值必須是1.另外由于記錄跳躍式的移動(dòng),希爾排序并不是一種穩(wěn)定的排序方法。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
C語(yǔ)言實(shí)現(xiàn)電話簿項(xiàng)目
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)電話簿項(xiàng)目,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-12-12C語(yǔ)言strlen和sizeof在數(shù)組中的使用詳解
對(duì)于 strlen 和 sizeof,相信不少程序員會(huì)混淆其功能。雖然從表面上看它們都可以求字符串的長(zhǎng)度,但二者卻存在著許多不同之處及本質(zhì)區(qū)別2021-10-10基于C語(yǔ)言編寫一個(gè)簡(jiǎn)單的Web服務(wù)器
C語(yǔ)言可以干大事,這篇文章主要為大家詳細(xì)介紹了如何基于C語(yǔ)言可以完成一個(gè)簡(jiǎn)易的Web服務(wù)器,希望這篇文章會(huì)幫你你對(duì)C語(yǔ)言有更深入的理解2024-03-03C++實(shí)現(xiàn)字符格式相互轉(zhuǎn)換的示例代碼
這篇文章主要為大家詳細(xì)介紹了C++中實(shí)現(xiàn)字符格式相互轉(zhuǎn)換的方法,主要有UTF8與string互轉(zhuǎn)、wstring與string互轉(zhuǎn),感興趣的小伙伴可以了解一下2022-11-11詳談C++何時(shí)需要定義賦值/復(fù)制構(gòu)造函數(shù)
下面小編就為大家?guī)硪黄斦凜++何時(shí)需要定義賦值/復(fù)制構(gòu)造函數(shù)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-01-01C語(yǔ)言深度解剖篇之關(guān)鍵字以及補(bǔ)充內(nèi)容
C語(yǔ)言的關(guān)鍵字共有32個(gè),根據(jù)關(guān)鍵字的作用,可分其為數(shù)據(jù)類型關(guān)鍵字、控制語(yǔ)句關(guān)鍵字、存儲(chǔ)類型關(guān)鍵字和其它關(guān)鍵字四類,這篇文章主要給大家介紹了關(guān)于C語(yǔ)言深度解剖篇之關(guān)鍵字以及補(bǔ)充內(nèi)容的相關(guān)資料,需要的朋友可以參考下2022-06-06