C++ 桶排序


查了很多文章,桶排序思想简单,实现起来有点复杂,记录一下桶排序。

一、桶排序是什么?

桶排序(又称箱排序)是一种基于分治思想、效率很高的排序算法,理想情况下对应的时间复杂度为 O(n)。

二、实现思路

1. 分组

将待排数据进行分组,如下图,将这些数组按范围分到各个桶中,此时每个桶中的数据是无序的,我们还需要为每个桶中的数据排序。每个桶中的排序算法选择至关重要。

看了很多教学文章,说每个桶中的数据是用链表存储的,可能为了减少开销吧,不知道用vector存行不行~

在这里插入图片描述

2. 桶内排序

对每个桶内的数据进行排序。
在这里插入图片描述

3. 合并

将排好的各个桶合并。

实现:





```cpp
// 桶排序.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include <vector>
using namespace std;


//每个桶中的元素以链表的方式存在
typedef struct Node {
	Node(int i = 0) :data(i), next(NULL) {}
	int data;
	Node* next;
}Node;

Node* insert(Node* head, int val) { //把变量val按序插入到链表中
	Node* newNode = new Node(val); //为变量开辟内存
	Node *pre,*curr;
	Node dummy;
	dummy.next = head;
	pre = &dummy;
	curr = head;
	while (curr != nullptr && val > curr->data) { //变量如果大于当前节点的值,说明变量不应该在此刻插入
		pre = curr;
		curr = curr->next;
	}
	//如果变量值小于等于当前节点的值,就把这个值插入到当前节点前面
	newNode->next = curr;
	pre->next = newNode;
	return dummy.next;
}

Node* merge(Node* head1, Node* head2) { //把两个链表连在一起,返回的是连接后的链表
	Node* dummy = new Node(0);
	Node* p=dummy;
	while (head1 != nullptr && head2 != nullptr) {
		if (head1->data < head2->data) {
			p->next = head1;
			p = p->next;
			head1 = head1->next;
		}
		else {
			p->next = head2;
			p = p->next;
			head2 = head2->next;
		}
	}
	if (head1 != nullptr) p->next = head1;
	if (head2 != nullptr) p->next = head2;

	return dummy->next;

}

void bucketSort(vector<int> arr) { //对vec中的值进行桶排序
	int n = arr.size();
	int bucketNum = 10;
	vector<Node*> Bucket(bucketNum, (Node * )(0));//每个桶中有一个链表
	for (int i = 0; i < n; i++) {
		int index = arr[i] ;//找到当前元素应该在哪个桶中
		Node* head = Bucket[i]; //定位到桶
		Bucket[i] = insert(head, arr[i]);//把当前元素插入到该桶所在的链表中
	}
	Node* res=Bucket[0];
	for (int i = 1; i < bucketNum; i++) {
		res = merge(res, Bucket[i]);
	}

	for (int i = 0; i < n; i++) {
		arr[i] = res->data;
		res = res->next;
		cout << arr[i] << endl;
	}
}


int main() {
	vector<int> arr{ 4,1,7,6,3,5,0 };
	bucketSort(arr);
}

  • 3
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值