/*成功完成在23号 0:00,指针操作调试大约六个小时,收获是:编写代码一定要仔细,尤其是指针操作*/
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#define bool int
#define ture 1
#define false 0
#define null 0
#define RADIX 10 //定义该技术排序的基数
#define MAX 100
struct bucketnode
{
int number;
struct bucketnode *next;
};
struct bucket
{
int remainder;//余数
bucketnode *head;
bucketnode *tail;
bucket *next;
};
void radix_sort (int array[],int n)
{
int i=0,remain,count=0,model=RADIX;
int *temp=(int *)malloc(sizeof(int)*n);//申请临时数组为存放操作
bucket head={RADIX,null,null,null};//建立头结点,代表整个桶链
bucket *p,*pre;
bucketnode *q,*prenode;
for(i=0;i<n;i++)//将给定数组的元素一一拷贝到临时数组里
{
temp[i]=array[i];
}
while(count!=n)//基数排序的主要环节,判断是否已经到了最大位,超过最大位则停止
{
count=0;
for(i=0;i<n;i++)//循环遍历整个数组,进行桶式排序
{
remain=temp[i]%RADIX; //得到模除后的数,即余数
//temp[i]=temp[i]/RADIX;//记录该基数的整数倍数,位下次判断做铺垫
for(pre=head.next,p=head.next;p!=null&&remain>=p->remainder;)
{ // 循环执行,如果找到该余数的桶则
if(p->remainder==remain) // 建立节点加入新节点
{
bucketnode *node=(bucketnode *)malloc(sizeof(bucketnode));
node->number=array[i];
node->next=null;
(p->tail)->next=node;
p->tail=node;
break;
}
pre=p;
p=p->next;
}
if(p==null||remain < p->remainder)//如果没有某一基数摸的桶则执行
{
bucketnode *node=(bucketnode *)malloc(sizeof(bucketnode));
node->number=array[i];
node->next=null;
bucket *newbucket=(bucket *)malloc(sizeof(bucket));
newbucket->head=newbucket->tail=node;
newbucket->remainder=remain;
if(head.next==null) //如果桶的头结点为空则将创建的桶节点直接连接到桶的头结点
{
head.next=newbucket;
newbucket->next=null;
}else if(p==null)//如果桶节点为空,说明遍历桶节点到最后,此节点的模为桶节点中最大
{
pre->next=newbucket;
newbucket->next=null;
}else if(remain < p->remainder)//如果找到了第一个比该桶节点大的模
{
if(p==pre)//谨记:此处曾因==误用为=使自己调试一个多小时!
{ //如果该节点即为第一个节点
newbucket->next=head.next;
head.next=newbucket;
}else //该节点不为第一个节点
{
pre->next=newbucket;
newbucket->next=p;
}
}
}
}
for(i=0,p=head.next;p!=null;)
{
for(q=p->head;q!=null;i++)
{
array[i]=q->number;
printf("%d/n",q->number);//输出每次排序的顺序
//printf("%d/n",array[i]);
//printf("%d/n",temp[i]);
if(!(temp[i]=q->number/model))//构造结束条件,当最高位都为零时候
{ //count累加到n,停止执行
count++;
}
prenode=q;//每处理一个节点后就删除给节点
q=q->next;
free(prenode);
}
pre=p;//每处理一个桶后就删除该桶
p=p->next;
free(pre);
}
head.head=null;
head.tail=null;
head.next=null;
model*=RADIX;//迭代增加一次有地位相高位取值
printf("******************************************************/n");
}
}
void array_printf(int array[],int n)
{
int i;
for(i=0;i<n;i++)
{
printf("%d/n",array[i]);
}
}
int main()
{
int i=0,temp;
int array[MAX];
while(1){
printf("please input your array(negative is quit!):/n");
printf("the %d number(negative is quit!):/n",i);
scanf("%d",&temp);
while(temp>=0)
{
array[i]=temp;
i++;
printf("the %d number(negative is quit!):/n",i);
scanf("%d",&temp);
}
printf("******************************************************/n");
radix_sort(array,i);
array_printf (array,i);
i=0;
}
system("pause");
}
//基数排序,写这段代码其实费了我不少时间。刚开始以为这是一段简单的代码,不过由于粗心,或是因为写代码的经验不足导致出现各种
//指针操作上的错误,不过幸亏没有放弃,一句话一句话的调试,而且还让我更加熟悉了调试。这几个小时没白花,纪念一下!
//最后的一个错误是if语句中的判断我居然写成了赋值,哈哈,幸亏在调试执行的时候发现!
//还有就是从今以后一定要记住写程序,只要是有跳转的语句块应该写注释!老师说:这不就是磨刀和砍柴的功夫吗?!