1. 程式人生 > >C++ 計數排序演算法的實現與改進(含筆試面試題)

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