1. 程式人生 > >計數排序,傳說中時間複雜度O(n+k)的排序演算法

計數排序,傳說中時間複雜度O(n+k)的排序演算法

基本思想

假設數序列中小於元素a的個數為n,則直接把a放到第n+1個位置上。當存在幾個相同的元素時要做適當的調整,因為不能把所有的元素放到同一個位置上。計數排序假設輸入的元素都是0到k之間的整數

回到頂部

參考程式碼

複製程式碼
#include <stdio.h>
void COUNTINGSORT(int *A, int *B, int array_size, int k)
{
        int C[k+1], i, value, pos;
        for(i=0; i<=k; i++)
        {
            C[i] 
= 0; } for(i=0; i< array_size; i++) { C[A[i]] ++; } for(i=1; i<=k; i++) { C[i] = C[i] + C[i-1]; } for(i=array_size-1; i>=0; i--) { value = A[i]; pos = C[value]; B[pos
-1] = value; C[value]--; } } int main() { int A[8] = {2, 5, 3, 0, 2, 3, 0, 3}, B[8], i; COUNTINGSORT(A, B, 8, 5); for (i=0; i<= 7; i++) { printf("%d ", B[i]); } printf("\n"); return 0; }
複製程式碼 回到頂部

圖示

對於資料2 5 3 0 2 3 0 3程式執行的過程如下圖所示:

      現在有個問題,若必須是0到n的自然數,是不是用途很小?我想了想,其實可以任意整數的,即找出最小的數來,看看與0的距離d,把所有的數同時減去d,劃到0到n的範圍內,計數排序。到最後待恢復就可以了。

計數排序的複雜度為Ο(n+k)(其中k是整數的範圍),快於任何比較排序演算法。[1-2]  當然這是一種犧牲空間換取時間的做法,而且當O(k)>O(n*log(n))的時候其效率反而不如基於比較的排序(基於比較的排序的時間複雜度在理論上的下限是O(n*log(n)), 如歸併排序,堆排序)

實現

#include <iostream> using namespace std; const int MAXN = 100000; const int k = 1000; // range int a[MAXN], c[MAXN], ranked[MAXN]; int main() { int n; cin >> n; for (int i = 0; i < n; ++i) { cin >> a[i];  ++c[a[i]]; } for (int i = 1; i < k; ++i) c[i] += c[i-1]; for (int i = n-1; i >= 0; --i) ranked[--c[a[i]]] = a[i]; for (int i = 0; i < n; ++i) cout << ranked[i] << endl; return 0; }

C語言實現

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18

相關推薦

計數排序傳說時間複雜O(n+k)的排序演算法

基本思想 假設數序列中小於元素a的個數為n,則直接把a放到第n+1個位置上。當存在幾個相同的元素時要做適當的調整,因為不能把所有的元素放到同一個位置上。計數排序假設輸入的元素都是0到k之間的整數。 回到頂部 參考程式碼 #include &

並行排序演算法——時間複雜O(n)的排序

最近老師講了並行的排序演算法,讓我對這個原來不是很瞭解的排序演算法產生了濃厚的興趣。並行排序方法,是指採用平行計算的方法對一組資料進行排序,理論上是在類似內排序的環境下,採用多核並行的方法讓時間降低,排序的複雜度最好的情況下能降低至O(n)左右。 排序的實質

一個時間複雜O(n)空間複雜O(1)的排序演算法

其實就是利用Hash的思想,開闢一個固定長度的hash陣列用於標記待排序陣列的資料元素是否出現過。由於固定長度的hash陣列,所以空間複雜度與待排序陣列資料規模n沒有關係,也就是說空間複雜度為O(1)。

Morris遍歷詳解——二叉樹先序序後序遍歷( 時間複雜O(N)空間複雜O(1) )

Morris二叉樹遍歷: 來到當前的節點:Cur 如果Cur無左孩子,Cur向右移動 (Cur = Cur.right) 如果Cur有左孩子,找到Cur左子樹上最右的節點,記為 mostright

陣列只出現一次的數字時間複雜O(n),空間複雜O(1)的解法

題目:一個整型數組裡除了兩個陣列外,其他的數字都出現了兩次,要找出這兩個數字。      異或運算有一個性質:任何數異或它自己,結果都是0;這樣如果題目變成只有一個數字只出現一次,其他數字均出現兩次,這樣我們從頭到尾異或陣列中的每一個數字,那麼最終的結果就是隻出現一次的數字

尋找主元素演算法時間複雜O(N)C#)

主元素問題:大小為N的陣列A,其主要元素是一個出現次數超過N/2的元素。 最近在學習演算法,書上發現這樣一道題,並且提供了一種遞迴演算法的概要,但是感覺不是特別好(遞迴判斷(時間複雜度大於O(N)了),還要對N的奇偶做出判斷以及使用附加陣列B),網上看了一下有一個SEO排行最靠前的(不說名字了,

找出大陣列arrayk大的元素(要求時間複雜O(n))

具體的程式碼實現:import java.util.Stack; /** * @author wuwh * @date createTime:2016年3月6日 上午12:23:14 */ public class KthBiggest { public static

八大排序演算法JAVA實現(時間複雜O(n-logn)篇)

本文講述時間複雜度為n*logn的排序演算法:歸併排序、快速排序、堆排序以及希爾排序的原理、Java實現以及變形應用。 一、歸併排序  原理:把兩個有序數列合併為一個有序數列。需遞迴實現。  Java實現: 1 public int[] mergeSort(in

八大排序演算法JAVA實現(時間複雜O(n-n)篇)

本文主要描述3個時間複雜度為n2的排序演算法:氣泡排序、選擇排序、插入排序。 1.氣泡排序:由陣列頭部開始,一次比較兩個元素,如果他們的順序錯誤就把他們交換過來。每次交換完成後,當前陣列最大值就會被放在最後。 1 public int[] bubbleSort

最壞時間複雜N^2排序(冒泡-選擇-插入)

氣泡排序 public void bubblesort(int a[]) { int len=a.length; int i=len-1; int last=0; while(

Manacher演算法最長迴文串時間複雜O(n)

最長迴文子串 問題 對於一個字串,請設計一個高效演算法,計算其中最長迴文子串的長度。 給定字串A以及它的長度n,請返回最長迴文子串的長度。 測試樣例: “abc1234321ab”,12 返回:7 中心擴充套件到Manache

N個字元的陣列迴圈右移K位。時間複雜O(N)。

將N個字元的陣列,迴圈右移K位。時間複雜度O(N) eg:str[]=”abcde123”,右移3位 1、旋轉abcde->edcba 2、旋轉123->321 3、整體旋轉

時間複雜O(n)什麼意思

時間複雜度O(n)什麼意思 2018年11月29日 14:55:38 Super_King_ 閱讀數:33 標籤: 演算法時間複雜度 更多 個人分類: 後端 時間複雜度  演算法分析  同一問題可用不同演算法

BFPRT演算法時間複雜O(n)求第k小的數字(分治演算法+快排)

去年寫了一篇《分治演算法 求第 k k k小元素

判斷一個數是不是素數 埃拉託斯特尼篩法 時間複雜 O(n*lglgn)

說明: 素數的定義:質數(prime number)又稱素數。一個大於1的自然數,除了1和它本身外,不能被其他自然數整除,換句話說就是該數除了1和它本身以外不再有其他的因數;否則稱為合數。 最小的素數是2,最小的合數是4 方法一: 根據素數的定義,判斷數n是不是素數,我們

最大子序列的和演算法-時間複雜O(n)

#include<iostream> using namespace std; int MaxSubseqSum(int ar[],int n){ int ThisSum=0,MaxSu

php多維陣列的去重(針對任意的鍵值進行去重)--二維陣列的唯一--時間複雜~O(n)

以二維陣列為例,來說明針對任意鍵值的去重,時間複雜度為~O(n),只用一個foreach迴圈: <?php $arr = array( '0'=>array(

1134 最長遞增子序列(時間複雜O(n*log(n))

基準時間限制:1 秒 空間限制:131072 KB 分值: 0 難度:基礎題 Description 給出長度為N的陣列,找出這個陣列的最長遞增子序列。(遞增子序列是指,子序列的元素是遞增的) 例如:5 1 6 8 2 4 5 10,最長遞增

編寫程式在一非遞減的順序表L刪除所有值相等的多餘元素。要求時間複雜On空間複雜O(1)

翠花上程式碼: Status delExcrescentValue(SeqList &S){ int flag = 0,val = S.elem[0];//記錄值不等的下標 //printf("%d\n",S.elem[0]); for(int i = 1;i

題目9  單鏈表儲存M個整數設計一個時間複雜儘可能高效的演算法

單鏈表中儲存M個整數,設計一個時間複雜度儘可能高效的演算法,對於連結串列中絕對值相等的元素(|data|<n),只保留第一次出現的節點,刪除其餘的節點。如:15->(-3)->(-15)->3  得:15->(-3)