prepend 関数を作成し、次のようにします。
struct node* prepend(struct node* root, int value)
{
struct node* new_root = malloc(sizeof(struct node));
new_root->next = root;
return new_root;
}
struct node* reverselist(struct node* inlist)
{
struct node* outlist = NULL;
while(inlist != NULL) {
struct node* new_root = prepend(outlist, inlist->value);
outlist = new_root;
inlist = inlist->next;
}
return outlist;
}
これをテストしていませんが、そのアイデアを理解していると思います。何も説明していない単なる変数名かもしれませんが、このアプローチはよりクリーンで、実際に何が起こるかを理解しやすいと思います。
編集:
なぜインプレースで行わないのかという質問があったので、ここで答えます。
- その場でできますか?元のリストを保持しないでよろしいですか?
- インプレースで行う必要がありますか?malloc には時間がかかりますか? これはコードのパフォーマンス上重要な部分ですか? 注意: 時期尚早の最適化は諸悪の根源です。
つまり、これは最初の実装です。動作するはずですが、最適化されていません。また、この実装が考えられる前にテストを作成する必要があります。テストに合格するまで、この低速で最適化されていない実装を保持する必要があります。使用するには遅すぎることが証明されます!
単体テストに合格し、実装が遅いことが証明された場合は、コードを最適化し、テストを変更せずにテストに合格することを確認する必要があります。
また、答えであるインプレース操作が必要ですか?元に戻す前にメモリを割り当てるのはどうですか。この方法では、割り当て呼び出しは 1 つだけで、うまくいけばパフォーマンスが大幅に向上するはずです。
このようにして、誰もが満足し、コードがよりきれいになり、ボブおじさんがショットガンを持ってドアに現れるリスクを回避できます。