排序算法---快速排序、堆排序、冒泡排序

排序算法

  • 1 快速排序
    • 代碼實現
    • stdlib庫快排
  • 2 堆排序
    • 堆排序的基本思想
      • 如何構造一個大頂堆
      • 排序
  • 3 冒泡排序

1 快速排序

文章原地址:https://blog.csdn.net/morewindows/article/details/6684558
快速排序的平均時間復雜度是0(NlogN),它采用了一種分治的策略,通常稱其為分治法。該方法的基本思想是:

  1. 先從數列中取出一個數作為基準數。
  2. 分區:將大于等于這個數放到它的右邊,小于它的數全放在它的左邊
  3. 再對左右區間進行快排

雖然快速排序稱為分治法,但分治法這三個字顯然無法很好概括快速排序的全部步驟,因此我對快速排序做了進一步的說明:挖坑填數+分治法。

以一個數組作為示例,取區間第一個數為基準數。
請添加圖片描述
初始時,i = 0; j = 9; X = a[i] = 72

由于已經將a[0]中的數保存到X中,可以理解成在數組a[0]上挖了個坑,可以將其它數據填充到這來。

從j開始向前找一個比X小或等于X的數。當j=8,符合條件,將a[8]挖出再填到上一個坑a[0]中。a[0]=a[8]; i++; 這樣一個坑a[0]就被搞定了,但又形成了一個新坑a[8],這怎么辦了?簡單,再找數字來填a[8]這個坑。這次從i開始向后找一個大于X的數,當i=3,符合條件,將a[3]挖出再填到上一個坑中a[8]=a[3]; j–;

數組變為:
請添加圖片描述

i = 3; j = 7; X=72

再重復上面的步驟,先從后向前找,再從前向后找。

從j開始向前找,當j=5,符合條件,將a[5]挖出填到上一個坑中,a[3] = a[5]; i++;

從i開始向后找,當i=5時,由于i==j退出。

此時,i = j = 5,而a[5]剛好又是上次挖的坑,因此將X填入a[5]。依次類推。

代碼實現

void quick_sort(int *arr,int l,int r)
{if(l<r){   int i=l,j=r,x=arr[i];while(i<j){/* 從右往左找小于x的值,找到之后,放到arr[i++] */while(i<j && arr[j]>=x){j--;}if(i<j){arr[i++]=arr[j];}/* 從左往右找大于等于x的值,找到之后,放到arr[j--] */while(i<j && arr[i]<x){i++;}if(i<j){arr[j--]=arr[i];}}/* 放x */arr[i]=x;/* 對x左右兩個區間進行快排 */quick_sort(arr,l,i-1);quick_sort(arr,i+1,r);}
}

測試:

int main(void)
{int arr[]={72,6,57,88,60,42,83,73,48,85};quick_sort(arr,0,9);for(int i=0;i<10;i++){printf("%d ",arr[i]);}return 0;
}

在這里插入圖片描述

stdlib庫快排

stdlib庫提供了快排函數qsort

void qsort(void *base, size_t nitems, size_t size, int (*compar)(const void *, const void*))
  • base是要排序的的數組
  • nitems是數組中元素個數
  • size是每個元素所占字節數
  • compar是比較函數
#include <stdio.h>
#include <stdlib.h>int cmp(void *a,void *b)
{return *(int *)a - *(int *)b;
}int main(void)
{int arr[]={72,6,57,88,60,42,83,73,48,85};qsort(arr,10,sizeof(int),cmp);for(int i=0;i<10;i++){printf("%d ",arr[i]);}return 0;
}

2 堆排序

文章原地址:https://www.cnblogs.com/lanhaicode/p/10546257.html
堆是一個完全二叉樹,通俗的說,堆就是利用完全二叉樹的結構來維護的一維數組。
按照堆的特點可以把堆分為大頂堆和小頂堆:

  • 大頂堆:每個結點的值都大于等于其左右孩子的值
  • 小頂堆:每個結點都小于等于其左右孩子的值。

在用一維數組描述的堆中,如果父結點的下標是i,則左孩子的結點的下標是2i+1,右孩子是2i+2;所以如果孩子結點的下標是i,則父結點的下標結點j是:

j = (i-1)/2	/* 整數相除,取整,相當于向下取整數 */

我們用簡單的公式來描述一下堆的定義:

  • 大頂堆:arr[i] >= arr[2*i+1] && arr[i] >= arr[2*i+2]
  • 小頂堆:arr[i] <=arr[2*i+1] && arr[i] <= arr[2*i+2]

下面以大頂堆為例。

堆排序的基本思想

將待排序序列構造成一個大頂堆,此時,整個序列的最大值就是堆頂的根結點,然后把根結點和最后一個結點(數組最后一個元素)交換位置,那么末尾元素此時就是最大元素了。

  1. 先把n個元素的無序序列,構建成大頂堆
  2. 將根結點與最后一個元素交換位置。(將最大元素放到數組末端)
  3. 交換過后可能不再滿足大頂堆的條件,所以需要將剩下的n-1個元素重新構建成大頂堆
  4. 重復第二步和第三步直到整個數組排序完成。

如何構造一個大頂堆

建立一個大頂堆是從最后一個非葉子結點開始從下往上調整的,也就是從最后一個結點的父結點開始。

這里以int a[6] = {7, 3, 8, 5, 1, 2}為例子。數組的長度是6,則最后一個結點的下標是5.
在這里插入圖片描述

先要找到最后一個結點的父結點:(5-1)/2=2。2所對應的數是8。然后比較該結點值和它的左右孩子結點的值,如果小于其左右孩子的值,就交換,把最大左右孩子最大的值放到該結點
8只有一個左子樹,左子樹的值為2,不需要跳轉
在這里插入圖片描述
下一步,繼續找到下一個非葉子結點(其實就是當前坐標-1就行了),該結點的值是3,小于其左子樹的值,交換值。
在這里插入圖片描述
在這里插入圖片描述
下一步,繼續找下一個非葉子結點,該結點的值是7,小于右子樹,需要交換
在這里插入圖片描述
在這里插入圖片描述
下一步,檢查調整后的子樹,是否滿足大頂堆的性質,如果不滿足則繼續調整(這里因為只將右子樹的值與根節點互換,只需要檢查右子樹是否滿足,而7>2剛好滿足大頂堆的性質,就不需要調整了)

到這里大頂堆的構造就完成了。

排序

大頂堆已經構造好了,下一步交換根結點和最后一個結點(將最大值放到數組末端),此時最大的元素就歸位了,然后對剩下的5個元素重復上面的步驟:
在這里插入圖片描述
剩下只有5個元素,把剩下的結點變為大頂堆
在這里插入圖片描述

將根結點(7)與最后一個結點交換:
在這里插入圖片描述
依次類推,最后得到排好序的數組:
在這里插入圖片描述

/* Function: 構建大頂堆 */
void BuildMaxHeap(int *heap, int len)
{int i;int temp;for (i = len/2-1; i >= 0; i--){if ((2*i+1) < len && heap[i] < heap[2*i+1])    /* 根節點小于左子樹 */{temp = heap[i];heap[i] = heap[2*i+1];heap[2*i+1] = temp;/* 檢查交換后的左子樹是否滿足大頂堆性質 如果不滿足 則重新調整子樹結構 */if ((2*(2*i+1)+1 < len && heap[2*i+1] < heap[2*(2*i+1)+1]) || (2*(2*i+1)+2 < len && heap[2*i+1] < heap[2*(2*i+1)+2])){BuildMaxHeap(heap, len);}}if ((2*i+2) < len && heap[i] < heap[2*i+2])    /* 根節點小于右子樹 */{temp = heap[i];heap[i] = heap[2*i+2];heap[2*i+2] = temp;/* 檢查交換后的右子樹是否滿足大頂堆性質 如果不滿足 則重新調整子樹結構 */if ((2*(2*i+2)+1 < len && heap[2*i+2] < heap[2*(2*i+2)+1]) || (2*(2*i+2)+2 < len && heap[2*i+2] < heap[2*(2*i+2)+2])){BuildMaxHeap(heap, len);}}}
}/* Function: 交換交換根節點和數組末尾元素的值*/
void Swap(int *heap, int len)
{int temp;temp = heap[0];heap[0] = heap[len-1];heap[len-1] = temp;
}int main()
{int a[6] = {7, 3, 8, 5, 1, 2};int len = 6;    /* 數組長度 */int i;for (i = len; i > 0; i--){BuildMaxHeap(a, i);Swap(a, i);}for (i = 0; i < len; i++){printf("%d ", a[i]);}return 0;
}

3 冒泡排序

https://www.runoob.com/w3cnote/bubble-sort.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/379505.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/379505.shtml
英文地址,請注明出處:http://en.pswp.cn/news/379505.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

CSS Hack 匯總快查

*:lang(zh) select {font:12px !important;} /*FF的專用*/ select:empty {font:12px !important;} /*safari可見*/ 這里select是選擇符&#xff0c;根據情況更換。第二句是MAC上safari瀏覽器獨有的。 僅IE7識別 *html {…} 當面臨需要只針對IE7做樣式的時候就可以采用這個HACK…

杭電2013-蟠桃記(C++)

Problem Description 喜歡西游記的同學肯定都知道悟空偷吃蟠桃的故事&#xff0c;你們一定都覺得這猴子太鬧騰了&#xff0c;其實你們是有所不知&#xff1a;悟空是在研究一個數學問題&#xff01; 什么問題&#xff1f;他研究的問題是蟠桃一共有多少個&#xff01; 不過&#…

c#中重載單目運算符-_C#程序重載二進制運算符(-,*,/)

c#中重載單目運算符-Here, we will design overloaded methods for binary operators: minus, multiply and divide. In the below program, we will create a Calculator class with data member val. 在這里&#xff0c;我們將為二進制運算符設計重載方法&#xff1a;減&…

項目總結:華南師范大學校園開發教育android客戶端總結

忽略之前小打小鬧&#xff0c;這個項目算是我的第一個項目--SCNU的網絡公選課的android版本的客戶端。項目是從5月中旬開始的&#xff0c;中間經歷了幾個星期的復習考試時間&#xff0c;到現在可以說是完工了吧&#xff08;或許還有寫細節要修改&#xff09;。這個項目帶給我蠻…

火鳥字幕合并器

火鳥字幕合并器-區塊獨立勾選-保存。漢王 PDF OCR轉載于:https://www.cnblogs.com/hnytwn/archive/2009/10/31/1593395.html

Linux系統編程---守護進程

1 守護進程的概述 Daemon&#xff08;守護進程&#xff09;是運行在后臺的一種特殊進程。它獨立于控制終端并且周期性地執行某種任務或等待處理某些發生的事件。它不需要用戶輸入就能運行而且提供某種服務&#xff0c;不是對整個系統就是對某個用戶程序提供服務。Linux系統的大…

c ++明明的隨機數_從列表C ++程序中隨機建議電影

c 明明的隨機數Problem statement: 問題陳述&#xff1a; Write an application code that will suggest movies from a list randomly and there wont be any repeat while suggesting the movies. That means the same movie wont be suggested twice though it will be don…

郵箱服務器

一&#xff0e;郵箱服務器的基本概念 郵件的客戶端&#xff1a;可以只安裝在電腦上&#xff08;C/S&#xff09;的也可以是網頁形式&#xff08;B/S&#xff09;的 郵件服務器&#xff1a;起到郵件的接受與推送的作用 郵件發送的協議&#xff1a; 協議&#xff1a;就是數據傳輸…

C#提高保存jpg圖像的質量

在程序中直接生成的jpg圖像&#xff0c;漢字有毛邊&#xff0c;經過一番搜索&#xff0c;在msdn上發現了下面控制jpg質量系數的文章&#xff0c;修改后試了一下&#xff0c;效果確實比前面強多了。原理我也不大懂&#xff0c;把代碼貼出來&#xff0c;與大家共享。 聯合圖…

延遲和定時器管理

文章目錄1 內核中時間概念2 標準定時器jiffies和HZ定時器API標準定時器案例3 高精度定時器(HRT)高精度定時器案例4 內核中延遲和睡眠原子上下文非原子上下文1 內核中時間概念 時間概念對計算機來說有些模糊&#xff0c;事實上內核必須在硬件的幫助下才能計算和管理時間。硬件為…

Web開發工具(插件)收集

1.IE Developer Toolbar 瀏覽和修改&#xff0c;選定Web頁上的特定元素&#xff0c;查看HTML對象的類名、ID&#xff0c;以及類似鏈接路徑、tab順序、快捷鍵等。 2.HttpWatch Professional 一款強大的網頁數據分析工具,可以查看當前網頁的http數據 FireFox插件 FireFox下插件實…

cin、cin.get()、cin.getline()、getline()、gets()等函數的用法

轉載&#xff0c;并經過本人補充cin、cin.get()、cin.getline()、getline()、gets()等函數的用法2007/10/27 22:51學C的時候&#xff0c;這幾個輸入函數弄的有點迷糊&#xff1b;這里做個小結&#xff0c;為了自己復習&#xff0c;也希望對后來者能有所幫助&#xff0c;如果有差…

Java StringBuilder subSequence()方法與示例

StringBuilder類subSequence()方法 (StringBuilder Class subSequence() method) subSequence() method is available in java.lang package. subSequence()方法在java.lang包中可用。 subSequence() method is used to return the new set of a character sequence that is a …

Linux設備驅動開發---設備樹的概念

文章目錄1 設備樹機制命名約定別名、標簽和phandleDT編譯器2 表示和尋址設備SPI和I2C尋址平臺設備尋址3 處理資源提取特定應用數據文本字符串單元格和無符號的32位整數布爾提取并分析子節點4 平臺驅動程序與DTOF匹配風格處理非設備樹平臺平臺數據與DT設備樹&#xff08;DT&…

【轉】C#中數組復制的4種方法

C#中數組復制的4種方法 from&#xff1a;http://blog.csdn.net/burningcpu/article/details/1434167今天旁邊的同事MM叫我調了一段程序&#xff0c;她想復制一個數組&#xff0c;int[] pins {9,3,4,9};int [] alias pins;這里出了錯誤&#xff0c;也是錯誤的根源&#xff0c…

Java StringBuilder codePointAt()方法與示例

StringBuilder類codePointAt()方法 (StringBuilder Class codePointAt() method) codePointAt() method is available in java.lang package. codePointAt()方法在java.lang包中可用。 codePointAt() method is used to return the Unicode code point at the given indices an…

用戶虛擬地址轉化成物理地址,物理地址轉換成內核虛擬地址,內核虛擬地址轉換成物理地址,虛擬地址和對應頁的關系

文章目錄1. 用戶虛擬地址轉換成物理地址2. 內核虛擬地址轉換成物理地址3. 物理地址轉換成內核虛擬地址4 內核虛擬地址和對應頁5 根據進程號獲取進程描述符1. 用戶虛擬地址轉換成物理地址 static void get_pgtable_macro(void) {printk("PAGE_OFFSET 0x%lx\n", PAGE…

簡單三層架構(登錄)

1&#xff0c;首先導包 dao //獲取數據String username request.getParameter("username");String password request.getParameter("password");//傳遞到Service層UserService service new UserService();//這里的UserService 需要創建到service包下Use…

通過隱藏option實現select的聯動效果

開始的時候需求是根據一定條件隱藏一部分<option>標簽&#xff0c;類似聯動效果&#xff0c;但是目前的html規范并沒有為<option>提供隱藏的效果&#xff0c;因此常用的設置display或者visibility無效。網上大部分解決方案是刪除<option>節點或<option>…

Java SimpleTimeZone setEndRule()方法與示例

SimpleTimeZone類setEndRule()方法 (SimpleTimeZone Class setEndRule() method) Syntax: 句法&#xff1a; public void setEndRule(int en_mm, int en_dd, int en_time);public void setEndRule(int en_mm, int en_dd, int en_dow, int en_time);public void setEndRule(int…