实验:基数排序
【实验目的】
- 掌握链表结点的指针域的修改。
- 掌握链表的操作特点和方法。
- 掌握基于链表的程序设计方法。
【实验内容】
- 实现基于链表的基数排序算法;
- 使用上述基数排序程序对人类基因组进行排序。
【实验要求】
输出使用基数排序程序排序的运行时间。箱子排序的时间复杂度为O(n)。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
/*
author:YXP
e-mail:yxp189@protonmail.com
如有问题,欢迎和我联系~
转载请标明出处~
*/
int NOW_LEVEL = 0; //当前层级
int LEVEL = 1; //搭建结构的层数;从0开始
int TIME = 0; //生成程序的迭代次数
int PRINT_TIME = 0; //打印的调用次数
int counter = 0; //层数计数器
int NODE = 0; //最底层分类数
struct _level { //层级结构定义
int level_th; //第几层
int lenth; //当前层的宽度
struct _level* last_level; //上一层的地址
struct _level** next_level; //下一层的链接
struct _node* head; //储存节点头
struct _node* tail; //储存末尾节点
};
struct _node { //数据节点定义
char CH_store; //存储的字符
int order; //当前在节点在序列中的第几位
int *traits; //当前节点在层级中的位置
struct _node* next; //下一个节点
};
int Build_tree(struct _level** TOP, int *level_th, int level_num); //生成层次结构
void Initalize_level(struct _level** HEAD, int *level_th, int now_level_th); //初始化层
int Insert(struct _level** TOP,struct _node* Node,int* level_th); //插入
void Print_content(FILE *fp_w,struct _level** TOP,int *position_arr); //打印指定位置元素
void Print_All(FILE **fp_w,struct _level** TOP,int* level_th, int now_level_th);//打印出最底层元素的分布情况
int Find_ch_place(char CH,int** positin); //找到字符(10x10)的插入位置
int Create_struct_node(struct _node** Node,char CH);//创建数据节点
int main(int argc, char *argv[]) {
clock_t start, finish;
int level_th[2] = {10,10}; //指定每一层的长度
struct _level* TOP = NULL;
Build_tree(&TOP, level_th, LEVEL);//建立层级结构
char* r_filename = "Test.txt"; //待读入的文件名称
FILE* fp_c,*fp_w,*fp_r =fopen(r_filename, "r");
printf ("@SORTING...\n");
int All_num = 0;//总计插入的数
char ch;
start = clock();//用于计算插入用时
while ((ch = fgetc(fp_r)) != EOF){
struct _node* Node;
Create_struct_node(&Node,ch); //创建数据节点
Insert(&TOP,Node,Node->traits); //在层级结构中插入数据节点
// Print_content(&TOP,Node->traits);//打印出插入的字符
// int i;
// printf("数据插入位置>>");
// for (i=0;i<=LEVEL;i++){ //输出存储的位置(层级位置)
// printf("%d ",Node->traits[i]);
// }
All_num++;
}
finish = clock();
char* w_filename = "result.txt"; //所得排序结果,输出到文件“result.txt”
fp_w =fopen(w_filename, "w");
Print_All(&fp_w,&TOP,level_th,NOW_LEVEL); //打印出所有的统计结果
printf (">>All_TYPE= %d\n",NODE); //最底层分类总个数;和定义的每层的长度有关(10x10)
printf (">>排序用时%lf\n",(double)(finish-start)/CLK_TCK);//输出(插入箱子/基数)排序用时
printf (">>All_NUM= %d\n",All_num); //总的数据个数
printf ("@SORT END!\n");
printf ("@Result_file has been sent to you folder! Pleae check it!\n");
system("pause");
return 0;
}
int Find_ch_place(char CH,int** positin)//对字符,找到应插入的位置
{
int temp = CH;
*positin = (int*)malloc((LEVEL+1)*sizeof(int));
int i;
for (i=0;i<(LEVEL+1);i++){
(*positin)[i] = temp%10;
temp/=10;
}
return 0;
}
int Create_struct_node(struct _node** Node,char CH)//创建数据节点
{
*Node = (struct _node*)malloc(sizeof(struct _node));
(*Node)->CH_store = CH;
(*Node)->order = 0;
(*Node)->next = NULL;
Find_ch_place(CH,&((*Node)->traits));
}
void Print_content(FILE *fp_w,struct _level** TOP,int *position_arr)//打印层级结构指定位置的元素
{
struct _level** temp1 = NULL,**temp2 = TOP;
int i,position;
for(i=0;i<LEVEL;i++){
temp1 = temp2;
position = position_arr[i];
if (fp_w != NULL){
fprintf (fp_w,"%d-\n",position);
}
temp2 = (*temp1)[position].next_level;
}
position = position_arr[i];
fprintf (fp_w,"%d-",position);
struct _node* CH_store = (*temp2)[position].tail;
if (CH_store != NULL){
if (fp_w==NULL){
printf ("CHAR = %c\n",CH_store->CH_store);
}else{
fprintf (fp_w,"CHAR = %c\t NUM = %d\n",CH_store->CH_store,CH_store->order+1);
}
}else{
if (fp_w==NULL){
printf ("%s\n","NULL");
}else{
fprintf (fp_w,"%s\n","NULL");
}
}
}
void Print_All(FILE **fp_w,struct _level** TOP,int* level_th, int now_level_th)//打印出总体的排序情况,并且输入到文件里。
{
PRINT_TIME ++;
int i = 0;
for (i=0;i<level_th[now_level_th];i++)
{
int k;
if(i == 0){
fprintf (*fp_w,"\n");
}
for (k=0;k<now_level_th;k++){
fprintf (*fp_w,"\t");
}
fprintf (*fp_w,"Lev= %d - Pos= %d -",now_level_th,i);
if (now_level_th<LEVEL) {
NOW_LEVEL++;
Print_All(fp_w,&((*TOP)[i].next_level[0]), level_th, now_level_th+1);
NOW_LEVEL--;
}
else {
if(now_level_th == LEVEL){
NODE ++;
if ((*TOP)[i].tail != NULL){
fprintf (*fp_w,"CHAR= %c\tNUM= %d\n",((*TOP)[i].tail)->CH_store, ((*TOP)[i].tail)->order+1);
}else{
fprintf (*fp_w,"NULL\n");
}
}
}
}
return;
}
int Insert(struct _level** TOP,struct _node* Node,int* level_th)//在层级结构中的指定位置插入元素
{
int now_level = 0,position = 0;
struct _level** temp1 = NULL,**temp2 = TOP;
for (now_level=0;now_level<LEVEL;now_level++){
temp1 = temp2;
position = Node->traits[now_level];
temp2 = (*temp1)[position].next_level;
}
position = Node->traits[now_level];;
if ((*temp2)[position].tail == NULL){
Node->order = 0;
(*temp2)[position].head = Node;
(*temp2)[position].tail = Node;
}else{
Node->order = (*temp2)[position].tail->order + 1;
(*temp2)[position].tail->next= Node;
(*temp2)[position].tail = Node;
}
return 0;
}
int Build_tree(struct _level** TOP, int *level_th, int level_num)//搭建层级结构(树)
{
Initalize_level(TOP, level_th, NOW_LEVEL);
return 0;
}
void Initalize_level(struct _level** HEAD, int *level_th, int now_level_th)//初始化层级结构的每一层
{
TIME ++;
int i = 0;
(*HEAD) = (struct _level*)malloc(level_th[now_level_th]*sizeof(struct _level));
for (i=0;i<level_th[now_level_th];i++)
{
(*HEAD)[i].level_th = now_level_th;
(*HEAD)[i].lenth = level_th[now_level_th];
if (now_level_th == 0) {
(*HEAD)[i].last_level = NULL;
}
else {
(*HEAD)[i].last_level = *HEAD;
}
(*HEAD)[i].head = NULL;
(*HEAD)[i].tail = NULL;
if (now_level_th<LEVEL) {
(*HEAD)[i].next_level = (struct _level**)malloc(level_th[now_level_th+1] * sizeof(struct _level*));
NOW_LEVEL++;
Initalize_level(&((*HEAD)[i].next_level[0]), level_th, now_level_th+1);
NOW_LEVEL--;
}
else {
(*HEAD)[i].next_level = NULL;
}
}
return;
}