1. 程式人生 > >_DataStructure_C_Impl:基數排序

_DataStructure_C_Impl:基數排序

基數 位數 distrib def data 收集 amp ini truct

#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
#define MaxNumKey 6 /*keyword項數的最大值*/
#define Radix 10	/*keyword基數,此時是十進制整數的基數*/
#define MaxSize 1000
#define N 6
typedef int KeyType; /*定義keyword類型*/
typedef struct
{
	KeyType key[MaxNumKey]; /*keyword*/
	int next;
}SListCell;	/*靜態鏈表的結點類型*/

typedef struct
{
	SListCell data[MaxSize];		/*存儲元素,data[0]為頭結點*/
	int keynum;						/*每一個元素的當前keyword個數*/
	int length;						/*靜態鏈表的當前長度*/
}SList;		/*靜態鏈表類型*/
typedef int addr[Radix]; /*指針數組類型*/

typedef struct
{
	KeyType key; /* keyword項 */
}DataType;

void PrintList(SList L);
void PrintList2(SList L);
void InitList(SList *L,DataType d[],int n);
int trans(char c);
void Distribute(SListCell data[],int i,addr f,addr r);
void Collect(SListCell data[],addr f,addr r);
void RadixSort(SList *L);
void InitList(SList *L,DataType a[],int n)
	/* 初始化靜態鏈表L(把數組D中的數據存於L中) */
{ 
	char ch[MaxNumKey],ch2[MaxNumKey];
	int i,j,max=a[0].key;
	for(i=1;i<n;i++)					/*將最大的keyword存入max*/
		if(max<a[i].key)
			max=a[i].key;
	(*L).keynum=(int)(log10((float)max))+1;	/*求keyword的個數*/
	(*L).length=n;						/*待排序個數*/
	for(i=1;i<=n;i++)
	{
		itoa(a[i-1].key,ch,10);					/*將整型轉化為字符,並存入ch*/
		for(j=strlen(ch);j<(*L).keynum;j++)		/*假設ch的長度<max的位數,則在ch前補‘0‘*/
		{
			strcpy(ch2,"0");
			strcat(ch2,ch);
			strcpy(ch,ch2);
		}
		for(j=0;j<(*L).keynum;j++)				/*將每一個keyword的各個位數存入key*/
			(*L).data[i].key[j]=ch[(*L).keynum-1-j];
	}
	for(i=0;i<(*L).length;++i)				/*初始化靜態鏈表*/
		(*L).data[i].next=i+1;
	(*L).data[(*L).length].next=0; 
}

int trans(char c)
	/*將字符c轉化為相應的整數*/
{ 
	return c-‘0‘;
}
void Distribute(SListCell data[],int i,addr f,addr r) 
	/*為data中的第i個keywordkey[i]建立Radix個子表。使同一子表中元素的key[i]同樣*/
	/*f[0..Radix-1]和r[0..Radix-1]分別指向各個子表中第一個和最後一個元素*/
{ 
	int j,p;
	for(j=0;j<Radix;j++)				/*將各個子表初始化為空表*/
		f[j]=0;							
	for(p=data[0].next;p;p=data[p].next)
	{
		j=trans(data[p].key[i]);		/*將相應的keyword字符轉化為整數類型*/
		if(!f[j])						/*f[j]是空表,則f[j]指示第一個元素*/
			f[j]=p;
		else
			data[r[j]].next=p;
		r[j]=p;							/*將p所指的結點插入第j個子表中*/
	}
}



void Collect(SListCell data[],addr f,addr r)
	/*按key[i]將f[0..Radix-1]所指各子表依次鏈接成一個靜態鏈表*/
{ 
	int j,t;
	for(j=0;!f[j];j++);	/*找第一個非空子表。succ為求後繼函數*/
	data[0].next=f[j];
	t=r[j];				/*r[0].next指向第一個非空子表中第一個結點*/
	while(j<Radix-1)
	{
		for(j=j+1;j<Radix-1&&!f[j];j++);	/*找下一個非空子表*/
		if(f[j])							/*將非空鏈表連接在一起*/
		{									
			data[t].next=f[j];
			t=r[j];
		}
	}
	data[t].next=0;		/*t指向最後一個非空子表中的最後一個結點*/
}

void RadixSort(SList *L)
	/*對L進行基數排序,使得L成為按keyword非遞減的靜態鏈表,L.r[0]為頭結點*/
{ 
	int i;
	addr f,r;
	for(i=0;i<(*L).keynum;i++)			/*由低位到高位依次對各keyword進行分配和收集*/
	{				
		Distribute((*L).data,i,f,r);	/*第i趟分配*/
		Collect((*L).data,f,r);			/*第i趟收集*/
		printf("第%d趟收集後:",i+1);
		PrintList2(*L);
	}
}



void main()
{
	DataType d[N]={268,126,63,730,587,184};
	SList L;
	InitList(&L,d,N);
	printf("待排序元素個數是%d個。keyword個數為%d個\n",L.length,L.keynum);
	printf("排序前的元素:\n");
	PrintList2(L);
	printf("排序前的元素的存放位置:\n");
	PrintList(L);
	RadixSort(&L);
	printf("排序後元素的存放位置:\n");
	PrintList(L);
	system("pause");
}
void PrintList(SList L)
	/*按數組序號形式輸出靜態鏈表*/
{ 
	int i,j;
	printf("序號 keyword 地址\n");
	for(i=1;i<=L.length;i++)
	{
		printf("%2d    ",i);
		for(j=L.keynum-1;j>=0;j--)
			printf("%c",L.data[i].key[j]);
		printf("    %d\n",L.data[i].next);
	}
}
void PrintList2(SList L)
	/*按鏈表形式輸出靜態鏈表*/
{
	int i=L.data[0].next,j;
	while(i)
	{
		for(j=L.keynum-1;j>=0;j--)
			printf("%c",L.data[i].key[j]);
		printf(" ");
		i=L.data[i].next;
	}
	printf("\n");
}

_DataStructure_C_Impl:基數排序