3


0

私は明日試験を受け、講師がクラスのウェブサイトに載せたこの二重リンクリストの例を理解しようとしていましたが、少し理解するのに苦労しています…​

これがコードです:

#include #include

typedef struct dl {int key;} float値struct dl * next。 struct dl *前へ; DL;

DL * insert(int c、float f、DL * 1){DL * new =(DL *)malloc(sizeof(DL)); if(new == NULL)exit(-1); new-> key = c; new-> value = f; if(l == NULL){new-> next = NULL; new-> prev = NULLそうでなければ(l-> key <c){while((l-> next!= NULL)

int search(int c、float * f、DL ** lptr){if(* lptr == NULL)の場合、0が返されます。 if(c <(* lptr) - > key){while(((* lptr) - >前へ!= NULL)

void printList(DL * 1){if(l == NULL)を返す。 while(l-> prev!= NULL){l = l-> prev; ; while(l!= NULL){printf( "%d、%f \ n"、l-> key、l-> value); l = 1→次。 }}

int main(void){DL *リスト= NULL。 float f; list = insert(3,5.6、list); list = insert(4,5.3、list); list = insert(7,3.6、list); list = insert(1,7.7、list); list = insert(9,2.3、list); list = insert(0,9.0、list); printList(リスト); if(検索(3、

これが出力です。

0,9.000000 1,7.700000 3,5.600000 4,5.300000 7,3.600000 9,2.300000実測値5.600000。 0,9.000000 1,7.700000 3,5.600000 4,5.300000 7,3.600000 9,2.300000

私が得ないのは "検索"機能です。 渡されるリストはDLのポインタへのポインタですね。 そして私たちは数を探しています、それで私たちはリスト全体を繰り返すために*(* lptr)=(* lptr) - > next *(またはprev)を続けます。 私が得ないものはなぜprintList()への2番目の呼び出しが全リストを印刷するかです…​ search()呼び出しが行われた後、「リスト」には検索した要素の後に要素しか含まれないはずですか? ポインタが変更されました、どうやってsearch()から戻ったときにポインタが最初の要素に戻ってリスト全体が表示されるのでしょうか。

これは、search()関数を変更して1行目に*(* lptr)= NULL を追加した場合には発生しません。printList()の2回目の呼び出しでは何も表示されず、ポインタが変更されます。今はNULLです。印刷するものは何もありません。 *( lptr)=(* lptr) - > next *が同じような効果をもたらさないのはなぜですか? ポインタも次のポインタに変更されています。2番目のprintList()呼び出しではリスト内の残りの要素だけが印刷されるべきではありませんか?

*編集:*すべての答えは正しいもののようです。私はそれを "最も古い"順に並べ替えて "最も速い"ものを受け入れます。 私は先に進み、どちらの答えが問題についてのより良い洞察を提供するかを見ることができましたが、私はすでに言われたことをすべて知っているのでそれは無関係です。 私はprintList()関数を見さえしないほど十分にばかげていて、それは問題ないと仮定しました。エラーはsearch()関数のどこかにあるとも仮定しました。 しかし、私は正しかったことを知っていました、私はポインタが変更されていて、リストがすべてを印刷することができなかったことを知っていました、しかし私は今なぜ理解します…​

6 Answer


5


`+ printList +`はリストを印刷する前に巻き戻します。

while (l->prev != NULL) { l=l->prev; };

上記の行がない場合は、見つかった要素の後にあるものだけを出力します。


4


この行はポインタを元に戻します。

while(l-> prev!= NULL){l = l-> prev; ;

そしてそれらは印刷をする:

while(l!= NULL){printf( "%d、%f \ n"、l-> key、l-> value); l = 1→次。 }

そして、これを行うにはもっと良い方法があります。追加のフィールドを追加するか、リストの最初と最後を常に指すフィールドを2つ追加するだけです。


2


私が読むことができる限り(そしてrmeadorがコメントしたように、それはかなりひどいコードです)、 `+ search `呼び出しは、見つかった要素を指すように ` list +`ポインターを変更します。

その秘訣はprintList関数です。 それが最初にすること(NULLをチェックすること以外)はこれです:

while (l->prev != NULL) { l=l->prev; };

したがって、基本的にはリストの先頭まで戻る「+ prev +」ポインタに続くため、リストの中央または末尾へのポインタが渡されても、実際の印刷はリストの先頭から開始されます。


1


printList()関数では、 `+ l = l→ prev +`を使用して、見つかった要素から戻ります。 その後、あなたはすべての内容を印刷しています。


1


_ 私が得ないものはなぜprintList()への2番目の呼び出しが全リストを印刷するかです…​ search()呼び出しが行われた後、「リスト」には検索した要素の後に要素しか含まれないはずですか? ポインタが変更されました、どうやってsearch()から戻ったときにポインタが最初の要素に戻ってリスト全体が表示されるのでしょうか。 _

あなたが持っているものは、実際にはリストへのポインタではなく、リスト内の要素へのポインタです。 printList関数がprev参照をループバックしてリストの最初の要素を見つけるためにprintList関数が最初に行うこと。


1


彼は印刷物の中のポインターを後戻りした。

while(l-> prev!= NULL){l = l-> prev; ;

リストは二重にリンクされていることを忘れないでください。 検索はリストを変更するのではなく、リストのどの部分が現在指しているのかだけを変更します。