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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

选择排序稳定吗_最常见的四种数据结构排序算法你不知道?年末怎么跳槽涨薪...

發布時間:2024/10/12 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 选择排序稳定吗_最常见的四种数据结构排序算法你不知道?年末怎么跳槽涨薪... 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

在學習數據結構的時候必然接觸過排序算法,而且在日常開發中相信排序算法用得也比較多。而排序算法眾多,各個效率又不同,難以記住。小編今天會介紹一些常用排序算法的特點和實現,對比不同排序算法的效率。

在面試中一問到排序算法就歇菜嗎?一說到排序算法只知道冒泡嗎?想了解更多排序算法嗎?想知道各種算法的實現原理及它們的優劣嗎?

小編這里列舉幾種常見的數據結構算法:

排序算法的空間、時間復雜度

下面,利用Python分別將他們進行實現。

直接插入排序


  • 算法思想:

直接插入排序.gif

直接插入排序的核心思想就是:將數組中的所有元素依次跟前面已經排好的元素相比較,如果選擇的元素比已排序的元素小,則交換,直到全部元素都比較過。
因此,從上面的描述中我們可以發現,直接插入排序可以用兩個循環完成:

  • 第一層循環:遍歷待比較的所有數組元素
  • 第二層循環:將本輪選擇的元素(selected)與已經排好序的元素(ordered)相比較。
    如果:selected > ordered,那么將二者交換
    • 代碼實現
    #直接插入排序def insert_sort(L): #遍歷數組中的所有元素,其中0號索引元素默認已排序,因此從1開始 for x in range(1,len(L)): #將該元素與已排序好的前序數組依次比較,如果該元素小,則交換 #range(x-1,-1,-1):從x-1倒序循環到0 for i in range(x-1,-1,-1): #判斷:如果符合條件則交換 if L[i] > L[i+1]: temp = L[i+1] L[i+1] = L[i] L[i] = temp

    冒泡排序


    • 基本思想

    冒泡排序.gif

    冒泡排序思路比較簡單: 將序列當中的左右元素,依次比較,保證右邊的元素始終大于左邊的元素;
    ( 第一輪結束后,序列最后一個元素一定是當前序列的最大值;) 對序列當中剩下的n-1個元素再次執行步驟1。 對于長度為n的序列,一共需要執行n-1輪比較
    (利用while循環可以減少執行次數)

    *代碼實現

    #冒泡排序def bubble_sort(L): length = len(L)#序列長度為length,需要執行length-1輪交換 for x in range(1,length):#對于每一輪交換,都將序列當中的左右元素進行比較#每輪交換當中,由于序列最后的元素一定是最大的,因此每輪循環到序列未排序的位置即可 for i in range(0,length-x): if L[i] > L[i+1]: temp = L[i] L[i] = L[i+1] L[i+1] = temp

    快速排序


    • 算法思想:

    快速排序.gif

    快速排序的基本思想:挖坑填數+分治法

  • 從序列當中選擇一個基準數(pivot)
    在這里我們選擇序列當中第一個數最為基準數
  • 將序列當中的所有數依次遍歷,比基準數大的位于其右側,比基準數小的位于其左側
  • 重復步驟1.2,直到所有子集當中只有一個元素為止。
    偽代碼描述如下:
    1.i =L; j = R; 將基準數挖出形成第一個坑a[i]。
    2.j--由后向前找比它小的數,找到后挖出此數填前一個坑a[i]中。
    3.i++由前向后找比它大的數,找到后也挖出此數填到前一個坑a[j]中。
    4.再重復執行2,3二步,直到i==j,將基準數填入a[i]中
    • 代碼實現:
    #快速排序#L:待排序的序列;start排序的開始index,end序列末尾的index#對于長度為length的序列:start = 0;end = length-1def quick_sort(L,start,end): if start < end: i , j , pivot = start , end , L[start] while i < j:#從右開始向左尋找第一個小于pivot的值 while (i < j) and (L[j] >= pivot): j = j-1#將小于pivot的值移到左邊 if (i < j): L[i] = L[j] i = i+1 #從左開始向右尋找第一個大于pivot的值 while (i < j) and (L[i] < pivot): i = i+1#將大于pivot的值移到右邊 if (i < j): L[j] = L[i] j = j-1#循環結束后,說明 i=j,此時左邊的值全都小于pivot,右邊的值全都大于pivot#pivot的位置移動正確,那么此時只需對左右兩側的序列調用此函數進一步排序即可#遞歸調用函數:依次對左側序列:從0 ~ i-1//右側序列:從i+1 ~ end L[i] = pivot#左側序列繼續排序 quick_sort(L,start,i-1)#右側序列繼續排序 quick_sort(L,i+1,end)

    歸并排序


    • 算法思想:

    歸并排序.gif

    1.歸并排序是建立在歸并操作上的一種有效的排序算法,該算法是采用分治法的一個典型的應用。它的基本操作是:將已有的子序列合并,達到完全有序的序列;即先使每個子序列有序,再使子序列段間有序。

    2.歸并排序其實要做兩件事:

    • 分解----將序列每次折半拆分
    • 合并----將劃分后的序列段兩兩排序合并
      因此,歸并排序實際上就是兩個操作,拆分+合并

    3.如何合并?
    L[first...mid]為第一段,L[mid+1...last]為第二段,并且兩端已經有序,現在我們要將兩端合成達到L[first...last]并且也有序。

    • 首先依次從第一段與第二段中取出元素比較,將較小的元素賦值給temp[]
    • 重復執行上一步,當某一段賦值結束,則將另一段剩下的元素賦值給temp[]
    • 此時將temp[]中的元素復制給L[],則得到的L[first...last]有序

    4.如何分解?
    在這里,我們采用遞歸的方法,首先將待排序列分成A,B兩組;然后重復對A、B序列
    分組;直到分組后組內只有一個元素,此時我們認為組內所有元素有序,則分組結束。

    • 代碼實現
    # 歸并排序#這是合并的函數# 將序列L[first...mid]與序列L[mid+1...last]進行合并def mergearray(L,first,mid,last,temp):#對i,j,k分別進行賦值 i,j,k = first,mid+1,0#當左右兩邊都有數時進行比較,取較小的數 while (i <= mid) and (j <= last): if L[i] <= L[j]: temp[k] = L[i] i = i+1 k = k+1 else: temp[k] = L[j] j = j+1 k = k+1#如果左邊序列還有數 while (i <= mid): temp[k] = L[i] i = i+1 k = k+1#如果右邊序列還有數 while (j <= last): temp[k] = L[j] j = j+1 k = k+1#將temp當中該段有序元素賦值給L待排序列使之部分有序 for x in range(0,k): L[first+x] = temp[x]# 這是分組的函數def merge_sort(L,first,last,temp): if first < last: mid = (int)((first + last) / 2)#使左邊序列有序 merge_sort(L,first,mid,temp)#使右邊序列有序 merge_sort(L,mid+1,last,temp)#將兩個有序序列合并 mergearray(L,first,mid,last,temp)# 歸并排序的函數def merge_sort_array(L):#聲明一個長度為len(L)的空列表 temp = len(L)*[None]#調用歸并排序 merge_sort(L,0,len(L)-1,temp)

    各種排序算法的應用場景

  • 當 n <= 50 時,適合適用直接插入排序和簡單選擇排序,如果元素包含的內容過大,就不適合直接插入排序,因為直接插入排序需要移動元素的次數比較多。
  • 當數組基本有序的情況下適合使用直接插入排序和冒泡排序,它們在基本有序的情況下排序的時間復雜度接近O(n)O(n)。
  • 若 n 較大,則應采用時間復雜度為O(nlog2n)O(nlog2?n)的排序方法:快速排序、堆排序或歸并排序。 當待排序的關鍵字是隨機分布、較復雜時,快速排序的平均時間最短。 堆排序所需的輔助空間少于快速排序,并且不會出現快速排序可能出現的最壞情況。 若要求排序穩定,則可選用歸并排序。但前面介紹的從單個記錄起進行兩兩歸并的排序算法并不值得提倡,通常可以將它和直接插入排序結合在一起使用。先利用直接插入排序求得較長的有序子序列,然后再兩兩歸并之。因為直接插入排序是穩定 的,所以改進后的歸并排序仍是穩定的。
  • 快速排序,歸并排序,希爾排序,堆排序平均時間復雜度都是O(nlog2n)O(nlog2?n) 其中,快速排序是最好的,其次是歸并和希爾,堆排序在數據量很大時效果明顯(堆排序適合處理大數據)。 大數據處理的一個例子:找出一千萬個數中最小的前一百個數。思路:建立一百個節點的大頂堆,首先將前一百個數放入堆中,之后每放入一個數就刪除一個堆頂元素,最后剩下的就是最小的一百個數。 這四種排序可看作為“先進算法”,其中,快排效率最高(大數據就不行了,而且速度有概率性),但在待排序列基本有序 的情況下,會變成冒泡排序,接近O(n2)O(n2). 希爾排序對增量的標準沒有較為滿意的答案,增量對性能會有影響。 歸并排序效率非常不錯,在數據規模較大的情況下,比希爾排序和堆排序要好。 多數先進的算法都是因為跳躍式的比較,降低了比較次數,但犧牲了排序的穩定 性。
  • 希爾排序:n 較小時較好,且關鍵字較為復雜較好。
  • 基數排序:n 較大時較好,且關鍵字較為復雜較好。
  • 喜歡小編分享的技術文章可以點贊 轉發 支持哦!

    總結

    以上是生活随笔為你收集整理的选择排序稳定吗_最常见的四种数据结构排序算法你不知道?年末怎么跳槽涨薪...的全部內容,希望文章能夠幫你解決所遇到的問題。

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