排序演算法應該是《資料結構與演算法》必須要掌握的,作為乙個合格的程式猿,不管是平時吹逼或者面試,理論來說應該是信手拈來且nobug,noerror,可是捫心自問是不是有這樣的效果?其實不然,不管是在面試還是平時做題,每次遇到還是心裡會有咯噔一下的感覺,一旦有膽怯的感覺就說明還是不夠紮實,反反覆覆練習很多次都忘,雖然排序演算法在實際工作中基本不用寫,掌握紮實意義不大,但是這個世界上又哪來那麼多有意義的事?哈哈哈,其實開玩笑的,在排序演算法中,會涉及到一些基礎的資料結構知識和演算法,比如二叉樹,數列,遞迴,分治等知識,掌握好基礎知識百利無一害,避免自己浮沙築高台,所以這裡有必要簡單總結一下,供自己和大家複習使用。
概述
快速排序算是乙個常考的排序演算法,也不難,自己感覺快速排序這個名字起得有問題,應該叫做錨點填坑遞迴排序排序,後面我會解釋這個問題。
思路
既然是錨點排序,顧名思義,我們就是根據乙個錨點值進行排序。
思考一:比如有3836932這幾個數,錨點該怎麼選?回答:隨便。但是考慮寫**和邏輯的方便,我這裡選擇第乙個數3作為錨點
思考二:選完錨點然後呢?
回答:我們就把第乙個位置扣掉,*3836932,可以看到第乙個位置為空了,我們從右往左找比3小的,可以看到2比3小,那麼就把2放到第乙個空位置,2383693*,可以看到最後乙個位置又空出來了,所以從前往後找,找乙個比3大的數,然後去填這個坑,23*36938,可以看到這就是乙個填坑遊戲,所以一輪填坑遊戲下來數字順序如下23336938
思考:可以看到第一數3最終放在了第三位置的記憶體中,那麼第三位置前面的就都是小於等於3的,後面都是大於等於3的,後面怎麼做呢?
回答:遞迴。。。,就很難受,搞到最後是遞迴,所以我把快速排序改名為(錨點填坑遞迴排序演算法)
int getid(vector& num, int left, int right)
num[left] = target;
return left;
}void quicksort(vector& num, int left, int right)
概述
堆排序相對於其他演算法,估計能一把寫出來的不多,其實堆排序並不難,主要是理解透徹,記憶一些點就可以了,堆排序顧名思義就是利用堆排序,那麼堆無非就是大堆和小堆,大堆就是根節點大於子節點,小堆相反。
思考一:知道堆是什麼後這玩意應該怎麼用?記住回答一:假如我們有一串數,我構建了乙個大堆,那麼頂尖就是這一串數最大值,那麼我取走這個頂尖的數,剩下的一堆資料重新構建乙個大堆,是不是新堆的頂尖就是第二大數,ok到目前為止我們思路理清了,下面繼續思考
思考二:第
一、堆是二叉樹,難道我還要寫乙個二叉樹類嗎?第
二、即使有了二叉樹,怎麼構建大堆?第
三、二叉樹刪除節點是不是還要還要再二叉樹類中實現?
回答二: 估計很多人一般思考到這一步就沒興趣或者畏懼了,但是最核心的地方也才剛剛開始,要點記憶:
大小堆是完全二叉樹,二叉樹和序列有對應關係,需要記憶:root=i; left=2*i+1; right=2*i+2(不信的可以自己驗證)
大小堆的第乙個非葉子節點的序號是size/2-1
其實記住這兩條,堆排序基本就是信手拈來,所以理解歸理解,記憶還是要記憶的,所以一般天才記憶力都不差,因為遇到問題後可以快速調出自己大腦儲存的知識,畢竟空間換算力,節約時間和腦力,做事就顯得利索幹練。
//構建大堆,使用記憶點一,遞迴構建
void adjust(vector& num, int length, int id)
}void heapsort(vector& num)
; for (int i = size-1; i > 0; i--)
}
總結
首先邏輯思路要清楚不要畏懼,第二要記憶兩個點,第三也就是留的思考問題,為什麼第一次構建大堆要遍歷非葉子節點,換句話說為什麼第一次要從下到上,後面就不需要了,其實自己可以簡單舉個例子,如果第一次從上到下,那麼假如根節點就是大於子節點,那麼就不會遞迴往下構建了,也就無法完成堆的構建,而後面可以從上到下是因為。。。自己想一下明白了。
氣泡排序算是入門級排序了,這個就不細說了
void bubblesort(vector& num)}}
}
總結
氣泡排序記得冒泡這個觀念就可以了,具體還有一些優化手法就不細說了,有興趣可以自己修改
歸併排序最重要的就是先把框架搭起來,其實思路沒什麼可以講得,框架如下:
void
mergesort
(vector<
int>
& num,
int start,
int end)
}
框架打好以後就是簡單實現了,實現的核心就是要把原始陣列利用起來, 寫的羅里吧嗦,意思就是這個意思
void
merge
(vector<
int>
& num,
int left,
int mid,
int right)
else
}else
if(a <= mid)
else
}for
(int i =
0, j = left;j <= right; i++
, j++
)}
插入排序,如果玩過撲克牌跑得快應該很快就能寫出來,抓牌的過程就是插入排序,就是將陣列後面乙個元素的關鍵字插入到前面的有序陣列中,一直重複至排序完成。
void
insertsort
(vector<
int>
& num,
int length)
}}
排序演算法之一 氣泡排序 C 版本
1.初始版本void bubblesort init int pdata,int size 每一輪結束之後,如果這輪中沒有進行一次資料交換,表明陣列已經有序,無需再進行操作。2.改進版本void bubblesort advance int pdata,int size if hasswap bre...
排序演算法之八 桶排序 C 版本
實現中,使用vector作為桶,只是從編碼便利的角度出發。因為需要對各個桶進行單獨排序,所以,對桶進行的排序演算法是否穩定,影響了整個演算法的穩定性,這裡使用的是sort演算法,因此整個演算法就是不穩定的。void bucketsort int pdata,int size 建立桶 int buck...
氣泡排序,選擇排序,插入排序 c 演算法優化版本
氣泡排序 bubblesort.h 氣泡排序 created on 2020年2月10日 author luyonglei ifndef src bubblesort h define src bubblesort h include using namespace std if 0template...