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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

二分查找和折半插入排序一块说说-很合适~~~

發(fā)布時(shí)間:2023/12/4 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 二分查找和折半插入排序一块说说-很合适~~~ 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

前言

上一篇在聊時(shí)間復(fù)雜度和空間復(fù)雜度時(shí),沒有按指定格式顯示(明明預(yù)覽的時(shí)候沒問題的),強(qiáng)迫癥的我稍微優(yōu)化了一下重新發(fā)布,目的就是讓小伙伴看著舒服。

上次聊到的直接插入排序在比較有序數(shù)據(jù)和待插入數(shù)據(jù)時(shí),是通過(guò)依次遍歷的方式進(jìn)行比較,當(dāng)數(shù)據(jù)量比較大時(shí),得考慮進(jìn)一步優(yōu)化;折半插入排序就是通過(guò)減少有序數(shù)據(jù)與待插入數(shù)據(jù)的比較次數(shù),從而提升效率。

正文

1. 先來(lái)熟悉一下折半查找

1.1 ?折半查找算法思想

折半查找又稱二分查找,僅適用于有序的順序表

思想(假設(shè)順序表是升序的):

  • 首先將指定值與順序表中中間位置元素進(jìn)行比較;

  • 若相等,代表找到,則返回該元素的位置;

  • 若不等,需繼續(xù)查找;

    若指定的值小于順序表中中間元素,則查找前半部分;

    若指定的值大于順序表中中間元素,則查找后半部分;

重復(fù)以上過(guò)程,直到找到元素為止;或者找完所有數(shù)據(jù)為止,即查找失敗;

1.2 折半查找實(shí)現(xiàn)及解析

算法代碼如下(在升序順序表中查數(shù)據(jù))

image-20210327174929319

執(zhí)行結(jié)果如下:

image-20210327175057909

解析查找步驟過(guò)程,如下:

圖中分別使用紅、綠、黃箭頭所指的數(shù)據(jù)分別高、中、低索引位,藍(lán)色為需要在順序表中查找的數(shù)。

能查到數(shù)據(jù)的步驟:

image-20210328000114746

上圖步驟說(shuō)明:

  • 第1步將low初始為0,high初始賦值為順序表中的元素個(gè)數(shù)減1,這里為5;當(dāng)循環(huán)進(jìn)來(lái)時(shí)將mid賦值為(low+high)/2,因?yàn)閙id為int類型,會(huì)取整,這里就得到mid為2;然后將索引位為2的數(shù)據(jù)66與需要查找的數(shù)據(jù)92進(jìn)行比較,發(fā)現(xiàn)92大于66,需繼續(xù)在后半部分查找,所以將low的值改為mid+1,即為3;

  • 第2步進(jìn)入循環(huán),繼續(xù)將mid的賦值為(low+high)/2,因?yàn)樯弦徊絣ow的值為3,high的值不變,還是為5,所以得出的mid值為4,然后將索引位為4的數(shù)據(jù)92與需要查找的數(shù)據(jù)92進(jìn)行比較,兩者相等,代表已經(jīng)找到,返回當(dāng)時(shí)找到的位置mid。

查找失敗時(shí)的情況:

image-20210328000247255

上圖步驟說(shuō)明:

  • 第1步將low初始為0,high初始賦值為順序表中的元素個(gè)數(shù)減1,這里為5;當(dāng)循環(huán)進(jìn)來(lái)時(shí)將mid賦值為(low+high)/2,因?yàn)閙id為int類型,會(huì)取整,這里就得到mid為2;然后將索引位為2的數(shù)據(jù)66與需要查找的數(shù)據(jù)921進(jìn)行比較,發(fā)現(xiàn)921大于66,需繼續(xù)在后半部分查找,所以將low的值改為mid+1,即為3;

  • 第2步進(jìn)入循環(huán),繼續(xù)將mid的賦值為(low+high)/2,因?yàn)樯弦徊絣ow的值為3,high的值不變,還是為5,所以得出的mid值為4,然后將索引位為4的數(shù)據(jù)92與需要查找的數(shù)據(jù)921進(jìn)行比較,發(fā)現(xiàn)921大于92,需繼續(xù)在后半部分查找,所以將low的值改為mid+1,即為5;

  • 第3步進(jìn)入循環(huán),繼續(xù)將mid的賦值為(low+high)/2,因?yàn)樯弦徊絣ow的值為5,high的值不變,還是為5,所以得出的mid值為5(這里高、中、低都指向同一位置),然后將索引位為5的數(shù)據(jù)100與需要查找的數(shù)據(jù)921進(jìn)行比較,發(fā)現(xiàn)921大于100,需繼續(xù)在后半部分查找,所以將low的值改為mid+1,即為6;

  • 第4步進(jìn)入循環(huán)時(shí),low在第3步時(shí)變?yōu)?,high還是沒變,依然是5,low大于high,不滿足循環(huán)條件,代表已經(jīng)查詢完成,但沒有查詢到數(shù)據(jù),跳出循環(huán),返回-1;

1.3 分析折半查找算法性能

時(shí)間復(fù)雜度

如果傳入的數(shù)據(jù)規(guī)模為n,即有n個(gè)元素;第一次在 n/2個(gè)元素中查找,第二次在n/(22)個(gè)元素中查找,第三次在n/(23)個(gè)元素中查找,假如經(jīng)過(guò)x次查找到元素,則得到時(shí)間復(fù)雜度為O(log2n);

空間復(fù)雜度

因?yàn)樵诓檎疫^(guò)程中,用到了固定的幾個(gè)中間變量(low,mid,high),所以算法過(guò)程中消耗的內(nèi)存是一個(gè)常量級(jí)別的,則空間復(fù)雜度為O(1);

穩(wěn)定性

由于在算法過(guò)程中只是查找,不改變?cè)氐奈恢?#xff0c;則折半查找算法是穩(wěn)定的。

綜上所述,插入排序的時(shí)間復(fù)雜度為O(log2n),空間復(fù)雜度為O(1),是穩(wěn)定算法;

2. 搞明白折半插入排序

2.1 折半插入排序算法思想

折半插入排序是對(duì)直接插入排序的優(yōu)化,直接插入排序在比較過(guò)程中依次遍歷有序列表中的元素和待插入數(shù)據(jù)比較,而折半插入排序是將原來(lái)的依次遍歷有序列表?yè)Q成折半查找算法,提升比較效率,找到合適位置之后,對(duì)應(yīng)的元素需要向后移位,然后將待插入元素插入到騰出的空位即可;重復(fù)到排序完成為止。

2.2 折半插入排序算法實(shí)現(xiàn)與解析

代碼實(shí)現(xiàn)(升序):

image-20210329104257982

運(yùn)行效果如下:

image-20210329104425770

步驟解析如圖:

image-20210329123521476

步驟說(shuō)明:

圖中綠線框部分代表是已經(jīng)排好序的列表,箭頭指的元素是下一個(gè)待插入的元素,黃線框部分為剩下的無(wú)序元素。黃方塊為每次折半查找到的mid位置,綠方塊表示最后有序列表騰出的位置。

  • 將原始數(shù)據(jù)array復(fù)制到新數(shù)組中arrayb中,這步的主要目的是后續(xù)不需要聲明額外臨時(shí)變量,也為了后續(xù)核心代碼實(shí)現(xiàn)邏輯簡(jiǎn)單易懂,減少過(guò)多的判斷;

  • 第1步將第一個(gè)元素作為有序列表(第一元素為2),下一個(gè)待插入的元素為5,將5放入哨兵位置,即索引為0的位置;然后折半查找,初始low為1,high為第一次也為1;因?yàn)閯傞_始有序列表中只有一個(gè)元素,則找到就是2,與哨兵位的值5比較,2小于5,需要繼續(xù)在有序列表的后半部分查找,改變low為mid+1,此時(shí)為2,大于high,跳出循環(huán);不需要移動(dòng)位置,保持當(dāng)前位置不變。

  • 第2步時(shí),有序列表中的元素為2、5,下一個(gè)待插入的元素為6,將6放入哨兵位置,即索引為0的位置;然后折半查找:

    第2-1步 初始low為1,此時(shí)計(jì)算出high的值為2;根據(jù)low和high計(jì)算出mid為1(因?yàn)槭莔id是整數(shù),所以3除以2,取整為1),將mid位的值2與待插入元素6比較,2小于6,需要繼續(xù)在有序列表中的后半部分繼續(xù)查找,則改變low的值,為mid加1,得到low為2;

    第2-1步 上一步得到low為2,high的值仍然為2;根據(jù)low和high計(jì)算出mid為2,將mid位的值5與待插入元素6比較,5小于6,需要繼續(xù)在有序列表中的后半部分繼續(xù)查找,則改變low的值,為mid加1,得到low為3;不滿足循環(huán)條件,退出折半;不需要移動(dòng)位置,保持當(dāng)前位置不變;

  • 第3步時(shí),有序列表中的元素為2、5、6,下一個(gè)待插入的元素為1,將1放入哨兵位置,即索引為0的位置;然后折半查找:

    第3-1步 初始low為1,此時(shí)計(jì)算出high的值為3;根據(jù)low和high計(jì)算出mid為2,將mid位的值5與待插入元素1比較,5大于1,需要繼續(xù)在有序列表中的前半部分繼續(xù)查找,則改變high的值,為mid減1,得到high為1;

    第3-2步 初始low為1,上一步計(jì)算出high的值為1;根據(jù)low和high計(jì)算出mid為1,將mid位的值2與待插入元素1比較,2大于1,需要繼續(xù)在有序列表中的前半部分繼續(xù)查找,則改變high的值,為mid減1,得到high為0;繼續(xù)循環(huán)是low大于high,不滿足條件,跳出循環(huán);

    第3-3步 根據(jù)折半查找比較,得出合適位置為high+1,即需要將待插入元素插入到1位置,需要將2、5、6三個(gè)元素依次向后移位,騰出索引位1的位置,將待插入元素1插入到此索引位。

  • 第4步時(shí),有序列表中的元素為1、2、5、6,下一個(gè)待插入的元素為9,將9放入哨兵位置,即索引為0的位置;然后折半查找:

    第4-1步 初始low為1,此時(shí)計(jì)算出high的值為4;根據(jù)low和high計(jì)算出mid為2(因?yàn)槭莔id是整數(shù),所以5除以2,取整為2),將mid位的值2與待插入元素9比較,2小于9,需要繼續(xù)在有序列表中的后半部分繼續(xù)查找,則改變low的值,為mid+1,得到low為3;

    第4-2步 上一步計(jì)算出low為3,high的值仍然為4;根據(jù)low和high計(jì)算出mid為3(因?yàn)槭莔id是整數(shù),所以7除以2,取整為3),將mid位的值5與待插入元素9比較,5小于9,需要繼續(xù)在有序列表中的后半部分繼續(xù)查找,則改變low的值,為mid+1,得到low為4;

    第4-3步 上一步計(jì)算出low為4,high的值仍然為4;根據(jù)low和high計(jì)算出mid為4,將mid位的值6與待插入元素9比較,6小于9,需要繼續(xù)在有序列表中的后半部分繼續(xù)查找,則改變low的值,為mid+1,得到low為5;繼續(xù)循環(huán)是low大于high,不滿足條件,跳出循環(huán);

  • 第5步是,有序列表中的元素為1、2、5、6、9,下一個(gè)待插入的元素為3,將3放入哨兵位置,即索引為0的位置;然后折半查找:

    第5-1步 初始low為1,此時(shí)計(jì)算出high的值為5;根據(jù)low和high計(jì)算出mid為3,將mid位的值5與待插入元素3比較,5大于3,需要繼續(xù)在有序列表中的前半部分繼續(xù)查找,則改變high的值,為mid減1,得到high為2;

    第5-2步 初始low為1,上一步計(jì)算出high的值為2;根據(jù)low和high計(jì)算出mid為1(3除以2取整得1),將mid位的值1與待插入元素3比較,1小于3,需要繼續(xù)在有序列表中的后半部分繼續(xù)查找,則改變low的值,為mid加1,得到low為2;

    第5-3步,上一步計(jì)算出low為2,第5-1步計(jì)算出high為2;根據(jù)low和high計(jì)算出mid為2,將mid位的值2與待插入元素3比較,2小于3,需要繼續(xù)在有序列表中的后半部分繼續(xù)查找,則改變low的值,為mid加1,得到low為3;繼續(xù)循環(huán),不符合循環(huán)條件,循環(huán)終止

    第5-4步 根據(jù)折半查找比較,得出合適位置為high+1,即需要將待插入元素插入到3位置,需要將5、6、9三個(gè)元素依次向后移位,騰出索引位3的位置,將待插入元素3插入到此索引位。最終得到排序結(jié)果1、2、3 、5 、6 、9;

2.3 折半插入排序算法分析

時(shí)間復(fù)雜度

在算法過(guò)程中有兩層循環(huán),第一層需要遍歷所有元素,則時(shí)間復(fù)雜度為O(n);第二層循環(huán)中包含兩部分算法,第一步是通過(guò)折半算法找位置,時(shí)間復(fù)雜度在剛開始已經(jīng)分析,為O(log2n);第二步是找到位置之后需要騰出空位,需要將對(duì)應(yīng)元素移位,時(shí)間復(fù)雜度為O(n);則整體算法的時(shí)間復(fù)雜度為外層循環(huán)的時(shí)間復(fù)雜度乘以內(nèi)層循環(huán)的時(shí)間復(fù)雜度,去掉系數(shù)和常數(shù),取大的,得出結(jié)果為O(n2);

空間復(fù)雜度

在算法核心部分只采用了固定的幾個(gè)中間變量(i,j,low,mid,high,arrayb[0]),所以算法過(guò)程中消耗的內(nèi)存是一個(gè)常量,則空間復(fù)雜度為O(1);

穩(wěn)定性

由于在算法過(guò)程中采用折半算法找位置的,使用大于符號(hào)進(jìn)行比較值,所以當(dāng)遇到相等數(shù)據(jù)時(shí),位置不會(huì)受到改變,則折半插入算法是穩(wěn)定的。

綜上所述,折半插入排序的時(shí)間復(fù)雜度為O(n2),空間復(fù)雜度為O(1),是穩(wěn)定算法;

總結(jié)

這里說(shuō)到兩種算法,折半查找(二分查找)算法,折半插入排序算法;最終關(guān)于插入排序算法的思想沒變,只是在比較有序列表時(shí)做了優(yōu)化;對(duì)于小數(shù)據(jù)量的排序,感覺不到優(yōu)化,當(dāng)數(shù)據(jù)量大時(shí),比較效率就明顯提升啦;如果不明白的小伙伴調(diào)試代碼試試,再不行可以留言,有時(shí)間會(huì)及時(shí)回復(fù)。

感謝小伙伴的:點(diǎn)贊收藏評(píng)論,下期繼續(xù)~~~

一個(gè)被程序搞丑的帥小伙,關(guān)注"Code綜藝圈",跟我一起學(xué)~~~

總結(jié)

以上是生活随笔為你收集整理的二分查找和折半插入排序一块说说-很合适~~~的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

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