排序演算法是每乙個程式設計者/演算法學習者高階路上的必經之路,是演算法殿堂的入門和基石存在。對於找工作來說,排序也是被面試詢問比較頻繁的問題。其他的各種演算法題中,也會經常用到排序的預處理。話不多說開始正題。
選擇排序,以公升序為例。對陣列做遍歷處理(索引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...