K.Maebashi's BBS 投稿フォーム
ハンドル名
件名
Link
>助言をいただき、それをむねに一応完成したソースを書き込みます。 >変なところがあれば、ぜひ助言をお願いします。 >#include <stdio.h> >#include <stdlib.h> >#include <string.h> >typedef int (*Compare)(int,int) ; >typedef struct DATA DATA; > >struct DATA >{ > DATA * next; > char * name; > int math; > int language; > int sum; >}; >#define MAX 256 >int AscendinOrder(int a,int b); >int DescendingOrder(int a,int b); >DATA* merge_sort(DATA* top,Compare); >DATA* merge_list(DATA* x, DATA* y,Compare); > >/**************************************** >機能:線形リストのデータをすべて解放する。 >引数:top 線形リストのトップデータ > comp 使用した比較関数 >出力:無し >****************************************/ >void AllFree(DATA *top,Compare *comp) >{ > DATA *temp,*freeData; > if(*comp == AscendinOrder || *comp == NULL){ > temp = top; > while(temp->next){ > freeData = temp; > temp =temp->next; > free(freeData->name); > free(freeData); > } > }else if(*comp == DescendingOrder){ > temp = top->next; > while(temp){ > freeData = temp; > temp =temp->next; > free(freeData->name); > free(freeData); > } > } >} >/**************************************** >機能:線形リストのノードを作成。 >引数:無し >出力:DATA型の新しいノードのポインタ >****************************************/ >DATA* newnode(){ > DATA *p; > p=malloc(sizeof(DATA)); > p->next=NULL; > return p; >} >/**************************************** >機能:合計点を求める >引数:data 合計点を求めるDATA型のポインタ >出力:mathとlanguageの合計点 >****************************************/ >int SUM(DATA *data) >{ > return data->math+data->language; >} >/**************************************** >機能:線形リストの末尾にノードを追加。 >引数:p リストの先頭 > c リストnameにはいる名前 > lang リストのlanguageに入る数値 > math リストのmathに入る数値 >出力:無し >****************************************/ >void add(DATA *p,char *c,int lang,int math){ > while(p->next != NULL){ > p= p->next; > } > > p->math = math; > p->language = lang; > p->sum = SUM(p); > p->name=malloc(strlen(c)+1); > strcpy(p->name,c); > p->next=newnode(); >} > >/**************************************** >機能:線形リストの内容を表示。 >引数:data リストの先頭 > comp 使った比較関数 >出力:無し >****************************************/ >void ShowData(DATA *data,Compare *comp) >{ > > DATA *temp; > if(*comp == AscendinOrder || *comp == NULL){ > for(temp = data; temp->next;temp= temp->next){ > printf("name : %s, language : %d, math : %d, sum :%d \n",temp->name,temp->language,temp->math,temp->sum); > } > }else if(*comp == DescendingOrder){ > for(temp = data->next; temp;temp= temp->next){ > printf("name : %s, language : %d, math : %d, sum :%d \n",temp->name,temp->language,temp->math,temp->sum); > } > } > >} >/**************************************** >機能:表示方法の設定。 >引数:無し >出力:表示方法の値。 >****************************************/ >int ShowCase() >{ > char c; > > printf("昇順で表示 :1 ,降順で表示:2\n"); > c = getchar(); > switch(c){ > case '1': > return 1; > case '2': > return 2; > default: > return 0; > } >} >int main() >{ > char data[MAX] = {'\0'}; > char ctemp[100] = {'\0'}; > int m,l,type; > FILE *fp = fopen("data.txt","r"); > char *n; > DATA *top = malloc(sizeof(DATA)); > > Compare comp = NULL; > type=ShowCase(); > if(type == 1){ > comp = AscendinOrder; > }else if(type == 2){ > comp = DescendingOrder; > }else{ > comp = NULL; > } > top->next = NULL; > while(fgets(data,MAX,fp)){ > if(n = strchr(data,'\n')) > *n = '\0'; > > sscanf(data,"%s%d%d",ctemp,&m,&l); > > > add(top,ctemp,l,m); > } > if(comp != NULL){ > top =merge_sort(top,comp); > } > ShowData(top,&comp); > AllFree(top,&comp); > return 0; >} >/**************************************** >機能:線形リストのマージソートする。 >引数:top リストの先頭 > comp 使う比較関数 >出力:ソート済みのリストのポインタ >****************************************/ >DATA* merge_sort(DATA* top,Compare comp) >{ > DATA *a, *b, *y; > > /* リストに含まれる要素数が0または1個のときは、ソートの必要がない */ > if( top == NULL || top->next == NULL ){ > return top; > } > > a = top; /* aは先頭の要素を指す */ > b = top->next; > if( b != NULL ){ > b = b->next; > } /* bは先頭から3番目の要素を指す */ > > /* 線形リストを中心くらいから半分に分けるため、中心位置がどこにあるのか探る */ > while( b != NULL ) > { > a = a->next; /* aは常に1つだけ進む */ > b = b->next; > if( b != NULL ){ > b = b->next; > } /* bは基本的に2つ進む */ > } > > /* 線形リストを2つに分割する */ > y = a->next; /* yは分割後の2つのリストのうちの、後半部分の方の先頭を指す */ > a->next = NULL; > > /* 分割した2つのリスト */ > return merge_list( merge_sort( top ,comp), merge_sort( y ,comp) ,comp); >} > >/************************************************************************ >機能:2つの線形リストをマージする。 >引数:x マージする2つの線形リストのうちの片方の先頭要素へのポインタ > y マージする2つの線形リストのうちの片方の先頭要素へのポインタ > comp 比較関数 >出力: マージされた線形リストの先頭要素へのポインタ >*************************************************************************/ >DATA* merge_list(DATA* x, DATA* y,Compare comp) >{ > DATA z, *p; > > p = &z; /* xとyをマージしてzを作り上げる */ > > /* 分割されている2つのリストのいずれか一方が空になるまで繰り返す */ > while( x != NULL && y != NULL ) > { > /* 2つのリストの先頭要素同士を比較する */ > if( comp(x->sum , y->sum) ) > { > /* リストxの方の先頭要素を、マージ後のリストに連結する */ > p->next = x; > p = x; > x = x->next; > } > else > { > /* リストyの方の先頭要素を、マージ後のリストに連結する */ > p->next = y; > p = y; > y = y->next; > } > } > > /* 先に片方のリストが空になるので、残された方のリストの要素を、マージ後リストに連結する */ > if( x == NULL ) > { > p->next = y; > } > else > { > p->next = x; > } > > return z.next; >} >int AscendinOrder(int a,int b) >{ > return a>=b? 1:0; >} >int DescendingOrder(int a,int b) >{ > return a <= b?1:0; >} > >data.txtの中身 >jon 90 30 >sum 40 50 >jack 20 100 >tom 35 70
spamよけのため、ここに「ほげぴよ」と入力してください。
削除パスワード :
クリック!