排序之基数排序

基数排序不是基于比较进行的排序,基数排序是对桶排序的推广;
基数是指进制,10进制的基数就是10, 2进制的基数就是2将待排序的元素分配到桶中;
基数排序分为两种,次位优先,主位优先;
次位优先是从低位的大小开始排序;主位优先是从高位的大小开始排序

//基数排序
#define MaxDight 4
#define Radix 10
typedef struct Node* PtrtoNode;
struct Node  // 桶元素
{
	int Key;
	PtrtoNode Next;
};
typedef struct HeadNode
{
	PtrtoNode Head, Tail;
}Bucket[Radix];

int GetDigit(int X,int d) // 找到X数的第d位数
{
	int i, D;
	for (i = 1; i <= d; i++)
	{
		D = X % Radix;
		X = X / Radix;
	}
	return D;
}
void LSDRadixSort(int A[],int N)
{
	int i,D,Di;
	PtrtoNode List,Tmp,p;
	Bucket B;
	List = NULL;
	for(i = 0;i<Radix;i++) // 初始化桶
	{
		B[i].Head = B[i].Tail = NULL;
	}
	for(i=0;i<N;i++) // 把数组的内容放入链表
	{
		Tmp = (PtrtoNode)malloc(sizeof(struct Node));
		Tmp->Key = A[i];
		Tmp->Next = List;
		List = Tmp;
	}
	for(D = 1;D<=MaxDight;D++) // 低位优先排序
	{
		p = List;
		while(p)  // 链表里的数据进入桶
		{
			Tmp = p;
			p = p->Next;
			Tmp->Next=NULL;
			Di = GetDigit(Tmp->Key,D); // 按照数字的Di位决定进入桶中
			if(B[Di].Head==NULL)
			{
				B[Di].Head=B[Di].Tail=Tmp;
			}
			else
			{
				B[Di].Tail->Next = Tmp;
				B[Di].Tail = Tmp;
			}
		}
		List = NULL;
		for(i=Radix-1;i>=0;i--) // 桶中的数据进入链表
		{
			if(B[i].Head)
			{
				B[i].Tail = List;
				List = B[i].Head;
				B[i].Head = B[i].Tail = NULL;
			}
		}
	}
	for(i=0;i<N;i++)  // 把链表的内容导入数组
	{
		Tmp = List;
		A[i] = Tmp->Key;
		List = List->Next;
		free(Tmp); //释放空间
	}
}
/* 基数排序 - 主位优先 */
 
/* 假设元素最多有MaxDigit个关键字,基数全是同样的Radix */
 
#define MaxDigit 4
#define Radix 10
 
/* 桶元素结点 */
typedef struct Node *PtrToNode;
struct Node{
    int key;
    PtrToNode next;
};
 
/* 桶头结点 */
struct HeadNode {
    PtrToNode head, tail;
};
typedef struct HeadNode Bucket[Radix];
  
int GetDigit ( int X, int D )
{ /* 默认次位D=1, 主位D<=MaxDigit */
    int d, i;
     
    for (i=1; i<=D; i++) {
        d = X%Radix;
        X /= Radix;
    }
    return d;
}
 
void MSD( ElementType A[], int L, int R, int D )
{ /* 核心递归函数: 对A[L]...A[R]的第D位数进行排序 */
     int Di, i, j;
     Bucket B;
     PtrToNode tmp, p, List = NULL; 
     if (D==0) return; /* 递归终止条件 */
      
     for (i=0; i<Radix; i++) /* 初始化每个桶为空链表 */
         B[i].head = B[i].tail = NULL;
     for (i=L; i<=R; i++) { /* 将原始序列逆序存入初始链表List */
         tmp = (PtrToNode)malloc(sizeof(struct Node));
         tmp->key = A[i];
         tmp->next = List;
         List = tmp;
     }
     /* 下面是分配的过程 */
     p = List;
     while (p) {
         Di = GetDigit(p->key, D); /* 获得当前元素的当前位数字 */
         /* 从List中摘除 */
         tmp = p; p = p->next;
         /* 插入B[Di]号桶 */
         if (B[Di].head == NULL) B[Di].tail = tmp;
         tmp->next = B[Di].head;
         B[Di].head = tmp;
     }
     /* 下面是收集的过程 */
     i = j = L; /* i, j记录当前要处理的A[]的左右端下标 */
     for (Di=0; Di<Radix; Di++) { /* 对于每个桶 */
         if (B[Di].head) { /* 将非空的桶整桶倒入A[], 递归排序 */
             p = B[Di].head;
             while (p) {
                 tmp = p;
                 p = p->next;
                 A[j++] = tmp->key;
                 free(tmp);
             }
             /* 递归对该桶数据排序, 位数减1 */
             MSD(A, i, j-1, D-1);
             i = j; /* 为下一个桶对应的A[]左端 */
         } 
     } 
}
 
void MSDRadixSort( ElementType A[], int N )
{ 
    MSD(A, 0, N-1, MaxDigit); 
}

猜你喜欢

转载自blog.csdn.net/weixin_40540957/article/details/84582039