排序總結(jié)

1.冒泡排序

依次循環(huán)旁邊的比較放到后邊去

/**

最好時間復(fù)雜度是O(n)

最壞時間復(fù)雜度是O(n^2)

平均時間復(fù)雜度:O(n^2)

平均空間復(fù)雜度:O(1)

*/

- (void)foolSortArray:(NSMutableArray *)array {

? ? for (int i = 0; i < array.count-1; i++) {

? ? ? ? for (int j = 0; j < array.count-i-1; j++) {

? ? ? ? ? ? if (array[j] > array[j+1]) {

? ? ? ? ? ? ? ? id tmp = array[j];

? ? ? ? ? ? ? ? array[j] = array[j+1];

? ? ? ? ? ? ? ? array[j+1] = tmp;

? ? ? ? ? ? }

? ? ? ? }

? ? }

}

2.選擇排序

用前邊的和后邊的依次比較放到前邊去,就是先排好前邊的

- (void)selectSortArray:(NSMutableArray *)array {

? ? for (int i = 0; i < array.count-1; i++) {

? ? ? ? for (int j = i+1; j < array.count; j++) {

? ? ? ? ? ? if (array[i] > array[j]) {

? ? ? ? ? ? ? ? id tmp = array[i];

? ? ? ? ? ? ? ? array[i] = array[j];

? ? ? ? ? ? ? ? array[j] = tmp;

? ? ? ? ? ? }

? ? ? ? }

? ? }

}

3.插入排序

- (void)insertSortArray:(NSMutableArray *)array {

? ? for (int i = 1; i < [array count]; i++) {

? ? ? ? int j = i;

? ? ? ? NSInteger temp = [[array objectAtIndex:i] integerValue];

? ? ? ? while (j > 0 && temp < [[array objectAtIndex:j - 1] integerValue]) {

? ? ? ? ? ? [array replaceObjectAtIndex:j withObject:[array objectAtIndex:(j - 1)]];

? ? ? ? ? ? j--;

? ? ? ? }

? ? ? ? [array replaceObjectAtIndex:j withObject:[NSNumber numberWithInteger:temp]];

? ? }

}

4.希爾排序

是把記錄按下標的一定增量分組扮饶,對每組使用直接插入排序算法排序啦撮;隨著增量逐漸減少艇纺,每組包含的關(guān)鍵詞越來越多嗜侮,當增量減至1時役纹,整個文件恰被分成一組贡羔,算法便終止尸饺。

增量:插入排序只能與相鄰的元素進行比較,而希爾排序則是進行跳躍比較沈堡,而增量就是步長静陈。

/**

最優(yōu)的增量在最壞的情況下卻為O(n2?3),最壞的情況下時間復(fù)雜度仍為O(n2)

需要注意的是诞丽,增量序列的最后一個增量值必須等于1才行

另外由于記錄是跳躍式的移動鲸拥,希爾排序并不是一種穩(wěn)定的排序算法

*/

- (void)shellSortArray:(NSMutableArray *)array {

? ? int count = (int)array.count;

? ? // 初始增量為數(shù)組長度的一半,然后每次除以2取整

? ? for (int increment = count/2; increment > 0; increment/=2) {

? ? ? ? // 初始下標設(shè)為第一個增量的位置僧免,然后遞增

? ? ? ? for (int i = increment; i<count; i++) {

? ? ? ? ? ? // 獲取當前位置

? ? ? ? ? ? int j = i;

? ? ? ? ? ? // 然后將此位置之前的元素刑赶,按照增量進行跳躍式比較

? ? ? ? ? ? while (j-increment>=0 && [array[j] integerValue]<[array[j-increment] integerValue]) {

? ? ? ? ? ? ? ? [array exchangeObjectAtIndex:j withObjectAtIndex:j-increment];

? ? ? ? ? ? ? ? j-=increment;

? ? ? ? ? ? }

? ? ? ? }

? ? }

}

5.快速排序

/**

最理想情況算法時間復(fù)雜度O(nlogn),最壞O(n^2),平均O(nlogn)

平均空間復(fù)雜度:O(nlogn)? ? ? O(nlogn)~O(n^2)

*/

- (void)quickSortArray:(NSMutableArray *)array withLeftIndex:(NSInteger)leftIndex andRightIndex:(NSInteger)rightIndex {

? ? if (leftIndex >= rightIndex) { // 如果數(shù)組長度為0或1時返回

? ? ? ? return ;

? ? }

? ? NSInteger i = leftIndex;

? ? NSInteger j = rightIndex;

? ? NSInteger key = [array[i] integerValue]; // 記錄比較基準數(shù)

? ? while (i < j) {

? ? ? ? /**** 首先從右邊j開始查找比基準數(shù)小的值 ***/

? ? ? ? while (i < j && [array[j] integerValue] >= key) { // 如果比基準數(shù)大懂衩,繼續(xù)查找

? ? ? ? ? ? j--;

? ? ? ? }

? ? ? ? // 如果比基準數(shù)小撞叨,則將查找到的小值調(diào)換到i的位置

? ? ? ? array[i] = array[j];

? ? ? ? /**** 當在右邊查找到一個比基準數(shù)小的值時,就從i開始往后找比基準數(shù)大的值 ***/

? ? ? ? while (i < j && [array[i] integerValue] <= key) { // 如果比基準數(shù)小浊洞,繼續(xù)查找

? ? ? ? ? ? i++;

? ? ? ? }

? ? ? ? // 如果比基準數(shù)大牵敷,則將查找到的大值調(diào)換到j(luò)的位置

? ? ? ? array[j] = array[i];

? ? }

? ? // 將基準數(shù)放到正確位置

? ? array[i] = @(key);

? ? /**** 遞歸排序 ***/

? ? // 排序基準數(shù)左邊的

? ? [self quickSortArray:array withLeftIndex:leftIndex andRightIndex:i - 1];

? ? // 排序基準數(shù)右邊的

? ? [self quickSortArray:array withLeftIndex:i + 1 andRightIndex:rightIndex];

}

6.堆排序

堆(heap)是計算機科學中一類特殊的數(shù)據(jù)結(jié)構(gòu)的統(tǒng)稱

堆總是滿足下列性質(zhì):1. 堆中某個節(jié)點的值總是不大于或不小于其父節(jié)點的值;2. 堆總是一棵完全二叉樹法希,將根節(jié)點最大的堆叫做最大堆或大根堆枷餐,根節(jié)點最小的堆叫做最小堆或小根堆

完全二叉樹:

若設(shè)二叉樹的深度為h,除第 h 層外苫亦,其它各層 (1~h-1) 的結(jié)點數(shù)都達到最大個數(shù)毛肋,第 h 層所有的結(jié)點都連續(xù)集中在最左邊,這就是完全二叉樹屋剑。

/**

時間復(fù)雜度為O(nlogn)

*/

- (void)heapSortArray:(NSMutableArray *)heapList len:(NSInteger)len {

? ? // 建立堆润匙,從最底層的父節(jié)點開始

? ? for(NSInteger i = (heapList.count/2 -1); i>=0; i--)

? ? ? ? [self adjustHeap:heapList location:i len:heapList.count];

? ? for(NSInteger i = heapList.count -1; i >= 0; i--){

? ? ? ? NSInteger maxEle = ((NSString *)heapList[0]).integerValue;

? ? ? ? heapList[0] = heapList[i];

? ? ? ? heapList[i] = @(maxEle).stringValue;

? ? ? ? [self adjustHeap:heapList location:0 len:i];

? ? }

}

- (void)adjustHeap:(NSMutableArray *)heapList location:(NSInteger)p len:(NSInteger)len {

? ? NSInteger curParent = ((NSString *)heapList[p]).integerValue;

? ? NSInteger child = 2*p + 1;

? ? while (child < len) {

? ? ? ? // left < right

? ? ? ? if (child+1 < len && ((NSString *)heapList[child]).integerValue < ((NSString *)heapList[child+1]).integerValue) {

? ? ? ? ? ? child ++;

? ? ? ? }

? ? ? ? if (curParent < ((NSString *)heapList[child]).integerValue) {

? ? ? ? ? ? heapList[p] = heapList[child];

? ? ? ? ? ? p = child;

? ? ? ? ? ? child = 2*p + 1;

? ? ? ? }

? ? ? ? else

? ? ? ? ? ? break;

? ? }

? ? heapList[p] = @(curParent).stringValue;

}

7.歸并排序

歸并排序(MERGE-SORT)是建立在歸并操作上的一種有效的排序算法,該算法是采用分治法(Divide and Conquer)的一個非常典型的應(yīng)用。將已有序的子序列合并饼丘,得到完全有序的序列趁桃;即先使每個子序列有序,再使子序列段間有序肄鸽。若將兩個有序表合并成一個有序表卫病,稱為二路歸并。

/**

時間復(fù)雜度為O(nlogn)

(1)“分解”——將序列每次折半劃分

(2)“合并”——將劃分后的序列段兩兩合并后排序

*/

- (NSArray *)mergeSortArray:(NSMutableArray *)array {

? ? // 排序數(shù)組

? ? NSMutableArray *tempArray = [NSMutableArray arrayWithCapacity:1];

? ? // 第一趟排序是的子數(shù)組個數(shù)為ascendingArr.count

? ? for (NSNumber *num in array) {

? ? ? ? NSMutableArray *subArray = [NSMutableArray array];

? ? ? ? [subArray addObject:num];

? ? ? ? [tempArray addObject:subArray];

? ? }

? ? /**

? ? 分解操作 每一次歸并操作

? ? 當數(shù)組個數(shù)為偶數(shù)時tempArray.count/2; 當數(shù)組個數(shù)為奇數(shù)時tempArray.count/2+1; 當tempArray.count == 1時典徘,歸并排序完成

? ? */

? ? while (tempArray.count != 1) {

? ? ? ? NSInteger i = 0;

? ? ? ? // 當數(shù)組個數(shù)為偶數(shù)時 進行合并操作蟀苛, 當數(shù)組個數(shù)為奇數(shù)時,最后一位輪空

? ? ? ? while (i < tempArray.count - 1) {

? ? ? ? ? ? // 將i 與i+1 進行合并操作 將合并結(jié)果放入i位置上 將i+1位置上的元素刪除

? ? ? ? ? ? tempArray[i] = [self mergeArrayFirstList:tempArray[i] secondList:tempArray[i + 1]];

? ? ? ? ? ? [tempArray removeObjectAtIndex:i + 1];

? ? ? ? ? ? // i++ 繼續(xù)下一循環(huán)的合并操作

? ? ? ? ? ? i++;

? ? ? ? }

? ? }

? ? return tempArray.copy;

}

// 合并

- (NSArray *)mergeArrayFirstList:(NSArray *)array1 secondList:(NSArray *)array2 {

? ? // 合并序列數(shù)組

? ? NSMutableArray *resultArray = [NSMutableArray array];

? ? // firstIndex是第一段序列的下標 secondIndex是第二段序列的下標

? ? NSInteger firstIndex = 0, secondIndex = 0;

? ? // 掃描第一段和第二段序列逮诲,直到有一個掃描結(jié)束

? ? while (firstIndex < array1.count && secondIndex < array2.count) {

? ? ? ? // 判斷第一段和第二段取出的數(shù)哪個更小帜平,將其存入合并序列幽告,并繼續(xù)向下掃描

? ? ? ? if ([array1[firstIndex] floatValue] < [array2[secondIndex] floatValue]) {

? ? ? ? ? ? [resultArray addObject:array1[firstIndex]];

? ? ? ? ? ? firstIndex++;

? ? ? ? } else {

? ? ? ? ? ? [resultArray addObject:array2[secondIndex]];

? ? ? ? ? ? secondIndex++;

? ? ? ? }

? ? }

? ? // 若第一段序列還沒掃描完,將其全部復(fù)制到合并序列

? ? while (firstIndex < array1.count) {

? ? ? ? [resultArray addObject:array1[firstIndex]];

? ? ? ? firstIndex++;

? ? }

? ? // 若第二段序列還沒掃描完裆甩,將其全部復(fù)制到合并序列

? ? while (secondIndex < array2.count) {

? ? ? ? [resultArray addObject:array2[secondIndex]];

? ? ? ? secondIndex++;

? ? }

? ? // 返回合并序列數(shù)組

? ? return resultArray.copy;

}

8.二分查找

/**

二分查找法只適用于已經(jīng)排好序的查找

*/

- (NSInteger)dichotomySearch:(NSArray *)array target:(id)key {

? ? NSInteger left = 0;

? ? NSInteger right = [array count] - 1;

? ? NSInteger middle = [array count] / 2;

? ? while (right >= left) {

? ? ? ? middle = (right + left) / 2;

? ? ? ? if (array[middle] == key) {

? ? ? ? ? ? return middle;

? ? ? ? }

? ? ? ? if (array[middle] > key) {

? ? ? ? ? ? right = middle - 1;

? ? ? ? }else if (array[middle] < key) {

? ? ? ? ? ? left = middle + 1;

? ? ? ? }

? ? }

? ? return -1;

}

9.遞歸

斐波那契數(shù)列問題

- (NSInteger)recursion0:(NSInteger)n {

? ? if (n <= 1) return n;

? ? return [self recursion0:n-1] + [self recursion0:n-2];

}

階乘

- (NSInteger)recursion1:(NSInteger)n {

? ? if (n == 0) { //遞歸邊界

? ? ? ? return 1;

? ? }

? ? return n*[self recursion1:(n-1)];//遞歸公式

}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末冗锁,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子嗤栓,更是在濱河造成了極大的恐慌冻河,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,198評論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件茉帅,死亡現(xiàn)場離奇詭異叨叙,居然都是意外死亡,警方通過查閱死者的電腦和手機堪澎,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評論 3 398
  • 文/潘曉璐 我一進店門擂错,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人樱蛤,你說我怎么就攤上這事钮呀。” “怎么了刹悴?”我有些...
    開封第一講書人閱讀 167,643評論 0 360
  • 文/不壞的土叔 我叫張陵行楞,是天一觀的道長攒暇。 經(jīng)常有香客問我土匀,道長,這世上最難降的妖魔是什么形用? 我笑而不...
    開封第一講書人閱讀 59,495評論 1 296
  • 正文 為了忘掉前任就轧,我火速辦了婚禮,結(jié)果婚禮上田度,老公的妹妹穿的比我還像新娘妒御。我一直安慰自己,他們只是感情好镇饺,可當我...
    茶點故事閱讀 68,502評論 6 397
  • 文/花漫 我一把揭開白布乎莉。 她就那樣靜靜地躺著,像睡著了一般奸笤。 火紅的嫁衣襯著肌膚如雪惋啃。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,156評論 1 308
  • 那天监右,我揣著相機與錄音边灭,去河邊找鬼。 笑死健盒,一個胖子當著我的面吹牛绒瘦,可吹牛的內(nèi)容都是我干的称簿。 我是一名探鬼主播,決...
    沈念sama閱讀 40,743評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼惰帽,長吁一口氣:“原來是場噩夢啊……” “哼憨降!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起该酗,我...
    開封第一講書人閱讀 39,659評論 0 276
  • 序言:老撾萬榮一對情侶失蹤券册,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后垂涯,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體烁焙,經(jīng)...
    沈念sama閱讀 46,200評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,282評論 3 340
  • 正文 我和宋清朗相戀三年耕赘,在試婚紗的時候發(fā)現(xiàn)自己被綠了骄蝇。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,424評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡操骡,死狀恐怖九火,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情册招,我是刑警寧澤岔激,帶...
    沈念sama閱讀 36,107評論 5 349
  • 正文 年R本政府宣布,位于F島的核電站是掰,受9級特大地震影響虑鼎,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜键痛,卻給世界環(huán)境...
    茶點故事閱讀 41,789評論 3 333
  • 文/蒙蒙 一炫彩、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧絮短,春花似錦江兢、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至席里,卻和暖如春叔磷,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背胁勺。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評論 1 271
  • 我被黑心中介騙來泰國打工世澜, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人署穗。 一個月前我還...
    沈念sama閱讀 48,798評論 3 376
  • 正文 我出身青樓寥裂,卻偏偏與公主長得像嵌洼,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子封恰,可洞房花燭夜當晚...
    茶點故事閱讀 45,435評論 2 359

推薦閱讀更多精彩內(nèi)容