1. 程式人生 > >排序演算法學習:快速的桶排序

排序演算法學習:快速的桶排序

排序原理

這裡寫圖片描述
假設現在要對5 3 5 2 8這幾個數進行排序。我們申請一個大小為9的陣列(待排序數中最大數+1),假設為9個木桶,把9個木桶置為0,如圖:
這裡寫圖片描述

然後在對應桶的編號(這就是為什麼要設定為待排序陣列中最大數+1了)中標記1,如圖在a[5]中標記為1,表示待排陣列中有5,並且5在a[5]這個位置。
這裡寫圖片描述

繼續向後標記

這裡寫圖片描述

如果遇到重複的數字,比如兩個5,就在該位置a[5]置為2,表示有兩個5

這裡寫圖片描述

這裡寫圖片描述
把所有要排序的數字都在對應位置的桶中做了標記,把被標記的桶中的編號順序取出來,就是排好的順序,如圖取出為2 3 5 5 8。

程式碼示例:

/*********************************************************************************
 *      Copyright:  (C) 2017 fanmaolin<
[email protected]
> * All rights reserved. * * Filename: bucketsort.c * Description: This file * * Version: 1.0.0(08/05/2017) * Author: fanmaolin <[email protected]> * ChangeLog: 1, Release initial version on "08/05/2017 08:55:48 PM" * ********************************************************************************/
#include <stdio.h> int i; int j; void bucketsort(int A[],int a[], int n) { int *p;//定義一個指標,指向木桶陣列 p = a; for(i = 0;i < n;i++)//對桶中對應陣列進行1的標記 { p[A[i]]++; } printf("列印木桶a[]的標號:"); for(i = 0; i <= 8; i++) { printf("%d ", p[i]); } for
(i = 0, j = 0;i <= 8;i++)//進行桶排序 { while((p[i]--) > 0)//如果有標記,標記幾次就列印幾次 { A[j++] = i; //把桶中對應的數賦值給對應的A[]中 } } bucketsort.c } int main() { int A[] = {3, 0, 8, 2, 1, 5}; //要進行排序的數字 int a[9]; //建立一個排序陣列中最大數+1大小的陣列,比如現在要排序陣列中最大數為8,就要建立一個max+1的陣列 int n = sizeof(A)/sizeof(int); for(i = 0; i < 9; i++ )//對木桶賦0值 { a[i] = 0; } for(i = 0; i < n; i++)//列印未排序陣列 { printf("%d ", A[i]); } printf("\n"); bucketsort(A, a, n);//進行桶排序 printf("\n"); printf("列印桶排序結果:"); for(i = 0; i < n; i++) { printf("%d ", A[i]); } printf("\n"); }

結果:

[fanmaolin@Centeros paixu]$ gcc bucketsort.c          
[fanmaolin@Centeros paixu]$ ./a.out 
3 0 8 2 1 5 
列印木桶a[]的標號:1 1 1 1 0 1 0 0 1 
列印桶排序結果:0 1 2 3 5 8 

排序特點

優點:速度快,簡單
缺點:佔空間大,如果你要排的數字中有1000,你就要申請1001大小的陣列。

總結:

1、演算法重在理解,多看資料。

2、錯誤:

[[email protected] paixu]gccbucketsort.c[fanmaolin@Centerospaixu] ./a.out
3 0 8 2 1 32766
列印木桶a[]的標號:1 1 1 1 0 0 0 0 1
列印桶排序結果:0 1 2 3 8 32766

多列印了32766,這並不是我需要的數

原因:
for(i = 0; i <= n; i++)//多列印了一位,而那一位我們並沒有賦值,是個垃圾資料
64 {
65 printf(“%d “, A[i]);
66 }

改為:for(i = 0; i < n; i++)

注意我的程式中用指標p指向木桶陣列,標記它的位置,在這裡不用指標會出錯,反覆列印