第十章(11).基数排序
来源:互联网 发布:盛世赢家软件下载 编辑:程序博客网 时间:2024/05/16 19:24
这次的经历终于让我尝到了什么叫“尽信书不如无书”!虽然以前也有过类似的经历,但是这次的经历实在是太深刻了啊!调试一个小时!!!这就是代价啊!不过这也有好处,让我对基数排序的原理理解更深了!
(思想和代码近似书上所描叙!)
#include < stdio.h >
#include < stdlib.h >#define MAX_NUM_OF_KEY 3 //关键字项数的最大值
#define RADIX 10 //关键字基数,此时是十进制整数的基数
#define MAX_SPACE 50typedef int KeysType ;
typedef struct {
KeysType keys[ MAX_NUM_OF_KEY ] ;
// InfoType otheritems ; //其他数据项
int next ;
} SLCell ; //静态链表的结点类型typedef struct {
SLCell r[MAX_SPACE ] ; //静态链表的可利用空间,r[0]为头结点
int keynum ; //记录当前关键字个数
int recnum ; //静态链表当前长度
} SLList ; //静态链表类型typedef int ArrType[ RADIX ] ; //指针数组类型
void InitList( SLList *L , int Data[ ] , int n ) ;
void Distribute( SLCell *r , int i , ArrType *f , ArrType *e ) ;
void Collect( SLCell *r , int i , ArrType f , ArrType e ) ;
void RadixSort( SLList *L ) ;int ord( KeysType key ) ;
int succ( int next ) ;//---------------------------------------------------------------------------//
#include "RadixSorting.h"
int ord( KeysType key )
{
return key%RADIX ; //return key ;
}void Distribute( SLCell *r , int i , ArrType *f , ArrType *e ) //*f为头,*e为尾
{ //静态链表L的r域中记录已按( keys[0]……keys[i-1])有序
//本算法按照第i个关键字keys[i]建立RADIX个子表,使同一子表中记录的keys[i]相同
//f[0…RADIX-1]和e[0…RADIX-1]分别指向各子表中第一个和最后一个记录
int j , p ;for( j = 0 ; j < RADIX ; ++ j )
(*f)[ j ] = 0 ; //各子表初始化为空表
for( p = r[ 0 ].next ; p ; p = r[ p ].next )
{
j = ord( r[ p ].keys[ i ] ) ; //ord将记录中第i个关键字映射到[0…RADIX-1]
if( !(*f)[ j ] )
(*f)[ j ] = p ;
else
r[ (*e)[ j ] ].next = p ;(*e)[ j ] = p ; //将p所指的结点插入第j个子表中
}
}int succ( int next )
{
return ++next ;
}void Collect( SLCell *r , int i , ArrType f , ArrType e )
{ //本算法按keys[i]自小至大将f[0…RADIX-1]所指各子表依次链接成一个链表,e[0…RADIX-1]为各子表的尾指针
int j , t ;for( j = 0 ; !f[ j ] ; j = succ( j ) ) ; //找第一个非空子表,succ为求后继函数
r[ 0 ].next = f[ j ] ; t = e[ j ] ; //r[ 0 ].next指向第一个非空子表中第一个结点while( j < RADIX - 1 ) //次数和书上表述不同,需要减一
{
for( j = succ( j ) ; j < (RADIX - 1) && !f[ j ] ; j = succ( j ) ) ; //找下一个非空子表
if( f[ j ] )
{
r[ t ].next = f[ j ] ; t = e[ j ] ; //链接两个非空子表
}
}
r[ t ].next = 0 ; //t指向最后一个非空子表中的最后一个结点
}void RadixSort( SLList *L )
{ //L采用静态链表表示的顺序表
//对L做基数排序,使得L成为按关键字自小到大的有序静态表,L.r[0]为头结点
int i ;
ArrType f , e ;for( i = 0 ; i < L->keynum ; ++ i ) //按最低位优先依次对个关键字进行分配和收集
{
Distribute( L->r , i , &f , &e ) ; //第i趟分配
Collect( L->r , i , f , e ) ; //第i趟收集
}
}void InitList( SLList *L , int Data[ ] , int n )
{
int i = 0 , j = 0 ;L->r[ 0 ].next = i + 1 ;
L->keynum = 0 ;
L->recnum = n ; //L->r[0]做头结点
while( i < n )
{
j = 0 ;
while( Data[ i ] / RADIX ) //商和余数均为0,则表示该元素over
{
L->r[ i + 1 ].keys[ j ] = Data[ i ] % RADIX ;
Data[ i ] /= RADIX ; //此处把外部的数据也改变了,如果要求严格一点,则需要把Data[]数据拷贝一份,用拷贝份进行处理
j ++ ;
}
L->r[ i + 1 ].keys[ j ] = Data[ i ] % RADIX ;
j ++ ;
L->r[ i + 1 ].next = i + 2 ;
if( L->keynum < j )
L->keynum = j ;
++ i ;
}
L->r[ L->recnum ].next = 0 ;
}void Print( SLList L )
{
int j = L.r[ 0 ].next , i = MAX_NUM_OF_KEY , temp ;
while( j )
{
i = MAX_NUM_OF_KEY ;
while( i > 0 )
{
temp = L.r[ j ].keys[ -- i ] ;
if( temp >= 0 )
printf( "%d" , temp ) ;
}
printf( " " ) ;
j = L.r[ j ].next ;
}
}int main( )
{
int Data[ ] = { 278 , 109 , 63 , 930 , 589 , 184 , 505 , 269 , 8 , 83 } ;
SLList L ;InitList( &L , Data , 10 ) ;
Print( L ) ;
printf( "\n" ) ;
RadixSort( &L ) ;
Print( L ) ;printf( "\n" ) ;
return 0 ;
}
- 第十章(11).基数排序
- 第十六章-基数排序
- 基数排序(转)
- 基数排序(C)
- 基数排序(radixSort)
- 基数排序(java实现)
- 基数排序 (Radix sort)
- 基数排序 radixsort(LSD)
- 基数排序(java实现)
- 基数排序(radix sort)
- 基数排序(数组版)
- 基数排序(LSD)
- 基数排序(C++版)
- 基数排序(桶排序)
- 基数排序(桶排序)
- 基数排序(桶排序)
- 基数排序(链表)
- 基数排序(未)
- 第十章(6).快速排序
- 第十章(7).选择排序
- 第十章(8).堆排序
- 第十章(9).归并排序(递归)
- 第十章(10).归并排序(非递归)
- 第十章(11).基数排序
- C++扫盲系列--第一个服务器程序
- 第十一章(1).多路平衡归并排序
- 第十一章(2).置换—选择排序
- 第六章(8)求集合的幂集
- 第六章(9).四皇后问题
- 第四章(4).KMP算法
- 第四章(5).建立词索引表
- 第三章(8).离散事件模拟