最初から:2つのリストと、返される新しいリストヘッドがあります。pnextは最初にそれを指します。
このコードは、ポインターの再割り当てをできるだけ少なくすることを目的としているため、入力リストの最初の「次の」ポインターをそのまま維持しようとします。
list1 pnext->list->Null
|
V
o->o->o...
list2
|
V
o->o->o...
スワップは、小さい要素がlist1の最初であることを確認するためにあります。それらの行が行うことは次のとおりです。
ステップバイステップで行く:
*pnext = list1;
最小の要素を含むノードを指す*pnext(最初の反復の前のリスト)を取得します。
list1
|
V
o->o->o...
^
|
list<-pnext
list2
|
V
o->o->o...
。
pnext = &list1->next;
前に述べたように、&演算子の優先順位は低いので注意が必要です。また、実際にはNode構造の一部を調べているため、グラフィカルに表示することも困難です。しかし、このようなもの:
list1
|
V
o---->o->o...
^ ^
| |
list x<-pnext
list2
|
V
o->o->o...
ここで、xは、list1が指すoの次のポインターです。
list1 = *pnext;
最初の要素が処理されるときに、list1ヘッドを進めます。
list1<-pnext
|
V
o->o->o->...
^
|
list
list2
|
V
o->o->o->...
これ以降、リストとは何の関係もありません。マージされたリストの先頭としてリストを返したいからです。
不変条件には、最後に処理された要素の次のポイントを指すpnextポイントがあります。これは、list1-2の最小の要素が移動する場所です。興味深いことはスワップで起こります。正確な手続きを自分で解決してみてください(このように描くのは難しく、**が何をするのかを理解するための良い練習です)。それを描く良い方法を見つけたら、それを追加するかもしれません。
あなたはそれがこのようなことをするので使うことができませんlist = list-> next;
:
list1
|
V
o->o->o->...
^
|
list
list2
|
V
o->o->o->...
つまり、あなたはその孤独なo(そしてループが進むにつれて最終的には他のすべて)を失うことを意味します。
編集:*pnext = list2;
最後にこれを行います:
ループ終了(上記のステートメントの前の状態):
list1<-pnext
|
V
o->o->o->null
^
|
list
o->o->o->...
^
|
list2
ステートメントの後:
list1
|
V
o->o->o Null
^ |
| |
list |
V
o->o->o->...
^
|
list2<-pnext
そのステートメントは、残りのリストをリストの最後に追加します。次に、マージされたリストの先頭を指すNode*リストが返されます。
edit2:
そして、ずっと、pnextは次のように表現する方が適切です。
list1
|
V
o->o->o Null
^ |
| |<-pnext
list |
V
o->o->o->...
^
|
list2
これは、最後に処理されたノードの次のポインターを指していることを意味します。