| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1488 人关注过本帖
标题:自写的C语言基数排序有点问题,请大家帮忙看看
取消只看楼主 加入收藏
lrongh
Rank: 2
等 级:论坛游民
帖 子:39
专家分:24
注 册:2009-10-6
结帖率:100%
收藏
已结贴  问题点数:20 回复次数:8 
自写的C语言基数排序有点问题,请大家帮忙看看
代码没有完全完成,只写了第一趟排序,还需要归并再排序,最后还得释放内存,不过先不管这些,因为第一趟就出问题了:不知为什么,输出的时候只会输出根结点中的数据,不会输出具有相同基数的数(也就是代码中next指向的数据)。以下是代码(有注释),请帮忙看看,不胜感激!
#include <stdio.h>
#include<stdlib.h>
#define size 20
typedef struct radix{
        int num; /*存储待排序的数字*/
        int lc; /*计数器*/
        struct radix *next; /*指向相同基数的数*/
    }radix;
radix arr[10]; /*arr[i]存储基数为i的数(0<=i<=9)*/
int basesort(int data[],int n){ /*data为待排序数组,n为数组元素的个数*/
    int i,j,k,d,lsd; /*d用来判别最大有效位,lsd记录基数(从个位起)*/
    for(i=1,j=0;i<n;i++)
      if(data[i]>data[j]) j=i;
    k=data[j];
    for(d=1;k/10>=1;k/=10,d*=10);  
    k=1;
    while(k<=d) {
        for(i=0;i<n;i++){
          lsd=((data[i]/k)%10); /*计算基数*/
          panduan(&(arr[lsd]),data[i]); /*根据基数不同存入不同的数组元素内*/
        }
        printf("\n重新排列: ");
        for(i=0;i<10;i++) {
          resort(&(arr[i]));
        }
        getchar();
        k*=10;
    }
}
void panduan(radix *p,int data){  /*相同基数判断:第一次存入根结点中,否则存入下一个链结点*/
    if((p->lc)&&p)
      crbase(p->next,data);
    else
      crbase(p,data);
}
int crbase(radix *p,int data){  /*执行数据存储*/
      if(!p) p=(radix *)malloc(sizeof(radix));
      p->num=data;p->lc++;
}
int resort(radix *p){ /*按顺序输出数据*/
    if((p->lc)>0){
      printf("%3d",p->num);p->lc--;
      if(p->lc)
      resort(p->next);
    }
}
int main() {
    int data[size],i;
    srand(time(NULL));
    for(i=0;i<size;i++)
    data[i]=rand()%100;
    printf("排序前:");
    for(i=0;i<size;i++)
    printf("%3d",data[i]);
    printf("\n");
    basesort(data,size);
}
搜索更多相关主题的帖子: 基数排序 C语言 
2009-10-18 19:41
lrongh
Rank: 2
等 级:论坛游民
帖 子:39
专家分:24
注 册:2009-10-6
收藏
得分:0 
代码中的getchar()是为了停下来观看排列效果的
2009-10-18 19:47
lrongh
Rank: 2
等 级:论坛游民
帖 子:39
专家分:24
注 册:2009-10-6
收藏
得分:0 
问题的症结已经找到了,出在数据的存储上,改进了一下,仍然得不到正确结果,哪位出手指点指点?
#include <stdio.h>
#include<stdlib.h>
#define size 20
typedef struct radix{
        int num; /*存储待排序的数字*/
        int lc; /*计数器*/
        struct radix *next; /*指向相同基数的数*/
    }radix;
radix arr[10]; /*arr[i]存储基数为i的数(0<=i<=9)*/
int basesort(int data[],int n){ /*data为待排序数组,n为数组元素的个数*/
    int i,j,k,d,lsd; /*d用来判别最大有效位,lsd记录基数(从个位起)*/
    for(i=1,j=0;i<n;i++)
      if(data[i]>data[j]) j=i;
    k=data[j];
    for(d=1;k/10>=1;k/=10,d*=10);  
    k=1;
    while(k<=d) {
        for(i=0;i<n;i++){
          lsd=((data[i]/k)%10); /*计算基数*/
          panduan(&(arr[lsd]),data[i]); /*根据基数不同存入不同的数组元素内*/
        }
        printf("\n重新排列: ");
        for(i=0;i<10;i++) {
          resort(&(arr[i]));
        }
        getchar();
        k*=10;
    }
}
void panduan(radix *p,int data){  /*相同基数判断:第一次存入根结点中,否则存入下一个链结点*/
    if(p->lc)
      crbase(p->next,data);
    else {
      p->num=data;
      p->lc++;
    }
}
int crbase(radix *p,int data){  /*执行数据存储*/
      if(!p){
        p=(radix *)malloc(sizeof(radix));
        p->num=data;
        p->lc++;
      }
      else
        crbase(p->next,data);
}
int resort(radix *p){ /*按顺序输出数据*/
     
    if((p->lc)>0){
      printf("%3d",p->num);p->lc--;
      if(p->lc)
      resort(p->next);
    }
}
int main() {
    int data[size],i;
    srand(time(NULL));
    for(i=0;i<size;i++)
    data[i]=rand()%100;
    printf("排序前:");
    for(i=0;i<size;i++)
    printf("%3d",data[i]);
    printf("\n");
    basesort(data,size);
}

[ 本帖最后由 lrongh 于 2009-10-18 21:29 编辑 ]
2009-10-18 21:23
lrongh
Rank: 2
等 级:论坛游民
帖 子:39
专家分:24
注 册:2009-10-6
收藏
得分:0 
计数器的累加也有问题,不能放在里面,改正如下:
 #include <stdio.h>
#include<stdlib.h>
#define size 20
typedef struct radix{
        int num; /*存储待排序的数字*/
        int lc; /*计数器*/  
        struct radix *next; /*指向相同基数的数*/  
    }Xradix;
Xradix arr[10]; /*arr[i]存储基数为i的数(0<=i<=9)*/  
int basesort(int data[],int n){ /*data为待排序数组,n为数组元素的个数*/  
    int i,j,k,d,lsd; /*d用来判别最大有效位,lsd记录基数(从个位起)*/
    for(i=1,j=0;i<n;i++)
      if(data[i]>data[j]) j=i;
    k=data[j];
    for(d=1;k/10>=1;k/=10,d*=10);   
    k=1;
    while(k<=d) {  
        for(i=0;i<n;i++){
          lsd=((data[i]/k)%10); /*计算基数*/  
          panduan(&(arr[lsd]),data[i]); /*根据基数不同存入不同的数组元素内*/
          arr[lsd].lc++;  
        }
        printf("\n重新排列: ");  
        for(i=0;i<10;i++) {
          if(arr[i].lc)
            resort(&(arr[i]));
  
        }
        getchar();  
        k*=10;  
    }  
}
void panduan(Xradix *p,int data){  /*相同基数判断:第一次存入根结点中,否则存入下一个链结点*/
    if(p->lc)
      crbase(p->next,data);
    else {
      p->num=data;  
    }
}
int crbase(Xradix *p,int data){  /*执行数据存储*/
      if(!p){  
        p=(Xradix *)malloc(sizeof(Xradix));
        p->num=data;
      }
      else
        crbase(p->next,data);
}
int resort(Xradix *p){ /*按顺序输出数据*/  
    if(p){
      printf("%3d",p->num);
      resort(p->next);
    }
}
int main() {  
    int data[size],i;
    srand(time(NULL));
    for(i=0;i<size;i++)
    data[i]=rand()%100;
    printf("排序前:");  
    for(i=0;i<size;i++)
    printf("%3d",data[i]);
    printf("\n");  
    basesort(data,size);  
}
仍然得不到正确结果,我跟踪了一下,相同基数的存储还是有问题。
2009-10-18 22:29
lrongh
Rank: 2
等 级:论坛游民
帖 子:39
专家分:24
注 册:2009-10-6
收藏
得分:0 
问题一定出在p->next的使用上,请熟悉指针操作的老师不吝指教!
2009-10-18 22:46
lrongh
Rank: 2
等 级:论坛游民
帖 子:39
专家分:24
注 册:2009-10-6
收藏
得分:0 
又修改了一次,把函数panduan去掉了,这样程序的可读性好一点
 
#include <stdio.h>  
#include<stdlib.h>  
#define size 20  
typedef struct radix{  
        int num; /*存储待排序的数字*/  
        int lc; /*计数器*/   
        struct radix *next; /*指向相同基数的数*/   
    }radix;  
radix arr[10]; /*arr[i]存储基数为i的数(0<=i<=9)*/   
int basesort(int data[],int n){ /*data为待排序数组,n为数组元素的个数*/   
    int i,j,k,d,lsd; /*d用来判别最大有效位,lsd记录基数(从个位起)*/  
    for(i=1,j=0;i<n;i++)  
      if(data[i]>data[j]) j=i;  
    k=data[j];  
    for(d=1;k/10>=1;k/=10,d*=10);   
    k=1;  
    while(k<=d) {   
        for(i=0;i<n;i++){  
          lsd=((data[i]/k)%10); /*计算基数,根据基数不同存入不同的数组元素内*/   
          if(arr[lsd].lc)  
            crbase(arr[lsd].next,data[i]);  
          else   
            arr[lsd].num=data[i];
   
          arr[lsd].lc++;   
        }  
        printf("\n重新排列: ");   
        for(i=0;i<10;i++) {  
          if(arr[i].lc)  
            resort(&(arr[i]));   
        }  
        getchar();   
        k*=10;   
    }   
}  
int crbase(radix *p,int data){  /*执行数据存储*/  
      if(!p){   
        p=(radix *)malloc(sizeof(radix));  
        p->num=data;  
      }  
      else  
        crbase(p->next,data);  
}  
int resort(radix *p){ /*按顺序输出数据*/   
    if(p){  
      printf("%3d",p->num);  
      resort(p->next);  
    }  
}  
int main() {   
    int data[size],i;  
    srand(time(NULL));  
    for(i=0;i<size;i++)  
    data[i]=rand()%100;  
    printf("排序前:");   
    for(i=0;i<size;i++)  
    printf("%3d",data[i]);  
    printf("\n");   
    basesort(data,size);   
}  
还是得不到正确结果,郁闷...,crbase(arr[lsd].next,data[i])这条语句有问题吗?我反复跟踪发现如果有相同基数的数程序会crbase(arr[lsd].next,data[i]),但是每次都只执行if(!p)中的语句,else从来没执行过,另外, 执行resort函数中的resort(p->next)语句后都是在if(p)那里就跳转了,也就是说arr[i]中的next都为空,怎么可能呢?明明执行过crbase(arr[lsd].next,data[i])呀?!
2009-10-19 09:17
lrongh
Rank: 2
等 级:论坛游民
帖 子:39
专家分:24
注 册:2009-10-6
收藏
得分:0 
其实我的思路很简单:如果有相同基数的数,判断存储该基数的结构体内的next指针是否为空,为空就分配空间,存储数据,不为空表明这里已经存储了一个相同基数的数,所以递归回去再判断...,如此依序形成一个具有相同基数的数据链;读取的时候则先判断指针是否存在,存在就读出其中的数据,再读下一个指针...一直到指针为空,说明该数据链上的数据已全部读出,再取下一个数组元素...
2009-10-19 10:16
lrongh
Rank: 2
等 级:论坛游民
帖 子:39
专家分:24
注 册:2009-10-6
收藏
得分:0 
万事俱备,只欠东风!下面的代码经过完善,功能已经齐全,就差哪位老师来指点一下,把前面所说的错误改正过来就OK了!
#include <stdio.h>   
#include<stdlib.h>   
#define size 20   
int count; /*全局变量,归集数据时用作数组下标*/
typedef struct radix{   
  int num; /*存储待排序的数字*/   
  int lc; /*计数器*/   
  struct radix *next; /*指向相同基数的数*/   
}radix;   
radix arr[10]; /*arr[i]存储基数为i的数(0<=i<=9)*/   
int basesort(int data[],int n){ /*data为待排序数组,n为数组元素的个数*/   
    int i,j,k,t=0,d,lsd; /*d用来判别最大有效位,lsd记录基数(从个位起)*/   
    for(i=1,j=0;i<n;i++)   
      if(data[i]>data[j]) j=i;   
    k=data[j];   
    for(d=1;k/10>=1;k/=10,d*=10);     
    k=1;   
    while(k<=d) {   
        for(i=0;i<n;i++){   
          lsd=((data[i]/k)%10); /*计算基数,根据基数不同存入不同的数组元素内*/   
          if(arr[lsd].lc)   
            crbase(arr[lsd].next,data[i]);   
          else   
            arr[lsd].num=data[i];     
          arr[lsd].lc++;   
        }   
        printf("第%d趟排序:",++t);   
        for(i=0;i<10;i++) {   
          if(arr[i].lc)   
            resort(&(arr[i]),data);   
        }   
        for(i=0;i<count;i++)
          printf("%3d",data[i]);
        system( "pause");      
        k*=10;
        count=0;   
    }
    printf("排序完成!");   
}   
int crbase(radix *p,int data){  /*执行数据存储*/   
      if(!p){   
        p=(radix *)malloc(sizeof(radix));   
        p->num=data;   
      }   
      else   
        crbase(p->next,data);   
}   
int resort(radix *p,int data[]){ /*按顺序输出数据*/   
    if(p){   
      data[count++]=p->num;
      resort(p->next,data);   
    }
    free(p);   
}   
int main() {   
    int data[size],i;   
    srand(time(NULL));   
    for(i=0;i<size;i++)   
      data[i]=rand()%100;   
    printf("排序前:");   
    for(i=0;i<size;i++)   
      printf("%3d",data[i]);   
    printf("\n");   
    basesort(data,size);   
}   
耐心等候老师的指点......
2009-10-19 16:54
lrongh
Rank: 2
等 级:论坛游民
帖 子:39
专家分:24
注 册:2009-10-6
收藏
得分:0 
哈哈,通过我不懈的努力,总算解决了,爽!
2009-10-20 10:19
快速回复:自写的C语言基数排序有点问题,请大家帮忙看看
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.022492 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved