排序相关算法之桶排序

看千遍知识,不如写百行代码。
开始我的FB之旅。

从最简单的排序开始。写一下桶排序方法。
输入:一堆待排序的数字(10,23,43,54,323…)
输出:排序好的结果

首先简单解释一下什么叫桶排序。首先列出一个数组a[M],我们把这个数组比作大小为M的桶组合, 每个数组元素象征了一个桶。假设待排序的数字总数为N个,将这N个数字丢到M个桶里,丢放规则可以自定,比如可以利用取余法,如针对具体某个数字n,做取余s=n%M,则将该数字n有序的放到第s个桶里。这里放入后会出现两种情况,第一种情况:当桶足够大,待排序数组足够小的话,待排序的数组可以放入互不重叠的桶里,每个桶里只有一个待排序数组的数字或者没有被放入数字。第二种,就是有多余2个数字被丢入了同一个桶里,这里需要做的是,保证每个桶里的数字是有序的。放好后会得到M个有序排列的桶,接下来就需要通过融合,将这M个有序排列的子数组合并成一个长的数组,从而得到排序结果。

所以说事实上,桶排序只是通过增加额外的空间,来进行排序的目的,平均复杂度可以达到O(n)。

实现代码如下:
BucketSort.h

#include<vector>
const int BucketNum = 4;

struct ListNode
{
    int data;
    explicit ListNode(int i) :data(i), mNext(NULL) {}
    ListNode* mNext;
};
class BucketsSort
{
public:
    BucketsSort();
    ~BucketsSort();
    void bucket_sort(int n,int array[]);
private:
    std::vector<ListNode *> buckets;
    ListNode* merge(ListNode *head1,ListNode*head2);
};

BucketSort.cpp

#include "BuctetSort.h"
#include <iostream>
BucketsSort::BucketsSort():buckets() {
    for (int i = 0;i < BucketNum;i++) {
        ListNode *h = new ListNode(0);
        buckets.push_back(h);
    }
}

BucketsSort::~BucketsSort() {
    for (int i = 0;i < buckets.size();i++) {
        buckets[i]->mNext = NULL;
        delete buckets[i];
    }
}


void BucketsSort::bucket_sort(int n, int array[]) {
    for (int i = 0;i < n;i++) {
        int m = array[i] % BucketNum;
        ListNode *p = buckets[m];
        ListNode *q = p->mNext;
        if (q == NULL) {
            p->mNext = new ListNode(array[i]);
        }else {
            while (q!=NULL && q->data > array[i]) {
                q = q->mNext;
                p = p->mNext;
            }
            ListNode *tmp = new ListNode(array[i]);
            p->mNext = tmp;
            tmp->mNext = q;
        }

    }
    ListNode* head = buckets[0]->mNext;
    for (int i = 1;i < BucketNum;i++) {
        head = merge(head, buckets[i]->mNext);
    }
    ListNode *p = head;
    for (int i = 0;i < n;i++) {
        array[i] = head->data;
        head = head->mNext;
    }
    while (p != NULL) {
        ListNode*tmp = p;
        p = p->mNext;
        delete tmp;
    }

}

ListNode* BucketsSort::merge(ListNode *head1, ListNode*head2) {
    ListNode *head=new ListNode(0);
    ListNode *p = head;
    while (head1 != NULL &&head2 != NULL) {
        if (head1->data > head2->data) {
            head->mNext = head1;
            head1 = head1->mNext;
        }
        else {
            head->mNext = head2;
            head2 = head2->mNext;
        }
        head = head->mNext;
    }
    if (head1 == NULL)head->mNext = head2;
    if (head2 == NULL) head->mNext = head1;
    return p->mNext;

}

main 函数

#include "BuctetSort.h"
#include<iostream>
using namespace std;
void print(int n,int array[]) {
    for (int i = 0;i < n;i++) {
        cout << array[i] << "  ";
    }
    cout << endl;
}
int main() {
    const int NUM = 100000;
    BucketsSort *h = new BucketsSort();
    srand((unsigned)time(NULL));
    int *array=new int[NUM];
    for (int i = 0;i < NUM;i++) {
        array[i] = rand()%1000;
    }
    h->bucket_sort(NUM , array);
    delete array;
    delete h;
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值