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

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

新規登録して質問してみよう
ただいま回答率
85.48%
C

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

Q&A

解決済

1回答

11435閲覧

単方向連結リストを逆順に表示

kt3302y

総合スコア27

C

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

0グッド

0クリップ

投稿2015/06/21 06:09

編集2015/06/21 09:09

下記のコードはノードのデータを逆順に表示するプログラムです。
私の考えとしてはノードを逆順にしてからそれを表示するという手法でやっているのですが、結果が改良する前と変わらないのです。どこが違うのか教えていただけませんか。
horohoroさんに言われて間違いに気づき下記のように編集したのですが
結果 <28><40><33><15>
<15><33><40>
<40><33>
<33>
(empty)
このようになってしまい、一番上しか逆になっていません
どうすればよいのでしょうか。
/*

  • list1.c: 片方向連結リストの例プログラム

*/

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

/* 連結リスト中のノードの構造体 /
struct node {
int val; /
値 */
struct node next; / 次ノード */
};

/* セルとそのポインタの型 */
typedef struct node Node;
typedef Node *NodePtr;

/* セルを一つ生成 */
NodePtr create_node(int v) {
NodePtr n = NULL;

n = malloc(sizeof(Node)); n->val = v; n->next = NULL; return n;

}

/* セルを表示 */
void print_node(NodePtr n) {
if (n != NULL) {
printf("<%d>", n->val);
}
else {
printf("(null)");
}
}

/* 連結リストの構造体 /
struct list {
/
先頭セルへのポインタ */
NodePtr head;
};

/* 連結リストとそのポインタの型 */
typedef struct list List;
typedef List *ListPtr;

/* 空の連結リストを生成 */
ListPtr create_list(void) {
ListPtr l = NULL;
l = malloc(sizeof(List));
l->head = NULL;
return l;
}

/* 連結リスト l が空かどうか判定 */
int is_empty(ListPtr l) {
return (l->head == NULL);
}

/* リスト l の内容を表示 */
void print_list(ListPtr l) {
NodePtr n = NULL;

if (is_empty(l)) { printf("(empty)\n"); return; } n = l->head; while (n != NULL) { print_node(n); n = n->next; } printf("\n");

}

/* リスト l の先頭にセルを挿入 */
void add_first(ListPtr l, int val) {
NodePtr n = NULL;
n = create_node(val);
n->next = l->head;
l->head = n;
}

/* リスト l の先頭セルを削除 */
int delete_first(ListPtr l) {
NodePtr n = NULL;
int v;

/* リストが空なら -1 を返す(負の値はリストに含まれないと仮定)*/ if (is_empty(l)) return -1; v = l->head->val; n = l->head; l->head = l->head->next; free(n); n = NULL; return v;

}

/* 連結リスト l のサイズを取得 */
int get_list_size(ListPtr l) {
NodePtr n = NULL;
int size;

size = 0; n = l->head; while (n != NULL) { size++; n = n->next; } return size;

}

/*

  • 連結リスト l における index 番目のセルの値を取得
  • (そのようなセルが存在しなければ -1 を返す)

*/
int get_value(ListPtr l, int index) {
NodePtr n = NULL;
if (index < 0) return -1;

n = l->head; while (index > 0 && n != NULL) { n = n->next; index--; } return (n == NULL) ? -1 : n->val;

}

/* リスト l 中の全セルを削除(ループ版)*/
void delete_all(ListPtr l) {
NodePtr n = NULL, m = NULL;

n = l->head; while (n != NULL) { m = n; n = n->next; free(m); } l->head = NULL;

}

/* セル n 以降を全て削除(内部処理用の再帰関数)*/
void delete_rest(NodePtr n) {
if (n->next != NULL) delete_rest(n->next);
free(n);
}

/* リスト l 中の全セルを削除(再帰版)*/
void delete_all_recursively(ListPtr l) {
if (l->head == NULL) return;
delete_rest(l->head);
l->head = NULL;
}

/* リスト l 全体を削除 */
#define delete_list(l) (delete_list0(l),l=NULL)
void delete_list0(ListPtr l) {
delete_all(l);
free(l);
}

/* リスト l において値 val を持つセルの位置を返す /
int get_index(ListPtr l, int value) {
/
課題1:ここに正しい実行内容を書く! */
return -1;
}

/* リスト l の位置 index に値 val を持つセルを挿入 /
void add(ListPtr l, int index, int value) {
/
課題2:ここに正しい実行内容を書く! */
}

/ノードを逆順にする/
void list_reverse(ListPtr l){

NodePtr p = NULL; NodePtr tmp = NULL; NodePtr work = NULL; /*変更箇所*/ p = l->head; while (p != NULL){ /*p->nextを書き換えるため一時退避*/ tmp = p->next; p->next = work; work = p; p = tmp; } l->head = work;//変更箇所

}

/ノードを逆順に表示/
void print_list_in_reverse(ListPtr l){
NodePtr n = NULL;

if (is_empty(l)) { printf("(empty)\n"); return; } list_reverse(l); n = l->head; while (n != NULL){ print_node(n); n = n->next; } printf("\n");

}

/* 連結リストの使用例 */
int main(void) {
FILE *fp = NULL;
char buf[10];
int age;
ListPtr l = NULL;

l = create_list(); add_first(l, 28); add_first(l, 40); add_first(l, 33); add_first(l, 15); print_list_in_reverse(l); delete_first(l); print_list_in_reverse(l); delete_first(l); print_list_in_reverse(l); delete_first(l); print_list_in_reverse(l); delete_first(l); print_list_in_reverse(l); return 0;

}

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

軽く眺めただけですが、
list_reverse()関数が機能していませんね。
(引数 l が使用されていない)

投稿2015/06/21 06:19

horohoro

総合スコア490

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kt3302y

2015/06/21 10:03

気づかせてくれてありがとうございます。 質問を多少編集しましたので、よろしければお願いします。
horohoro

2015/06/21 12:34

print_list_in_reverse()関数の中で、list_reverse()関数を読んでますね。 ってことは、delete_first()関数直後のprint_list_in_reverse()関数の度に、 list_reverse()関数が呼ばれて、ノードが逆になるように変換されるけど、 これが意図した動作ではないってことかな。。。
kt3302y

2015/06/21 12:51

繰り返し行ってるから交互になっちゃってるんですよね すいません、初歩的なところで間違えていました。 いろいろとありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問