老生常談 排序演算法溫習一O n 2 級別

2021-10-07 07:27:14 字數 2853 閱讀 4777

排序演算法是每乙個程式設計者/演算法學習者高階路上的必經之路,是演算法殿堂的入門和基石存在。對於找工作來說,排序也是被面試詢問比較頻繁的問題。其他的各種演算法題中,也會經常用到排序的預處理。話不多說開始正題。

選擇排序,以公升序為例。對陣列做遍歷處理(索引i),每一輪遍歷過程中,向後和每乙個元素進行比較(索引j),找出關鍵字最小的索引,在大迴圈結束前,將最小的關鍵字交換到當前最前方(i)。注意,細節,每一輪內迴圈,j的起始位置為i+1。

(有序區,無序區)。在無序區里找乙個最小的元素跟在有序區的後面。對陣列:比較得多,換得少。

選擇排序思路:

在未排序序列中找到最小(大)元素,存放到排序序列的起始位置

從剩餘未排序元素中繼續尋找最小(大)元素,然後放到已排序序列的末尾

以此類推,直到所有元素均排序完畢

//選擇排序

template

<

typename t>

void

choicesort

(vector

& arr)

if(min!=i)

swap

(arr[i]

,arr[min]);

//將找到的最小元素放到排序序列末尾,實際就是每一次i的位置

}return

;}

選擇排序的每一在未排序序列中搜尋,對所有的進行比較,最後進行交換。而氣泡排序實際上也是一種交換排序。它進行序列中的兩兩比較,如果反序就進行交換。

//基本氣泡排序,前->後

template

<

typename t>

void

bubblesort

(vector

& arr)

}return;}

//後->前

template

<

typename t>

void

bubblesort_1

(vector

& arr)

}return

;}

以前往後為例,在每乙個大迴圈裡,我們一次迴圈將最大值冒泡到序列末尾,然後又從頭開始進行下一輪。為什麼不在每一輪前往後結束,進行一次後往前呢?在一次大迴圈裡,先將未排序序列的最大值放到最後,再將最小值放到頭部。ok,來回冒泡,雞尾酒風味。

//冒泡改進,雞尾酒

template

<

typename t>

void

cocktailsort

(vector

& arr)

right--

;for

(int i=right;i>left;i--

) left++;}

return

;}

不難,雙指標的味道,熟悉又美味。

我們來考慮一種情況,當序列基本處於有序狀態時,如[2,1,3,4,5,6,7,8,9],在原來的冒泡演算法情況下,當i=0時,交換了前兩位,已經處於有序狀態,但是,演算法仍然會將後續的i=1-8進行比較,進行了無用操作。利用flag來標識是否需要繼續進行比較。初始化flag,不然就進不了冒泡核心區啦!在每一次大迴圈初始,將flag賦值為false,當內迴圈進行了資料交換時,將flag重新賦為true,說明此時序列還沒有處於有序狀態。相反,有序,就會跳出。這樣的將冒泡的最後一次大迴圈的操作進行了優化。

//冒泡改進,標記正確序列,針對近乎有序的數序列

template

<

typename t>

void

newbubblesort_2

(vector

& arr)}}

return

;}

撲克大家都玩過,撲克牌的排序方法就是典型的插入排序,當然計算機**的插入排序沒有那麼直觀,不過也不難理解。

核心思想:將乙個記錄插入到已經排好序的序列中,重點在於搜尋當前記錄應該處於的位置。在開始時,去序列第乙個值作為有序序列。向下取另乙個記錄,插入到其中(找到比其大的就後移,找到比其小或等於位置的進行插入)。

//直接插入排序

void

insertsort

(vector<

int>

& arr)

else

break;}

}return

;}

本文主要介紹的雖然是o(n^2)級別的排序演算法,但是還是把希爾排序放在了這裡,保持和前述插入排序的思維連貫性。希爾排序,歷史上第乙個突破了 o(n ^2)時間複雜度的排序演算法,從此為計算機開啟了快速排序的道路。

實際上,希爾排序的演算法思維非常簡單,通過學習插入排序,我們知道,插入排序在進行小資料量的排序時有一定的優勢,於是,將待排序資料按增量進行均勻分組。設初始增量為h,對於資料中第h個資料開始,每隔h取乙個數,打包成一組進行插入排序。每乙個大迴圈後,較小增量h,知道h=1時,就是普通的插入排序,此時由於資料整體以及基本有序,插入排序的複雜度進化到o(n)。對於希爾排序的時間複雜度分析,比較複雜,這裡先不進行詳述。留下實現的希爾排序供參考。

//shell sort

template

<

typename t>

void

shellsort

(vector

& arr)

else

break;}

} h /=3

;//增量縮減

}return

;}

之後會繼續出歸併排序、快速排序、堆排序的回顧,語言複習和程式設計練習同步進行。

學海無涯,大家一起加油!

聖杯布局,老生常談

聖杯布局的定義應該是乙個header,乙個footer,中間是container,包含乙個自適應寬度的center,center左邊和右邊各有乙個寬度確定的div,大概是這樣 1 使用普通的css來表現 首先是基本的html header middle left right footer 然後我們簡...

老生常談session,cookie的區別,安全性

一,為什麼session,cookie經常會有人提到 做web開發的人基本上都會用session和cookie,但是僅僅只是會用,並不知道session和cookie的真正的工作原理,都只是憑著感覺來猜測。web開發者只要利用它們來完成工作就行了,所以每個人的理解基本都會有大同小異,我想這就是ses...

老生常談session cookie的區別 安全性

一,為什麼session,cookie經常會有人提到 做web開發的人基本上都會用session和cookie,但是僅僅只是會用,並不知道session和cookie的真正的工作原理,都只是憑著感覺來猜測。web開發者只要利用它們來完成工作就行了,所以每個人的理解基本都會有大同小異,我想這就是ses...