1.定义
什么是桶排序?
桶排序就是把数据放到一个桶(容器)中,在这个桶中进行一系列的排序操作,再将桶中的数据传回原处的过程叫做桶排序。
例如:把数组的内容放到一个桶中,在桶中进行排序,类似于哈希查找的拉链法,可参考哈希拉链法的操作处理。
2.桶内排序过程
首先考虑桶内的排序问题;
选择一种排序方式;
在此处可以先构建链表;
struct List { double nVal; List* pNext; };
将数据插入链表中,可理解为入栈:
1.创建添加的节点:
List* pTemp = new List; pTemp->nVal = nVal; pTemp->pNext = nullptr;
2.链表没有节点时:
if (rpHead == nullptr) { rpHead = pTemp; return; }
3.有节点时-头插入:
if (rpHead->nVal > pTemp->nVal)//头插 { pTemp->pNext = rpHead; rpHead = pTemp; return; }
4.有节点时-中间插入:
List* pMark = rpHead; //创建遍历的标记 while (pMark!=nullptr)//遍历链表 { if (rpHead->pNext->nVal > pTemp->nVal) { pTemp->pNext = pMark->pNext; pMark->pNext = pTemp; return; } pMark = pMark->pNext; }
3.桶的创建和使用
通过创建一个List**类型的临时空间(桶)pArr,将要排序的数组arr的数传到桶(pArr)中,再通过(1-4)过程完成排序过程,再将桶(pArr)的值传回数组arr。
[以下两部分为全部代码]:
void BucketSort(double arr[], int nLen) { if (arr == nullptr || nLen <= 0) { return; } //创建临时空间pArr; List** pArr = new List * [10]; //每一个都是指针,所以要对其赋空; memset(pArr, 0, sizeof(List*) * 10); //将数组arr的数全部插入到临时空间中,并通过InsertSortList函数对其排序; for (int i = 0; i < nLen; i++) { int index = arr[i] * 10;//桶(pArr)号 InsertSortList(pArr[index], arr[i]); } //将临时空间pArr的值依次传回原数组arr中 int j = 0; for (int i = 0; i < 10; i++) { while (pArr[i] != nullptr) { List* pDel = pArr[i]; pArr[i] = pArr[i]->pNext; arr[j] = pDel->nVal; j++; delete pDel; pDel = nullptr; } } delete[]pArr; pArr = nullptr; }
InsertSortList函数的代码部分:
void InsertSortList(List*& rpHead,double nVal) { //1.创建添加的新节点 List* pTemp = new List; pTemp->nVal = nVal; pTemp->pNext = nullptr; //2.链表没有节点 if (rpHead == nullptr) { rpHead = pTemp; return; } //3.有节点,进行新节点的头插入操作: if (rpHead->nVal > pTemp->nVal)//头插 { pTemp->pNext = rpHead; rpHead = pTemp; return; } //4.有节点,进行新节点的中间插入操作: List* pMark = rpHead; //创建遍历的标记 while (pMark!=nullptr)//遍历链表 { if (rpHead->pNext->nVal > pTemp->nVal) { pTemp->pNext = pMark->pNext; pMark->pNext = pTemp; return; } pMark = pMark->pNext; } }
4.结果验证
结果验证:
创建一个长度为5的数组,其值全部为小数;
对其进行桶排序;
对排序后的数组遍历;
double arr[5] = { 0.243,0.124,0.413,0.854,0.324 }; BucketSort(arr, 5); for (double nVal : arr) { cout << nVal << " "; } cout << endl;