質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.53%

  • C

    3657questions

    C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

リストのソートがうまくいきません

受付中

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 107

wagon

score 3

コード

 前提・実現したいこと

ノードを用いたソートの関数の実現

 発生している問題・エラーメッセージ

実行したところ、listの中身が一部取り除かれてしまいます

エラーメッセージ

なし

 該当のソースコード

/*(ヘッダ部)*/

#ifndef MYNODE_H
#define MYNODE_H

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

/*--- 生徒データ ---*/
typedef struct {
    char name[20];        /* 氏名 */
    int math;            /*数学*/
    int eng;            /*英語*/
} Student;

/*--- ノード ---*/
typedef struct __node {
    Student        data;    /* データ */
    struct __node *next;    /* 後続ポインタ(後続ノードへのポインタ)*/
} Node;

/*--- 線形リスト ---*/
typedef struct {
    Node *head;        /* 先頭ノードへのポインタ */
    Node *crnt;        /* 着目ノードへのポインタ */
} List;

/*--- 線形リストを初期化 ---*/
void Initialize(List *list)
{
    list->head = NULL;        /* 先頭ノード */
    list->crnt = NULL;        /* 着目ノード */
}
/*--- 一つのノードを動的に生成 ---*/
Node *AllocNode(void)
{
    if(calloc(1,sizeof(Node)) == NULL)
    {
        puts("記憶域の確保に失敗しました");
        return NULL;
    }
    else
        return calloc(1,sizeof(Node));
}
/*--- nの指すノードの各メンバに値を設定 ----*/
void SetNode(Node *n, Student *x, Node *next)
{
    n->data = *x;        /* データ */
    n->next = next;        /* 後続ポインタ */
}
/*--- 生徒データの表示(改行あり)---*/
void PrintLnStudent(const Student *x)
{
    printf("Name:%s Math:%d Eng:%d\n", x->name, x->math, x->eng);
}
/*--- 先頭にノードを挿入 ---*/
void InsertFront(List *list, Student *x)
{
    Node *ptr = list->head;
    list->head = list->crnt = AllocNode();
    SetNode(list->head, x, ptr);
}
/*--- 全ノードのデータをリスト順に表示 ---*/
void Print(const List *list)
{
    if (list->head == NULL)
        puts("ノードがありません。");
    else {
        Node *ptr = list->head;

        puts("全データを先頭ノードから順番に表示する");
        while (ptr != NULL) {
            PrintLnStudent(&ptr->data);
            ptr = ptr->next;                /* 後続ノードに着目 */
        }
    }
}
//ソートの関数
void math_sort(List *list)
{
    int min,score;
    Student tmp;
    Node *phead = list->head;
    Node *ptr_i = list->head;
    Node *ptr_j;
    Node *ptr_min;

        while(ptr_i->next != NULL)
        {
            ptr_j = ptr_i;
            ptr_min = ptr_i;
            min = ptr_i->data.math;
            //最小値を探索
            while(ptr_j->next != NULL)
            {
                ptr_j= ptr_j->next;
                score = ptr_j->data.math;
                if(min > score)
                {
                    min = score;
                    //着目ノードを変更
                    list->crnt = ptr_j;
                    ptr_min = ptr_j;
                }
            }    
            //最小値がptr_iにない場合
            if(ptr_min != ptr_i)
            {
                tmp = ptr_min->data;
                RemoveCurrent(list);
                if(ptr_i == list->head)
                {
                    InsertFront(list,&tmp);
                    ptr_i = ptr_i->next;
                }
                else
                {
                    phead = phead->next = ptr_i;
                    ptr_i = ptr_i->next;
                    phead->next = AllocNode();
                    SetNode(phead->next,&tmp,ptr_i);
                    ptr_i = ptr_i->next;
                }
            }
            //最小値がptr_iにある場合
            else
            {
                phead = phead->next;
                ptr_i = ptr_i->next;

            }

        }
}
#endif

ソースファイル
#include<stdio.h>
#include"mynode.h"

int main(void)
{
    List list;
Initialize(&list);
fset_all_Student(&list,"input.txt");
    Print(&list);
math_sort(&list);
    Print(&list);

return 0;
}

 試したこと

ファイルからの読み込みには成功していました。
実行結果はこのように表示されました
全データを先頭ノードから順番に表示する
Name:Tom Math:75 Eng:60
Name:Jerry Math:85 Eng:90
Name:Spike Math:45 Eng:30
Name:Rachel Math:55 Eng:85
Name:Monica Math:75 Eng:90
Name:Phoebe Math:80 Eng:75
Name:Chandler Math:70 Eng:65
Name:Joey Math:85 Eng:75
Name:Ross Math:90 Eng:85
全データを先頭ノードから順番に表示する
Name:Spike Math:45 Eng:30
Name:Tom Math:75 Eng:60
Name:Jerry Math:85 Eng:90
Name:Phoebe Math:80 Eng:75
Name:Chandler Math:70 Eng:65
Name:Joey Math:85 Eng:75
Name:Ross Math:90 Eng:85

上部分がファイルに入っているデータです。
下部分の表示でSpikeの次に先頭に表示したいものとその次の人のデータが消えてしまいます。
どのように修正すれば解決するでしょうか。

 補足情報(FW/ツールのバージョンなど)

visual C++ 2010

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • episteme

    2018/07/16 13:52

    うまくいかないのはノードの挿入ではなくリストのソートではないのか? であればタイトルの間違い。

    キャンセル

  • y_waiwai

    2018/07/16 14:10

    コードがベタ書きになってるので修正してください。編集ボタンを押して、<code>を押して、'''の枠の中にコードをコピペしてくだされ

    キャンセル

  • wagon

    2018/07/16 15:26

    修正させていただきました。すみません。

    キャンセル

  • rubato6809

    2018/07/17 13:26

    RemoveCurrent() はどうなってますか? とりあえず、fset_all_Student()は書けました。

    キャンセル

回答 1

+2

Node* minimum_node(Node* p) {
  p, p->next, p->next->next ... の中から最小値を持つ Node* を返す
}

void swap_node(Node* x, Node* y) {
  x->data と y->data を交換する
}

を作っておけば 

void math_sort(List *list) {
  Node* p = list->head;
  while ( p != NULL ) {
    // p以降の最小Nodeとpのナカミを交換
    swap_node(p, minimun_node(p)); 
    p = p->next;
  }
}

でよくね?

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/07/16 14:45

    こうすると Node *crnt; 不要。

    キャンセル

  • 2018/07/16 15:37

    回答ありがとうございます。
    しかしながら、今回は最小値を含むノードを削除して、そのノードを挿入していくという手順で行いたいんです。
    すみません。

    キャンセル

  • 2018/07/16 20:05

    えーと...ごめん、メンド臭いから僕はパス。

    キャンセル

  • 2018/07/16 20:32

    了解です。ありがとうございました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.53%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • C

    3657questions

    C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。