基数排序-队列实现

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/huangqiang1363/article/details/41983983

基数排序是一种不需要比较就能实现排序的算法思维,主要步骤为分配和收集的过程,重复这个过程于最大数的位数后,排序结束。

以下是完全以队列模拟桶的分配收集过程。

头文件(单链表部分):
typedef int ElemType;
typedef struct LNode
{
	ElemType data;
	struct LNode *next;
}LNode,*LinkList;

int InitList_link(LinkList *head)		   //初始化函数
{
	*head=(LinkList)malloc(sizeof(LNode));	    //产生头结点
	if(NULL==*head)
		return -1;		         //初始化失败
	(*head)->next=NULL;
	return 0;	             	//初始化成功
}

int ListEmpty_link(LinkList head)		       //判空函数
{
	if(NULL==head->next)
		return 1;		     //单链表为空
	return 0;		       	//单链表不为空
}

int ListLength_link(LinkList head)        	//求长度函数
{ 
	int len=0;
	LNode *p=head->next;
	while(NULL!=p)
	{
		len++;
		p=p->next;
	}
	return len;
}

int ListGet_link(LinkList head, int i, ElemType *x)	    //取单链表中的某一个元素
{
	LNode *p;
	int j;

	p=head;
	j=-1;
	while(p->next!=NULL&&j<i)              //查找返回
	{
		p=p->next;
		j++;
	}

	if(j!=i)
	{
		printf("取元素位置参数错");
		return 0;
	}

	*x=p->data;
	return 1;
}

int ListInsert_link(LinkList head,int i,ElemType e)      //在任意位置进行插入
{
	int count=0;
	LNode *p=head,*q=NULL;
	while(count<i-1&&NULL!=p)
	{
		p=p->next;
		count++;
	}
	if(count>i-1||NULL==p)
		return -1;
	q=(LNode *)malloc(sizeof(LNode));
	if(NULL==q)
		return -2;
	q->data=e;
	q->next=p->next;        
	p->next=q;
	return 0;
}
头文件(队列)部分:
#define MAX 100 
typedef enum{Empty,Full} StateType;

typedef struct
{
	ElemType data[MAX];
	int front,rear;
	StateType tag;
}CSqQueue;

int InitQueue_csq(CSqQueue *Q)        //顺序循环队列---课本代码
{
	(*Q).front=0;
	(*Q).rear=0;
	(*Q).tag=Empty;
	return 0;
}

int QueueEmpty_csq(CSqQueue Q)
{
	if(Q.front==Q.rear&&Empty==Q.tag)
		return 1;
	return 0;
}

int QueueFull_csq(CSqQueue Q)
{
	if(Q.front==Q.rear&&Full==Q.tag)
		return 1;
	return 0;
}

int QueueLength_csq(CSqQueue Q)
{
	if(QueueEmpty_csq(Q))
		return 0;
	else if(QueueFull_csq(Q))
		return MAX;
	return (Q.rear-Q.front+MAX)%MAX;
}

int EnQueue_csq(CSqQueue *Q,ElemType e)
{
	if(QueueFull_csq(*Q))
		return -1;
	(*Q).data[(*Q).rear]=e;
	(*Q).rear=((*Q).rear+1)%MAX;
	(*Q).tag=Full;
	return 0;
}

int DeQueue_csq(CSqQueue *Q,ElemType *e)
{
	if(QueueEmpty_csq(*Q))
		return -1;
	*e=(*Q).data[(*Q).front];
	(*Q).front=((*Q).front+1)%MAX;
	(*Q).tag=Empty;
	return 0;
}
头文件(桶排)部分:
typedef int KeyType;
ElemType MaxList_link(LinkList head)
{
	ElemType e;
	ElemType a[MAX];
	int i;
	for(i=0;i<ListLength_link(head);i++)
	{                                     //假设输入为3\1\2
		ListGet_link(head,i,&a[i]);   //依次取元素3、1、2
	}
	e=a[0];
	for(i=1;i<ListLength_link(head);i++)
	{
		if(e<a[i])
			e=a[i];           //e取最大值
	}
	return e;
}

int Num(ElemType e)
{
	int i=0;
	while(e)
	{
		e/=10;
		i++;
	}
	return i;
}

void RadixSort(LinkList *head,KeyType key)
{
	CSqQueue q[10];           //10个队列模拟桶操作过程
	ElemType x;
	int i,j,k;
	ElemType tag;

	for(i=0;i<10;i++)
		InitQueue_csq(&q[i]);                   //初始化10桶
	for(i=0;i<ListLength_link(*head);i++) //待排的个数
	{
		ListGet_link(*head,i,&x);      //顺序取单链表元素
		tag=x;
		j=key;      //n位数    //这里应该用LSD,而不是MSD
		j--;
		while(j--)               //没有高位补0操作
		{
			tag/=10;
		}
		switch(tag%10)       //入相应的桶
		{
			case 0:
				EnQueue_csq(&q[0],x);
				break;
			case 1:
				EnQueue_csq(&q[1],x);
				break;
			case 2:
				EnQueue_csq(&q[2],x);
				break;
			case 3:
				EnQueue_csq(&q[3],x);
				break;
			case 4:
				EnQueue_csq(&q[4],x);
				break;
			case 5:
				EnQueue_csq(&q[5],x);
				break;
			case 6:
				EnQueue_csq(&q[6],x);
				break;
			case 7:
				EnQueue_csq(&q[7],x);
				break;
			case 8:
				EnQueue_csq(&q[8],x);
				break;
			default:
				EnQueue_csq(&q[9],x);
				break;
		}
	}
	k=1;
	InitList_link(head);
	for(i=0;i<10;i++)       //10个桶收集过程
	{
		for(j=0;j<QueueLength_csq(q[i]);)      //这里有个陷阱
		{
			DeQueue_csq(&q[i],&x);
			ListInsert_link(*head,k,x); 
			k++;
		}
	}
}
源文件部分:
#include<stdio.h>
#include<stdlib.h>

#include"LinkList.h"
#include"Queue.h"
#include"RadixSort.h"

int main()
{
	LinkList list;
	int i,x;
	KeyType key;
	InitList_link(&list);
	printf("请输入一组无序的数据以负数结束:");
	i=1;
	while(scanf("%d",&x)&&x>0)
	{
		ListInsert_link(list,i,x);   //入表
		i++;
	}
	key=Num(MaxList_link(list));  //获得最大数的位数以确定分配收集的次数
	int flag=1;
	for(i=1;flag<=key;i++)
	{
		RadixSort(&list,flag);
		flag++;
	}
	printf("基数排序后,该组数据依次为:");
	for(i=0;i<ListLength_link(list);i++)
	{
		ListGet_link(list,i,&x);
		printf("%d  ",x);
	}

	return 0;
}
以上代码可以实现基数排序,但是待排的序列中不能含有0,具体没来得及看,嘿嘿~

猜你喜欢

转载自blog.csdn.net/huangqiang1363/article/details/41983983