排序總結系列八:桶排序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++;  
        }  
    }  
}  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章