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

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

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

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

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

2回答

12580閲覧

C言語のリスト構造の並び替えについてです

G-apple-tmp

総合スコア11

C

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

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2015/01/08 06:17

お世話になっております。
現在、リスト構造内の並び替えを行うプログラムを書いております。
並び替えは、例えば、
1 2 3 4 5 6 7 8 9 10
というデータがあって、これを、奇数を前半、偶数を後半、というふうに並び替えたいです。
(1 2 3 4 5 6 7 8 9 10

1 3 5 7 9 2 4 6 8 10)

私が(正確には教授が提示したプログラムを書き換えたものですが)書いたプログラムはこうです。

lang

1#include < stdio.h > 2#include < stdlib.h > 3 4struct list 5{ 6 int data; 7 struct list *next; 8}; 9 10struct list *insert_list(int n, struct list *head1, struct list *head2) 11{ 12 if( n==1 ) // n=1のとき、現在のデータの直前に挿入 13 { 14 head2->next = head1; 15 return head2; 16 } 17 18 else 19 { 20 if( head1->next == NULL ) // n=1 になる前にリストの最後尾に到達したので最後尾に追加 21 { 22 head1->next = head2; 23 } 24 25 else 26 { 27 head1->next = insert_list(n-1, head1->next, head2); 28 } 29 30 return head1; 31 } 32} 33 34// リスト構造の先頭に新しいデータを追加する関数(課題1と同じ) 35struct list *add_list(int x, struct list *head) 36{ 37 struct list *new_head; // 宣言 38 new_head = (struct list *)malloc(sizeof(struct list)); // 領域確保 39 40 new_head->data = x; // 新しいデータの代入 41 new_head->next = head; // 古い head を新しい head の次のデータに指定 42 43 return new_head; 44} 45 46struct list *delete_list(int num, struct list *head) 47{ 48 struct list *p; 49 50 // num=1の場合、このデータを消す。つまり、次のデータのポインタを返す。 51 // num>1 の場合、このデータはそのままつなげる。つまり、自分のポインタを返す。 52 if( num == 1 ) 53 { 54 return head->next; 55 } 56 57 else 58 { 59 60 if( head->next == NULL ) // num=1になる前にNULLが来た場合は、指定ミス 61 { 62 printf("指定されたデータは存在しません\n"); 63 } 64 65 else 66 { 67 head->next = delete_list(num-1,head->next); // 再帰呼び出しで、次のデータへ 68 } 69 return head; 70 } 71} 72 73void show_list(struct list *head) 74{ 75 if( head == NULL ) 76 { 77 printf("\n\n"); 78 } 79 else 80 { 81 printf("%d ",head->data); 82 show_list(head->next); 83 } 84} 85 86list *sort(list *headEx) 87{ 88 list *p1,*Array,tmp; 89 int n,i; 90 91 if(headEx==NULL||headEx->next==NULL) 92 return headEx; 93 94 for(p1=headEx,n=0;p1;p1=p1->next,n++); 95 96 if((Array=(list*)calloc(n,sizeof(list)))==NULL) 97 { 98 perror("calloc()"); 99 exit(1); 100 } 101 102 for(i=0,p1=headEx;i<n;i++,p1=p1->next) 103 Array[i] = *p1; 104 105 for(i=0;i<n;i++) 106 printf("Array[%d]=%d\n\n",i,Array[i]); 107 108 for(i=1;i<n;i++) 109 { 110 if(Array[i]%2==1)//←ココ 111 { 112 tmp=Array[i]; 113 Array[i]=Array[i-1]; 114 Array[i-1]=tmp; 115 } 116 } 117 118 119 120 free(Array); 121} 122 123void main() 124{ 125 int a,n; // 入力用変数 126 struct list *head1, *head2; // リスト1とリスト2 127 list *p1 ; 128 list *p2 ; 129 head1 = NULL; // 最初はNULLポインタ 130 head2 = NULL; // 最初はNULLポインタ 131 132 head1 = add_list(10,head1); 133 head1 = add_list(9,head1); 134 head1 = add_list(8,head1); 135 head1 = add_list(7,head1); 136 head1 = add_list(6,head1); 137 head1 = add_list(5,head1); 138 head1 = add_list(4,head1); 139 head1 = add_list(3,head1); 140 head1 = add_list(2,head1); 141 head1 = add_list(1,head1); 142 143 printf("リスト1:"); 144 show_list(head1); 145 146 sort(head1); 147 148 printf("(新)リスト1:"); 149 show_list(head1); 150 151 152} 153 154コード

このコードの、

lang

1for(i=1;i<n;i++) 2 { 3 if(Array[i]%2==1)//←ココ 4 { 5 tmp=Array[i]; 6 Array[i]=Array[i-1]; 7 Array[i-1]=tmp; 8 } 9 } 10 11コード

という部分、list *Arrayの偶奇を判定して、並び替えを行おうと思ったのですが、listであるArrayとintである自然数の間で演算子を用いて演算を行えません。
また、このif文を外してプログラムを実行したのですが、リストはソート前と後で何も変わっておりませんでした。
この二つを解決したいと思っております。どなたか回答お願いいたします。

_______________________

回答ありがとうございます。
訂正しましたので、sort関数の部分だけ記述致します。

lang

1list *sort(list *headEx) 2{ 3 list *p1,**Array,*tmp; 4 int n,i; 5 6 if(headEx==NULL||headEx->next==NULL) 7 return headEx; 8 9 for(p1=headEx,n=0;p1;p1=p1->next,n++); 10 11 if((*Array=(list*)calloc(n,sizeof(list)))==NULL) 12 { 13 perror("calloc()"); 14 exit(1); 15 } 16 17 for(i=0,p1=headEx;i<n;i++,p1=p1->next) 18 *Array[i] = *p1; 19 20 for(i=0;i<n;i++) 21 printf("Array[%d]=%d\n\n",i,Array[i]); 22 23 for(i=0;i<n;i++) 24 { 25 if((Array[i]->data % 2) == 1) 26 { 27 tmp=Array[i]; 28 Array[i]=Array[i-1]; 29 Array[i-1]=tmp; 30 } 31 } 32 33 return *Array; 34 35 free(Array); 36} 37

sort関数の部分で、デバッグエラーが起きてしまいます。今原因を探っているのですが、有り得ない配列の要素を参照しているようには思えず、原因がわかりません。追記でも記述いたしましたが、改めてご教授のほどよろしくお願いいたします。

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

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

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

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

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

guest

回答2

0

追記の個所について回答します。

Arrayfreeしてしまうのですから、その値をそのまま返してはいけません。
freeしたアドレスへのアクセスを行ったため、デバッグエラーになった可能性があります。

sort関数では、リンクリストを一旦配列に変換して、それを使って並べ替えたあとで、再びリンクリストに戻して返す、という動作を想定していると思います。
ですので、リンクリスト→配列の変換と逆の操作をする必要があります。

前回の「2つ目」で言っている「headExのリストに書き戻してください」というのはこういうことです。

それと、デバッグで発生する問題は、開発環境によって異なります。たとえば、Visual Studioでしたら、Visual StudioのバージョンとWindowsのバージョンを、それ以外でもOSとコンパイラーのバージョンなどを、質問の際に書いておくと、他の回答者の方々にもより詳しい解説をしていただけることが期待できます。

投稿2015/01/08 14:41

argius

総合スコア9388

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

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

0

ベストアンサー

1つ目は、ポインターの宣言に問題があるためです。
ポインターの宣言は、変数ごとにアスタリスクを付ける必要があります。

tmpp1と同じに、Arraystruct list *のさらに配列として宣言するため、アスタリスクは2つ付けます。

また、%演算の箇所は、構造体のdataの値を使うのですから、Array[i]->dataとします。

lang

1 // struct list *p1,*Array,tmp; 2 struct list *p1, **Array, *tmp; 3 4 // (中略) 5 6 for(i=1;i<n;i++) 7 { 8 // if(Array[i]%2==1)//←ココ 9 if( ( Array[i]->data % 2 ) == 1 )

2つ目は、結果を書き戻していないためです。

free(Array)の前に、Arrayの結果をheadExのリストに書き戻してください。

投稿2015/01/08 07:37

argius

総合スコア9388

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問