リストには、前のノードおよびリスト内の次のノードへの参照を持つノードがあります。
この関数は、リストの最初のノードを取得します。したがって、この最初のノードには前のノードがありません。このステートメントで
list->prev=allocate();
それは関数名から以下のように、それはリストの先頭に新しいノードをプッシュするため、前のノードが作成されます。このステートメントで
list->prev->next=list;
表現list->prev
は新しい作成されたノードのアドレスを生成します。この作成されたノードは、リストの現在の最初のノードを指すものとする。従って、そのデータメンバnext
は、ノードlist
のアドレスを含むものとする。
そして、この文
list->prev->next=list;
はこれを行います。
中間変数を導入するほうが簡単です。この質問
については
例えば
Element_t *new_node = allocate();
list->prev = new_node; // list->prev=allocate();
new_node->next = list; //list->prev->next=list;
list = new_node; //list=list->prev;
return list;
この意味するところ:F->ネクスト> PREV = F->前のページ?
ノードf
がリストから削除されているように見えます。今すぐ次のノード(f->next
)はf
を指していませんが、前のノードf
を指します。
ここでも、中間変数を導入するかどうかがより明確になります。
Element_t *previous_node_of_f = f->prev;
Element_t *next_node_of_f = f->next;
next_node_of_f->prev = previous_node_of_f; // f->next->prev=f->prev
もこの
previous_node_of_f->next = next_node_of_f;
のようなステートメントを追加する場合は、ノードf
は、リストから完全に削除されます。だから今、あなたが追加したい
(list)
A B C
+----------+ +----------+ +----------+
| next=B |--->| next=C |--->| next=0 |
| prev=0 |<---| prev=A |<---| prev=B |
| data="A" | | data="B" | | data="C" |
+----------+ +----------+ +----------+
を:
typedef struct Element {
struct Element * next;
struct Element * prev;
void * data;
} Element_t;
これを仮定すると、あなたのリンクリストがbasicly次のように動作します。
--------------------------------------------------------
| prev ^
| |
---------------------- ---------------------- ----------------------
| previous_node_of_f | | f | | next_node_of_f |
---------------------- ---------------------- ----------------------
| ^
| next |
-------------------------------------------------------
https://www.cs.cmu.edu/~adamchik/15-121/lectures/Linked%20Lists/linked%20lists.html良い説明 – edtheprogrammerguy