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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

【排序】折半插入排序

發(fā)布時(shí)間:2023/12/15 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【排序】折半插入排序 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

目錄

折半插入排序原理

折半插入排序圖文說(shuō)明

代碼實(shí)現(xiàn)

C實(shí)現(xiàn)

?JAVA實(shí)現(xiàn)

?復(fù)雜度分析和穩(wěn)定性

復(fù)雜度

穩(wěn)定性

總結(jié)


折半插入排序原理

折半插入排序是對(duì)直接插入排序的一種改良方式,在直接插入排序中,每次向已排序序列中插入元素時(shí),都要去尋找插入元素的合適位置,但是這個(gè)過(guò)程是從已排序序列的最后開(kāi)始逐一去比較大小的,這其實(shí)很是浪費(fèi),因?yàn)槊勘容^一次緊接著就是元素的移動(dòng)。折半排序就是通過(guò)折半的方式去找到合適的位置,然后一次性進(jìn)行移動(dòng),為插入的元素騰出位置。什么是折半的方式去找合適的位置呢,那就是折半查找了,因?yàn)樵僖雅判虻男蛄兄?#xff0c;序列元素都是按照順序排列的,既然這樣,完全不需要逐一去比較大小,而是去比較已排序序列的中位數(shù),這個(gè)中間的位置將一排序列分為左右兩部分,通過(guò)一次比較后,就縮小了比較的范圍,重復(fù)這樣的操作,需要插入的元素就找到了合適的位置了。

折半插入排序圖文說(shuō)明

注:藍(lán)色代表已排序序列,白色代表未排序序列,紅色箭頭指向未排序序列的第一個(gè)元素位置。

?

如圖所示,現(xiàn)在有一個(gè)待排序序列[8 5 4 2 3],首先默認(rèn)初始狀態(tài)下,位置0的數(shù)字8作為已排序序列[8],位置1--位置4的[5 4 2 3 1]?為待排序序列,之后就逐一從[5 4 2 3 1]中取出數(shù)字向前進(jìn)行比較,插入到已排序序列的合適位置。尋找過(guò)程中將藍(lán)色的已排序區(qū)域不斷進(jìn)行折半。

初始狀態(tài)下,已排序區(qū)只有一個(gè)數(shù)據(jù)元素8,low位置和high位置都指向了該位置,mid為中間位置,此時(shí)很顯然也是0位(0+0)/ 2。此時(shí)temp < mid,將high指向mid的前一位,這里也就是-1,這個(gè)時(shí)候high=-1low=1,很顯然high<low,每當(dāng)這個(gè)時(shí)候,就到了移動(dòng)元素的時(shí)候了,將(high+1)(i-1)的元素都向后移一位,再把(high+1)位置上插入要插入的元素。

之后的操作也是這樣類(lèi)似的,詳細(xì)過(guò)程如下圖。

?

代碼實(shí)現(xiàn)

C實(shí)現(xiàn)

代碼:

#include <stdio.h>void insertSort(int array[], int n){int temp;for(int i = 1; i < n; i++){int low = 0;int hight = i-1;temp = array[i];while(hight>=low){int mid = ( low + hight ) / 2;if (array[mid] > temp){hight = mid - 1;}else{low = mid + 1;}}for (int j = i-1; j > hight; j--) {array[j+1] = array[j];}array[hight+1] = temp;} }void main(){int i;int a[8] = { 8, 5, 4, 3, 2, 1, 6, 7 };printf("before:{");for(i = 0; i < 8; i++){printf("%d ",a[i]);}printf("}\n");insertSort(a,8);printf("after:{");for(i = 0; i < 8; i++){printf("%d ",a[i]);}printf("}\n");}

測(cè)試結(jié)果:?

?JAVA實(shí)現(xiàn)

代碼:

/*** Created by GFC on 2018/8/29.*/ public class HalfSearchSort {public void sort(int[] array){int temp;for(int i = 1; i < array.length; i++){int low = 0;int hight = i-1;temp = array[i];while(hight>=low){int mid = ( low + hight ) / 2;if (array[mid] > temp){hight = mid - 1;}else{low = mid + 1;}}for (int j = i-1; j > hight; j--) {array[j+1] = array[j];}array[hight+1] = temp;}}public static void main(String[] args) {HalfSearchSort sort = new HalfSearchSort();int a[] = {8, 5, 4, 3, 2, 1, 6, 7};System.out.println("Before: " + Arrays.toString(a));//System.out.println(5/2);sort.sort(a);System.out.println("After: " + Arrays.toString(a));} }

?測(cè)試結(jié)果

?復(fù)雜度分析和穩(wěn)定性

復(fù)雜度

和直接插入排序相比較,折半插入排序僅僅是減少了比較的次數(shù),而移動(dòng)總次數(shù)并沒(méi)有發(fā)生改變。這個(gè)比較次數(shù)大概是,移動(dòng)次數(shù)沒(méi)有改變,所以其復(fù)雜度和直接插入排序是一樣的。

穩(wěn)定性

根據(jù)代碼分析可以知道,當(dāng)待插入數(shù)與mid位置的值相等時(shí),接下來(lái)相當(dāng)于進(jìn)入了有序序列的右半?yún)^(qū),mid+1到high,之后經(jīng)過(guò)多次折半查找,該元素所找到的合適位置就是前一個(gè)與之相等元素的后一位,所以說(shuō)兩者相對(duì)位置沒(méi)有發(fā)生變化,這般插入排序是穩(wěn)定的。

總結(jié)

折半插入排序其實(shí)是在直接插入排序的基礎(chǔ)上,結(jié)合了二分查找法的思想,順序的二分查找替代了直接插入排序中遍歷查找的過(guò)程,從而更快的能夠確定待插入元素的位置,但是由于移動(dòng)次數(shù)并沒(méi)有發(fā)生改變,所以?xún)烧叩臅r(shí)間復(fù)雜度相同。折半插入排序是穩(wěn)定的,其時(shí)間復(fù)雜度為。

?

總結(jié)

以上是生活随笔為你收集整理的【排序】折半插入排序的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

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