桶排序詳解以及優化C++代碼

/*
* @Author: hzf
* @Date:   2020-02-29 20:47:49
* @Last Modified by:   hzf
* @Last Modified time: 2020-02-29 21:36:01
*/
/*
 桶排序
 原理:
 準備有限個桶,將一系列數字分批次,按照要求放入桶內,再按照順序取出
 根據數組中的最大數的位數確定取放幾次,根據個位、十位、百位上面的數字確定放入哪個桶中
 
 舉例: 001 012 022 016 123 1236
 最大值爲1234,有四位,所以確定取放四次
 準備六個桶,分別編號爲0 1 2 3 4 5
 第一輪根據個位數放置001進入一號桶,012進入二號桶,022進入二號桶,016進入六號桶
 123 進入三號桶,1236進入六號桶,結果如下:
 一號桶:0001 
 二號桶:0012 0022
 三號桶:0123 
 六號桶:0016 1236
 再依次取出,結果爲: 001 012 022 123 016 1236

 第二次根據十位數字同理放置,結果爲:
 零號桶:001 
 一號桶:012 016
 二號桶:022 123
 三號桶:1236
 六號桶:
取出後爲:001 012 016 022 123 1236

第三次根據百位數字,結果爲:
 零號桶:001 012 016 022
 一號桶:123 1236
 二號桶:
 三號桶:
 六號桶:
 取出後爲:001 012 016 022 123 1236

 第四次根據千位數字,結果爲:
 零號桶:0001 0012 0016 0022 0123
 一號桶:1236
 二號桶:
 三號桶:
 六號桶:
 取出後爲:1 12 16 22 123 1236
*/

#include <iostream>
#include <math.h>
using namespace  std;

int GetLength(int *arr)
{
	return (sizeof(arr)/sizeof(arr[0]));
}

int maxbits(int *arr)
{
	int length = GetLength(arr);
	int maxValue = -1;

	for (int i = 0; i < length; ++i)
	{
		if(arr[i] > maxValue)
			maxValue = arr[i];
	}

	int res = 0;
	while(maxValue != 0)
	{
		res += 1;
		maxValue /= 10;
	}

	return res;
}

/*獲取數字的第i位置上的數字*/
int getDigit(int num, int i)
{
	return (num/pow(10, i - 1) % 10);
}

/*
 begin,end 表示排序範圍
 digit表示取放次數
*/
void radixSort(int *arr, int begin, int end, int digit)
{
	const int radix = 10;//基底
	int i=0, j=0;

	int *bucket = new int[end-begin+1];
	for (int d=0; d<digit; d++)
	{
		/*
		count[0] 表示:當前位置(d)是0的數字有多少個
		count[1] 表示:當前位置(d)是0 1的數字有多少個
		count[2] 表示:當前位置(d)是0 1 2的數字有多少個
		count[3] 表示:當前位置(d)是0 1 2 3的數字有多少個
		……
		*/
		int *count = new int[radix];//count[0……9]
		for (i=begin; i<=end; ++i)
		{
			j = getDigit(arr[i], d);//獲取數字的第d位置上的值
			count[j]++;//對應的桶的容量加一
		}

		for (i = 1; i < radix; ++i)
		{
			count[i] += count[i - 1];//計算前綴和,即第i位置上數字是<=i的總個數
		}

		for (int i = end; i >= begin; ++i)
		{
			/*
			假定這是第一次遍歷,那麼就是個位數字
			從右向左開始,根據當前位置arr[i]的個位數是x,查找count[x],那麼arr[i]就應該排在第x-1位置
			爲什麼?因爲小於等於x的數字共有count[x]個,該數字又是在最右邊,所以是最後一個放進去,也是最後一個取出的
			之後,help[count[x]-1] = arr[i], count[x]-1,下一個(--i)數字
			*/
			j = getDigit(arr[i], d);
			bucket[count[j] - 1] = arr[i];
			count[j]--;
		}

		for (int i = begin; i <= end; ++i)
		{
			/*相當於該輪結束,數字再依次放回,進行下一輪篩選*/
			arr[i] = bucket[j];
		}
	}
}

void radixSort(int *arr)
{
	if(arr == NULL || GetLength(arr) < 2)
		return;

	radixSort(arr, 0, GetLength(arr)-1, maxbits(arr));
}

int main(int argc, char const *argv[])
{
	/* code */
	return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章