[ create a new paste ] login | about

Link: http://codepad.org/sqApPNGz    [ raw code | output | fork ]

C, pasted on Dec 17:
/*
名前と点数のデータを持っているリスト構造をソートさせたいのです。

(名前)	(点数)
骨川スネ夫	50
野比のび太	0
出木杉英才	100
剛田たけし	20
源静香		80

のようなデータを予め持っているとして、名前でソートしたい時はあいうえお順に、
点数でソートしたい時は0から順に並び替え、画面に出力させたいのですが、
そもそもあいうえお順でソートさせる方法が分からず、
名前と点数を同時に動かす方法も思いつかず、提出期限間近になってしまいました。
どうかお願いします。

//漢字でソートは無理だから漢字名とは別に表示させずにひらがなで名前のデータを入れておくのでしょうか?
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_STR 63  /* 全角31文字(半角63文字)まで */

typedef struct STUDENT{
  char name[MAX_STR + 1];
  char kana[MAX_STR + 1];
  int record;
} STUDENT;

typedef struct LIST{
  STUDENT data;
  struct LIST* prev;
  struct LIST* next;
} LIST;

/*
 a < b  ==> less than 0
 a = b  ==> 0
 a > b  ==> more than 0
*/

int CmpName(STUDENT* a, STUDENT* b){
  return strcmp(a->kana, b->kana);
}

int CmpRecord(STUDENT* a, STUDENT* b){
  return (a->record - b->record);
}

void Swap(LIST* prev){
  /* head-prev-next-foot */
  LIST* head = prev->prev;
  LIST* next = prev->next;
  LIST* foot = prev->next->next;
  /* prev <==> next */
  if (head != NULL)  head->next = next;
  if (foot != NULL)  foot->prev = prev;
  prev->prev = next;
  prev->next = foot;
  next->prev = head;
  next->next = prev;
}

LIST* Sort(LIST* root, int(cmp)(STUDENT*, STUDENT*)){
  /* linked list to array */
  LIST* c;
  int fswap;
  while (1){
    fswap = 0;
    for (c=root; c->next!=NULL;){
      if (0 < cmp(&c->data, &c->next->data)){
        Swap(c);
        fswap = 1;
      } else{
        c = c->next;
      }
    }
    while (root->prev != NULL)  root = root->prev;
    if (fswap == 0)  break;
  }
  return root;
}

LIST* MakeMember(const char* n, const char* k, int r, LIST* prev){
  /* alloc memory */
  LIST* m = (LIST*)malloc(sizeof(LIST));  /*諸君 私はキャストが好きだ*/  
  /* data */
  strncpy(m->data.name, n, MAX_STR);
  strncpy(m->data.kana, k, MAX_STR);
  m->data.record = r;
  /* linked list */
  m->prev = prev;
  m->next = (prev != NULL)? prev->next: NULL;
  if (m->prev != NULL)  m->prev->next = m;
  if (m->next != NULL)  m->next->prev = m;
  /* finish */
  return m;
}

void DelMember(LIST* target){
  LIST* prev;
  LIST* next;
  prev = target->prev;
  next = target->next;
  free(target);
  if (prev != NULL)  prev->next = next;
  if (next != NULL)  next->prev = prev;
}

void Show(LIST* root){
  LIST* c;
  for (c=root; c!=NULL; c=c->next)
    printf("%s\t%d\n", c->data.name, c->data.record);
}

LIST* InitList(void){
  LIST* root;
  LIST* endl;
  root = endl = MakeMember("骨川スネ夫", "ホネガワスネオ", 50, NULL);
  endl = MakeMember("野比のび太", "ノビノビタ", 0, endl);
  endl = MakeMember("出木杉英才", "デキスギエイサイ", 100, endl);
  endl = MakeMember("剛田たけし", "ゴウダタケシ", 20, endl);
  endl = MakeMember("源静香", "ミナモトシズカ", 80, endl);
  return root;
}


int main(void){

  LIST* root;
  LIST* tmp;

  root = InitList();
  printf("source data\n");
  Show(root);

  root = Sort(root, CmpRecord);
  printf("sort by record asc\n");
  Show(root);

  root = Sort(root, CmpName);
  printf("sort by name asc\n");
  Show(root);

  while (root != NULL){
    tmp = root->next;
    DelMember(root);
    root = tmp;
  }

  return 0;
}


Output:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
source data
骨川スネ夫	50
野比のび太	0
出木杉英才	100
剛田たけし	20
源静香	80
sort by record asc
野比のび太	0
剛田たけし	20
骨川スネ夫	50
源静香	80
出木杉英才	100
sort by name asc
剛田たけし	20
出木杉英才	100
野比のび太	0
骨川スネ夫	50
源静香	80


Create a new paste based on this one


Comments: