C++ 計數排序演算法的實現與改進(含筆試面試題)
計數排序侷限性比較大,演算法思想:假定輸入是有一個小範圍內的整數構成的(比如年齡等),利用額外的陣列去記錄元素應該排列的位置,思想比較簡單。
計數排序是典型的不是基於比較的排序演算法,基於比較的排序演算法最少也要O(nlogn),有沒有可能創造線性時間的排序演算法呢?那就是不基於比較的排序演算法;
如果陣列的資料範圍為0~100,則很適合此演算法。計數排序使用一個額外的陣列C,其中第i個元素是待排序陣列A中值等於i的元素的個數。然後根據陣列C來將A中的元素排到正確的位置。它只能對整數進行排序
演算法步驟:
1、找出待排序的陣列中最大和最小的元素
2、統計陣列中每個值為i的元素出現的次數,存入陣列C的第i項
3、對所有的計數累加(從C中的第一個元素開始,每一項和前一項相加)
4、反向填充目標陣列:將每個元素i放在新陣列的第C(i)項,每放一個元素就將C(i)減去1
實現程式碼:
/*************************************************************************** * @file main.cpp * @author MISAYAONE * @date 27 March 2017 * @remark 27 March 2017 * @theme Counting Sort ***************************************************************************/ #include <iostream> #include <vector> #include <time.h> #include <Windows.h> using namespace std; void Counting_sort(int a[], size_t n, int k) { //申請額外空間 int *p = new int[n]; int *q = new int[k+1]; for (int i = 0; i < k; ++i) { q[i] = 0;//將q指向的陣列所有元素置0 } //儲存陣列a中每個元素出現的個數,將排序交給了q陣列(其順序在q陣列中就是有序的) for (int j = 0; j < n; ++j) { q[a[j]]++ ; } //將所有計數次數累加 for (int i = 1; i < k; ++i) { q[i] = q[i] + q[i-1]; } //將元素重新輸入 for (int i = n-1; i >= 0; --i) { //次數大小最小為1、陣列開始為0 p[q[a[i]]-1] = a[i]; q[a[i]]--; } for (int j = 0; j < n; ++j) { a[j] = p[j]; } //不要忘了釋放分配的空間 delete []p; delete []q; } int main(int argc, char **argv) { int a[10] = {2,56,4,2,9,56,3,59,9,16}; int max = a[0]; for (int i = 1;i < 10; ++i) { if (a[i]>max) { max = a[i]; } } Counting_sort(a,10,max+1);//傳入max+1是為了讓計數的陣列從0開始足夠大 for (int i = 0; i < 10; ++i) { cout<<a[i]<<" "; } cin.get(); return 0; }
複雜度分析:
在一定限制下時間複雜度為O(n),額外空間O(n)(需要兩個陣列)
O(n+k), n為原陣列長度,k為資料範圍
特點:穩定排序stable_sort,out_place排序
例題1、某地區年齡排序問題?
夠典型的計數排序吧,年齡的區間也就那麼大,程式碼就不上了,請參照上述參照計數排序演算法。
相關推薦
C++ 計數排序演算法的實現與改進(含筆試面試題)
計數排序侷限性比較大,演算法思想:假定輸入是有一個小範圍內的整數構成的(比如年齡等),利用額外的陣列去記錄元素應該排列的位置,思想比較簡單。 計數排序是典型的不是基於比較的排序
C++ 氣泡排序演算法的實現與改進(含筆試面試題)
氣泡排序(Bubble sort)也是一種簡單直觀的排序演算法。它重複地走訪過要排序的數列,一次比較兩個元素,如果他們的順序錯誤就把他們交換過來。走訪數列的工作是重複地進行直到沒有再需要交換,也就是說該數列已經排序完成。這個演算法的名字由來是因為越小的元素會經由
C++ 插入排序演算法的實現與改進(含筆試面試題)
插入排序是一種最簡單直觀的排序演算法,它的工作原理是通過構建有序序列,對於未排序資料,在已排序序列中從後向前掃描,找到相應位置並插入。 簡單小tips:假設一個數列:1、2、5、3。插入排
C++ 堆排序演算法的實現與改進(含筆試面試題)
堆排序(Heap sort)是指利用堆這種資料結構所設計的一種排序演算法。堆積是一個近似完全二叉樹的結構,並同時滿足堆積的性質:即子結點的鍵值或索引總是小於(或者大於)它的父節點。堆排序可以用到上一次
高階排序演算法實現與優化
本文用到的測試資料生成的程式碼和分析:《測試資料自動生成》 文章圖片來源於 GitHub,網速不佳的朋友請點我看原文。 順便軟廣一下個人技術小站:godbmw.com。歡迎常來 ♪(^∇^*) 1. 談談高階排序 本文主要介紹高階排序演算法中的歸併排序和快速排序。他們有運用了分支思想,並且大多通過遞迴來實現。
高自由度:c++八大排序演算法實現程式碼和原理
網上有很多八大排序的程式碼,不過那都比較簡約,只是想表明演算法原理。當然也有個人的部落格寫的也是很好的。我寫的八大排序演算法有以下幾個特點:1、只要改變一個數值,就能實現從小到大或從大到小的排序。2、改變一個N的值可以隨便改變排序陣列的元素的多少。3、排序適合int、lon
計數排序演算法(C語言實現)
計數排序, 比較適合數值跨度比較小的, 也就是陣列中最大值減去最小值得到的值儘量小, 同時陣列元素又比較多的情況下用計數排序效率比較高,同時,計數排序演算法基友穩定性。 計數排序的時間複雜度為O(n),計數排序是用來排序0到100之間的數字的最好的演算法。 演算法的步
常見排序演算法總結與分析之交換排序與插入排序-C#實現
# 前言 每每遇到關於排序演算法的問題總是不能很好的解決,對一些概念,思想以及具體實現的認識也是模稜兩可。歸根結底,還是掌握不夠熟練。以前只是看別人寫,看了就忘。現在打算自己寫,寫些自己的東西,做個總結。本篇是這個總結的開始,所以我們先來闡述一下本次總結中會用到的一些概念。 排序是如何分類的?可以從不同的的角
快速排序演算法實現 C# 版本
採用遞迴思想 實現了 快速排序演算法 如下: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespa
希爾排序演算法原理與實現
1.問題描述 輸入:n個數的序列<a1,a2,a3,...,an>。 輸出:原序列的一個重排<a1*,a2*,a3*,...,an*>;,使得a1*<=a2*<=a3*<=...<=an*。 2. 問題分析 例如,假設有
希爾排序演算法實現(C++)
希爾排序是一種按照增量排序的方法。其中增量值是小於n的正整數。 shell排序的基本思想[1]是: 先取一個小於n的整數d1作為第一個增量,把檔案的全部記錄分成d1個組。所有距離為dl的倍數的記錄放在同一個組中。先在各組內進行直接插人排序;然後,取第二個增量d2<d1重複上述的分組和排序,直
C#常用8種排序演算法實現以及原理簡介
public static class SortExtention { #region 氣泡排序 /* * 已知一組無序資料a[1]、a[2]、……a[n],需將其按升序排列。首先比較a[1]與a[2]的值,若a[1]大於a[
Java排序演算法分析與實現:快排、氣泡排序、選擇排序、插入排序、歸併排序(一)
轉載 https://www.cnblogs.com/bjh1117/p/8335628.html 一、概述: 本文給出常見的幾種排序演算法的原理以及java實現,包括常見的簡單排序和高階排序演算法,以及其他常用的演算法知識。 簡單排序:氣泡排序、選擇排序、
時間複雜度為O(N*logN)的常用排序演算法總結與Java實現
時間複雜度為O(N*logN)的常用排序演算法主要有四個——快速排序、歸併排序、堆排序、希爾排序1.快速排序·基本思想 隨機的在待排序陣列arr中選取一個元素作為標記記為arr[index](有時也直接選擇起始位置),然後在arr中從後至前以下標j尋找比arr[inde
計數排序的理解與實現
計數排序是一種非基於比較的排序演算法,其空間複雜度和時間複雜度均為O(n+k),其中k是整數的範圍。基於比較的排序演算法時間複雜度最小是O(nlogn)的。注意:計數排序對於實數的排序是不可行的(下面會解釋)。該演算法於1954年由 Harold H. Sewar
八大排序演算法總結與Java實現
概述 因為健忘,加上對各種排序演算法理解不深刻,過段時間面對排序就蒙了。所以決定對我們常見的這幾種排序演算法進行統一總結,強行學習。首先羅列一下常見的十大排序演算法: 直接插入排序 希爾排序 簡單選擇排序 堆排序 氣泡排
常見排序演算法彙總與分析(下)(基數排序與計數排序)
本篇彙總的演算法將不再是基於比較的排序演算法,因此會突破這類演算法的時間複雜度下界O(nlog2n)。如果有朋友對前面的內容感興趣,可以先去看看常見排序演算法彙總與分析(中)(選擇排序與歸併排序) 我們先來總結基數排序演算法,該演算法在排序過程中不進行比較,而是通過“分
九種排序演算法總結與Java實現
一、九種排序演算法總結 平均時間複雜度O(n^2): 氣泡排序、選擇排序、插入排序 平均時間複雜度O(nln): 快速排序、歸併排序、堆排序 時間複雜度介於O(nlgn)和O(n^2):希爾排序 時間複雜度O(n+k):計數排序 時間複雜度O(d(n+k)):基數排序
常用資料結構與排序演算法實現、適用場景及優缺點(Java)
1.下壓棧(後進先出)(能夠動態調整陣列大小的實現): package Chapter1_3Text; import java.util.Iterator; public class ResizingArrayStack<Item> implements
go實現計數排序演算法
前面我們詳細講解了計數排序演算法,今天我們用程式碼來實現 package main import "fmt" //計數排序 func countingSort(theArray[] int)[]int{ lastArray := make([]int,len(the