ページ 1 / 1
ポインタによる出力
Posted: 2015年10月11日(日) 18:31
by sim
コード:
#include<stdio.h>
#include<stdlib.h>
/*構造体の宣言*/
struct node
{
int data;
struct node *next;
};
int main(void)
{
/*変数宣言*/
struct node *start, *p, *end, *num;
int d;
/*リストを初期化する*/
start = end = NULL;
/*データを入力する*/
printf("Input Number : ");
scanf("%d",&d);
/*リストを作成する*/
while(d > 0)
{
/*
/* 新規ノードを作成する */
p = malloc(sizeof(struct node));
p->data = d;
p->next = NULL;
if (start == NULL)
{
/* リストが空なら先頭の位置を更新する */
start = num = p;
}
else
{
/* 新規ノードをリストの末尾に接続する */
num->next = p;
/* リストの末尾の位置を更新する */
num = p;
}
if(start->data<=p->data)
{
start->next = p;
p ->next = NULL;
}
else
{
p->next=start;
}
*/
/*データを入力する*/
printf("Input Number : ");
scanf("%d",&d);
}
/*リストを作成する*/
printf("Result : ");
for(p=start; p!=NULL; p=p->next)
{
printf("%d",p->data);
}
printf("\n");
return 0;
}
こんばんわ。今回は入力された数字を昇順に出力するプログラムがわかりません。
途中までやりました。指摘お願いします。/**/の間のみでお願いします。
Re: ポインタによる出力
Posted: 2015年10月11日(日) 20:04
by box
sim さんが書きました:
こんばんわ。今回は入力された数字を昇順に出力するプログラムがわかりません。
リストに放り込む際に昇順にしてやればよいと思います。
Re: ポインタによる出力
Posted: 2015年10月12日(月) 01:36
by かずま
sim さんが書きました:こんばんわ。今回は入力された数字を昇順に出力するプログラムがわかりません。
途中までやりました。指摘お願いします。/**/の間のみでお願いします。
end や num は何のためにあるのですか?
/**/の間のみという条件を満たすプログラムは、
次のプログラムを理解した上で、あなたが書いて見せてください。
入力と逆順のリストを作るプログラム
コード:
#include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
struct Node *next;
};
int main(void)
{
struct Node *head = NULL; // リストの先頭のノードを指すポインタ
struct Node *p; // 新規のノードを指すポインタ、または
// リストの中のノードを順に見ていくポインタ
int d;
while (scanf("%d", &d) == 1 && d != 0) {
p = malloc(sizeof(struct Node));
p->data = d;
p->next = NULL;
if (head == NULL)
head = p;
else {
p->next = head;
head = p;
}
}
for (p = head; p != NULL; p = p->next)
printf(" %d", p->data);
printf("\n");
return 0;
}
実行結果
入力順のリストを作るプログラム
コード:
#include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
struct Node *next;
};
int main(void)
{
struct Node *head = NULL; // リストの先頭のノードを指すポインタ
struct Node *tail; // リストの末尾のノードを指すポインタ
struct Node *p; // 新規のノードを指すポインタ、または
// リストの中のノードを順に見ていくポインタ
int d;
while (scanf("%d", &d) == 1 && d != 0) {
p = malloc(sizeof(struct Node));
p->data = d;
p->next = NULL;
if (head == NULL)
head = tail = p;
else {
tail->next = p;
tail = p;
}
}
for (p = head; p != NULL; p = p->next)
printf(" %d", p->data);
printf("\n");
return 0;
}
実行結果
入力を昇順にソートしたリストを作るプログラム
コード:
#include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
struct Node *next;
};
int main(void)
{
struct Node *head = NULL; // リストの先頭のノードを指すポインタ
struct Node *p; // 新規のノードを指すポインタ、または
// リストの中のノードを順に見ていくポインタ
struct Node *q; // リストの中のノードを順に見ていくポインタ
int d;
while (scanf("%d", &d) == 1 && d != 0) {
p = malloc(sizeof(struct Node));
p->data = d;
p->next = NULL;
if (head == NULL) // リストが空
head = p;
else if (d < head->data) { // 先頭のノードの前に挿入
p->next = head;
head = p;
}
else { // 先頭のノードの後で挿入位置を探す
for (q = head; q->next != NULL; q = q->next)
if (d < q->next->data) break; // 挿入位置が見つかった
if (q->next == NULL) // 末尾に追加
q->next = p;
else { // リストの途中に挿入
p->next = q->next;
q->next = p;
}
}
}
for (p = head; p != NULL; p = p->next)
printf(" %d", p->data);
printf("\n");
return 0;
}
実行結果
Re: ポインタによる出力
Posted: 2015年10月12日(月) 10:46
by みけCAT
普通に入力して、マージソートなどでソートをしてから出力するのがいいでしょう。
コード:
#include<stdio.h>
#include<stdlib.h>
/*構造体の宣言*/
struct node
{
int data;
struct node *next;
};
int main(void)
{
/*変数宣言*/
struct node *start, *p, *end, *num;
int d;
/*リストを初期化する*/
start = end = NULL;
/*データを入力する*/
printf("Input Number : ");
scanf("%d",&d);
/*リストを作成する*/
while(d > 0)
{
/*
*/
/* 新規ノードを作成する */
p = malloc(sizeof(struct node));
if (p == NULL)
{
perror("malloc");
return 1;
}
p->data = d;
p->next = NULL;
if (start == NULL)
{
/* リストが空なら先頭の位置を更新する */
start = num = p;
}
else
{
/* 新規ノードをリストの末尾に接続する */
num->next = p;
/* リストの末尾の位置を更新する */
num = p;
}
/*データを入力する*/
printf("Input Number : ");
scanf("%d",&d);
}
{
/* プロトタイプ宣言 */
struct node *sort(struct node *head);
int print_list(struct node *start);
/* リストをソートする */
start = sort(start);
/* ソートしたリストを出力する */
print_list(start);
}
/* リストを開放する */
for (p = start; p != NULL;)
{
num = p->next;
free(p);
p = num;
}
return 0;
}
struct node *sort(struct node *head)
{
struct node *a = NULL, *b = NULL, *i, *result = NULL;
struct node **ap = &a, **bp = &b, **rp = &result;
/* 要素が1個以下ならソートする必要が無い */
if (head == NULL || head->next == NULL) return head;
/* リストを適当に2個に分ける */
for (i = head;;)
{
/* リストAに要素を追加する */
*ap = i;
ap = &(*ap)->next;
i = i->next;
*ap = NULL;
if (i == NULL) break;
/* リストBに要素を追加する */
*bp = i;
bp = &(*bp)->next;
i = i->next;
*bp = NULL;
if (i == NULL) break;
}
/* 分けたリストをソートする */
a = sort(a);
b = sort(b);
/* ソートしたリストをマージする */
while (a != NULL && b != NULL)
{
if (a->data <= b->data)
{
*rp = a;
rp = &(*rp)->next;
a = a->next;
*rp = NULL;
}
else
{
*rp = b;
rp = &(*rp)->next;
b = b->next;
*rp = NULL;
}
}
if (a != NULL)
{
*rp = a;
}
else
{
*rp = b;
}
/* 結果を返す */
return result;
}
/* リストを出力する */
int print_list(struct node *start)
{
int d;
struct node *p;
if(0)
{
/*
*/
/*データを入力する*/
printf("Input Number : ");
scanf("%d",&d);
}
/*リストを作成する*/
printf("Result : ");
for(p=start; p!=NULL; p=p->next)
{
printf("%d",p->data);
}
printf("\n");
return 0;
}
Re: ポインタによる出力
Posted: 2015年10月12日(月) 12:48
by かずま
入力と逆順のリストを作るプログラムですが、
「末尾に追加」を特別扱いしなくてもよいので次のようになります。
コード:
#include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
struct Node *next;
};
int main(void)
{
struct Node *head = NULL; // リストの先頭のノードを指すポインタ
struct Node *p; // 新規のノードを指すポインタ、または
// リストの中のノードを順に見ていくポインタ
struct Node *q; // リストの中のノードを順に見ていくポインタ
int d;
while (scanf("%d", &d) == 1 && d != 0) {
p = malloc(sizeof(struct Node));
p->data = d;
p->next = NULL;
if (head == NULL) // リストが空
head = p;
else if (d < head->data) { // 先頭のノードの前に挿入
p->next = head;
head = p;
}
else { // 先頭のノードの後で挿入位置を探す
for (q = head; q->next != NULL; q = q->next)
if (d < q->next->data) break; // 挿入位置が見つかった
p->next = q->next;
q->next = p;
}
}
for (p = head; p != NULL; p = p->next)
printf(" %d", p->data);
printf("\n");
return 0;
}
whileループの中で場合分けをしていますが、これをしなくてもよいようにするテクニックがあります。
コード:
#include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
struct Node *next;
};
int main(void)
{
struct Node head; // リストの先頭のノードを指すポインタを持つノード
struct Node *p; // 新規のノードを指すポインタ、または
// リストの中のノードを順に見ていくポインタ
struct Node *q; // リストの中のノードを順に見ていくポインタ
int d;
head.next = NULL;
while (scanf("%d", &d) == 1 && d != 0) {
p = malloc(sizeof(struct Node));
p->data = d;
for (q = &head; q->next != NULL; q = q->next)
if (d < q->next->data) break; // 挿入位置が見つかった
p->next = q->next;
q->next = p;
}
for (p = head.next; p != NULL; p = p->next)
printf(" %d", p->data);
printf("\n");
return 0;
}
Re: ポインタによる出力
Posted: 2015年10月12日(月) 13:21
by かずま
かずま さんが書きました:入力と逆順のリストを作るプログラムですが、
すみません。訂正です。「入力を昇順にソートしたリストを作るプログラム」でした。
Re: ポインタによる出力
Posted: 2015年10月12日(月) 14:32
by sim
コード:
while(d > 0)
{
/* 新規ノードを作成する */
p = malloc(sizeof(struct node));
p->data = d;
p->next = NULL;
if (start == NULL)
{
/* リストが空なら先頭の位置を更新する */
start = num = p;
}
else
{
/* 新規ノードをリストの末尾に接続する */
num->next = p;
/* リストの末尾の位置を更新する */
num = p;
}
if(start->data<=p->data)
{
start->next = p;
p ->next = NULL;
}
else
{
p->next=start;
}
このプログラムの状態からは、できないのですか?(未完成)
Re: ポインタによる出力
Posted: 2015年10月12日(月) 15:18
by かずま
sim さんが書きました:このプログラムの状態からは、できないのですか?(未完成)
最初のプログラムと同じ行数です。削除は一切行っていません。変更部分も追加だけです。
コード:
#include<stdio.h>
#include<stdlib.h>
/*構造体の宣言*/
struct node
{
int data;
struct node *next;
};
int main(void)
{
/*変数宣言*/
struct node *start, *p, *end, *num;
int d;
/*リストを初期化する*/
start = end = NULL;
/*データを入力する*/
printf("Input Number : ");
scanf("%d",&d);
/*リストを作成する*/
while(d > 0)
{
/*
*/ // 追加
/* 新規ノードを作成する */
p = malloc(sizeof(struct node));
p->data = d;
p->next = NULL;
if (start == NULL)
{
/* リストが空なら先頭の位置を更新する */
start = num = p;
}
else if (0) // 変更
{
/* 新規ノードをリストの末尾に接続する */
num->next = p;
/* リストの末尾の位置を更新する */
num = p;
} else // 変更
if(start->data<=p->data)
{ if (0) // 変更
start->next = p;
p ->next = NULL; for (num = start; num->next && num->next->data < d; num = num->next); p->next = num->next; num->next = p; // 変更
}
else
{
p->next=start;
start = p; // 追加
}
/* // 追加
*/
/*データを入力する*/
printf("Input Number : ");
scanf("%d",&d);
}
/*リストを作成する*/
printf("Result : ");
for(p=start; p!=NULL; p=p->next)
{
printf("%d",p->data);
}
printf("\n");
return 0;
}
実行結果
コード:
Input Number : 3
Input Number : 1
Input Number : 4
Input Number : 2
Input Number : 0
Result : 1234
Re: ポインタによる出力
Posted: 2015年10月12日(月) 16:27
by sim
指摘ありがとうございます。一様やってみましたが,インプットナンバーがループしてしまうときがあります。
コード:
#include<stdio.h>
#include<stdlib.h>
/*構造体の宣言*/
struct node
{
int data;
struct node *next;
};
int main(void)
{
/*変数宣言*/
struct node *start, *p, *end, *num, *q;
int d;
/*リストを初期化する*/
start = end = NULL;
/*データを入力する*/
printf("Input Number : ");
scanf("%d",&d);
/*リストを作成する*/
while(d > 0)
{
/* 新規ノードを作成する */
p = malloc(sizeof(struct node));
p->data = d;
p->next = NULL;
if (start == NULL)
{
/* リストが空なら先頭の位置を更新する */
start = num = p;
}
else if(0)
{
/* 新規ノードをリストの末尾に接続する */
num->next = p;
/* リストの末尾の位置を更新する */
num = p;
}
else if(start->data<=p->data)
{
start->next = p;
p ->next = NULL;
}
else if(0)
{
p->next = num->next;
num->next = p;
}
else
{
p->next=start;
start = p;
}
/*データを入力する*/
printf("Input Number : ");
scanf("%d",&d);
}
/*リストを作成する*/
printf("Result : ");
for(p=start; p!=NULL; p=p->next)
{
printf("%d",p->data);
}
printf("\n");
return 0;
}
Re: ポインタによる出力
Posted: 2015年10月12日(月) 16:57
by かずま
sim さんが書きました:指摘ありがとうございます。一様やってみましたが,インプットナンバーがループしてしまうときがあります。
51~54行目がダメ。なぜ、意味を理解しようとしないのですか?
Re: ポインタによる出力
Posted: 2015年10月12日(月) 17:00
by box
sim さんが書きました:指摘ありがとうございます。一様やってみましたが,インプットナンバーがループしてしまうときがあります。
コード:
else if(0)
else if(0)
if(0)
って何ですか?
Re: ポインタによる出力
Posted: 2015年10月12日(月) 17:02
by かずま
コードを付けるのを忘れました。
コード:
while (d > 0) {
p = malloc(sizeof(struct node)); /* 新規ノードを作成する */
p->data = d;
p->next = NULL;
if (start == NULL) { /* リストが空なら */
start = p; /* 先頭の位置を更新する */
}
else if (start->data <= p->data) { /* 先頭が小さければ */
struct node *q; /* 先頭の次から、挿入位置を探し */
for (q = start; q->next && q->next->data < d; q = q->next) ;
p->next = q->next; /* 挿入する */
q->next = p;
}
else { /* 先頭が大きければ */
p->next = start; /* 先頭の前に挿入 */
start = p;
}
if (0) というのは、次の文を無視するためのもので、意味を理解して削除してほしかった。
Re: ポインタによる出力
Posted: 2015年10月12日(月) 17:20
by sim
すみません。一様、図に書いてやっていたのですがfor文がうかばなかったのです。
随時、理解していきます。また、参考にさせていただきます。
Re: ポインタによる出力
Posted: 2015年10月13日(火) 10:32
by かずま
sim さんが書きました:すみません。一様、図に書いてやっていたのですがfor文がうかばなかったのです。
for文は、入場所を探すというコメントを付けて、何度も指摘しています。
入力データを、先頭の前か、末尾にしか追加しないと、昇順にならないことは自明です。
ということで、最終的には次のようにするのが良いと思います。
コード:
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node *next;
};
int main(void)
{
struct node head, *p, *q;
int d;
head.next = NULL; /* リストを初期化する */
while (printf("Input Number : "), scanf("%d", &d) == 1 && d > 0) {
p = malloc(sizeof(struct node)); /* 新規ノードを作成する */
p->data = d;
for (q = &head; q->next != NULL && q->next->data < d; q = q->next) ;
p->next = q->next; /* 挿入場所を探して、挿入する */
q->next = p;
}
printf("Result : "); /* リストを表示する */
for (p = head.next; p != NULL; p = p->next)
printf(" %d", p->data);
printf("\n");
return 0;
}
while文の中の式が煩雑だと思うなら、次のように書くこともできます。
コード:
while (1) {
printf("Input Number : ");
if (scanf("%d", &d) != 1 || d <= 0) break;
一様ではなく、一応です。