排序算法(八) - 桶排序

桶排序是目前我看到的排序算法中最复杂的一种排序方法了,不是他的排序原理复杂,是实现起来代码量比较复杂。
原理:桶排序的基本思想是将一个数据表分割成许多buckets,然后每个bucket各自排序,或用不同的排序算法,或者递归的使用bucket sort算法。也是典型的divide-and-conquer分而治之的策略。它是一个分布式的排序,介于MSD基数排序和LSD基数排序之间。

步骤:
一、建立一堆buckets;
二、遍历原始数组,并将数据放入到各自的buckets当中;
三、对非空的buckets进行排序;
四、按照顺序遍历这些buckets并放回到原始数组中即可构成排序后的数组。

看一下我写的示例,还是很容易理解的。
C++示例:

#include <iostream>
using namespace std;

/*
 桶排序使用的链表节点
 */
struct Node {
    int data;
    struct Node *next;
};


void quickSort(struct Node *arr, int min, int max) {
    if (min < max) {
        int key = arr[max].data;
        int i = min - 1;
        for (int j = min; j < max; j++) {
            if (arr[j].data <= key) {
                i = i + 1;
                int temp = arr[i].data;
                arr[i].data = arr[j].data;
                arr[j].data = temp;
            }
        }
        int temp = arr[i + 1].data;
        arr[i + 1].data = arr[max].data;
        arr[max].data = temp;
        quickSort(arr, min, i);
        quickSort(arr, i + 1, max);
    }
}

/*
 桶排序
 */
void bucketSort(int arr[], int count) {
    struct Node *buckets[count];

    int maxValue = 0;

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

    int range = maxValue / count + 1;

    // 将arr中的数据分桶放入
    for (int i = 0; i < count; i++) {
        int bucketIndex = arr[i] / range;
        struct Node *current = (struct Node *)malloc(sizeof(struct Node));
        current->data = arr[i];
        current->next = buckets[bucketIndex];
        buckets[bucketIndex] = current;
    }

    // 对每个桶排序,并合并最后结果
    int arrayIndex = 0;
    for (int i = 0; i < count; i++) {
        int size = 0;
        struct Node *node = buckets[i];
        while (node != NULL) {
            size++;
            node = node->next;
        }

        if (size > 0) {
            int tempArr[size];
            node = buckets[i];
            int j = 0;
            while (node != NULL) {
                tempArr[j] = node->data;
                j++;
                node = node->next;
            }
            // 使用快速排序对每个桶排序
            quickSort(tempArr, 0, size - 1);
            for (int k = 0; k < size; k++) {
                arr[arrayIndex] = tempArr[k];
                arrayIndex++;
            }
        }
    }
}

/*
 主函数(入口函数)
 */
int main(int argc, const char * argv[]) {
    int arrA[10] = {12,321,42,53,562,11,4,45,63,543};

//    radixSort(arrA, 10);
    bucketSort(arrA, 10);

    for (int i = 0; i < 10; i++) {
        cout<< arrA[i] << " ";
    }
    cout<< endl;

    return 0;
}

最后结果:这里写图片描述

桶排序的最优时间复杂度是(n)当桶的数量很多的时候,接近于原数组的个数。
桶排序的最差时间复杂度是(n^2)当桶的数量只有一个的时候,效率等同于你排序使用的算法。
桶排序的评价时间复杂度是(n)我们会使用比较多的桶来做排序。

下面是几种算法的时间复杂度比较
这里写图片描述

猜你喜欢

转载自blog.csdn.net/honey199396/article/details/79761996