排序演算法 C 版本

2021-10-17 12:06:07 字數 3166 閱讀 7367

排序演算法應該是《資料結構與演算法》必須要掌握的,作為乙個合格的程式猿,不管是平時吹逼或者面試,理論來說應該是信手拈來且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...