排序总结系列八:桶排序Bucket sort(基数排序)

桶排序Bucket sort(基数排序)

补充说明三点
1,桶排序是稳定的
2,桶排序是常见排序里最快的一种,比快排还要快…大多数情况下
3,桶排序非常快,但是同时也非常耗空间,基本上是最耗空间的一种排序算法
RadixSort.cpp
static int GetMaxFigure(int *arr,int len)//得到一组数的最大值,并返回其位数
{
	int count = 0;
	int max = arr[0];                            //得到一组数的最大值
	for(int i=1; i<len; i++)
	{
		if(max < arr[i])
		{
			max = arr[i];
		}
	}

	do
	{
		count++;
		max /= 10;
	}while(max != 0);

	return count;                                //返回其位数
}

static int GetNum(int num, int figure) //从最高位开始,每次得到一位
{
	for(int i=0; i<figure; i++)
	{
		num /= 10;
	}
	return num % 10;
}

static void Radix(int *arr,int len, int figure)
{
	HNode hrr[10];                                        //用双向链表模拟十个桶
	int i;
	int index;
	for(i=0; i<10; i++)                                   //对十个桶进行初始化
	{
		InitList(&hrr[i]);
	}

	for( i=0; i<len;i++)
	{
		index = GetNum( arr[i],  figure);    //将所有数字按从最高位入桶
		Push(&hrr[index], arr[i]);
	}

	index = 0;
	for(i=0; i<len; )
	{
		if(Pop(&hrr[index],  &arr[i]))       //将数字按位数从新出到arr中
		{
			i++;
		}
		else
		{
			index++;                            //直到一桶出空才处出下一桶
		}
	}
}

void RadixSort(int *arr,int len)
{
	int figure = GetMaxFigure(arr,len);//将最大数的位数最为循环次数
	for(int i=0; i<figure;i++)
	{
		Radix(arr,len,i);                        //从高到底位排序
	}
}
/
#include"NodeHNode.h"
//用链队来处理10个桶
typedef struct Node
{
	int data;
	struct Node *next;
}Node;
typedef struct HNode
{
	Node * front;
	Node * rear;
}HNode,*List;

void InitList(List plist);
bool Push(List plist,int val);
bool Pop(List plist,int *rtval);
void Show(List plist);

void InitList(List plist)
{
	assert(plist != NULL);
	 
	plist->front = plist->rear = NULL;
}

static Node *BuyNode(int val)
{
	Node *p = (Node*)malloc(sizeof(Node));
	assert(p != NULL);

	p->data = val;
	p->next = NULL;

	return p;
}

bool Push(List plist,int val)
{
	Node *p = BuyNode(val);

	if(plist->front == NULL)
	{
		plist->front = plist->rear= p;
	}
	else
	{
		plist->rear->next = p; //崩溃
		plist->rear= p;
	}
	return true;
}

bool Pop(List plist,int *rtval)
{
	if(plist->front == NULL)
	{
		return false;
	}

	Node *p = plist->front;
	*rtval = p->data;
	plist->front = p->next;
	free(p);

	if(plist->front == NULL)
	{
		plist->rear = NULL;
	}
	return true;
}

void Show(List plist)
{
	for(Node *p=plist->front; p!=NULL; p=p->next)
	{
		printf("%4d", p->data);
	}
	printf("\n");
}<span style="font-size: 18px; line-height: 1.5; white-space: pre-wrap; font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">/</span>
桶排序 (Bucket sort)或所谓的箱排序,工作的原理是将阵列分到有限数量的桶子里。每个桶子再个别排序(有可能再使用别的 排序算法 或是以递回方式继续使用桶排序进行排序)。桶排序是 鸽巢排序 的一种归纳结果。当要被排序的阵列内的数值是均匀分配的时候, 桶排序使用线性时间( Θ (n)) 。但桶排序并不是 比较排序 ,他不受到 O(n log n) 下限的影响。
下列程序进行 : 
   1. 设置一个定量的阵列当作空桶子。 
   2.寻访序列,并且把项目一个一个放到对应的桶子去。 
   3.对每个不是空的桶子进行--(插入)排序--。 
   4. 从不是空的桶子里把项目再放回原来的序列中。 
 
    适用于位数相同,均匀分布的数列 
   尤其例如: 
         13,52,16,31,64,16,24,34,82,67,43,56,68,46,90,84,98,26 
#define radix  10  
#define interval 10  
  
struct Bucket
{  
    int key;  
    Bucket *next;  
    Bucket()
{  
        key=NULL;  
        next=NULL;
}  
};  
  
void bucketSort(int A[], int len)  
{  
    Bucket buckets[radix];  
    int i;  
    Bucket *temp, *parent, *newNode;  
    for(i=0; i< len; i++)  
    {  
        temp = &buckets[ A[i]/interval ];          
        if(temp->key == NULL)  
        {  
            temp->key = A[i];  
        }
else
{  
            if(A[i] < temp->key)              //在已存在数据的捅最前端插入数据  
            {  
                newNode = new Bucket;  
                newNode->key = temp->key;  
                newNode->next = temp->next;  
                temp->key = A[i];  
                temp->next = newNode;  

            }
else
{                              //插入排序  
                parent=temp;  
                temp=temp->next;  
                while(temp)  
                {  
                    if(A[i]<temp->key) break;  
                    parent = temp;  
                    temp=temp->next;  
                }  
                newNode=new Bucket;  
                newNode->key=A[i];  
                newNode->next=temp;  
                parent->next=newNode;  
                cout<<"--3--A[i]:"<<A[i]<<endl;  
            }  
        }  
    }

    int j=0;  
    for(i=0;i<radix;i++)         //遍历每个捅 便得到有序数列  
    {  
        temp=&buckets[i];  
        while(temp && temp->key!=NULL)//要加上temp->key 因为temp即使没有数据,其也不为空  
        {  
            A[j] = temp->key;  
            temp = temp->next;  
            j++;  
        }  
    }  
}  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值