Try   HackMD

lib/list_sort.c sort執行流程

起始狀態

且設A<B<C

A = 0x555555566eb8;
B = 0x555555566f68;
c = 0x555555567018;

count = 0;

// queue的第一格節點
pending = NULL
list = 0x555555566eb8 // A






foo



head

 

head

 



a

A

 

 



head:c->a






c

C

 

 



head:c->c






a:c->head






b

B

 

 



a:c->b






b:c->a






b:c->c






c:c->b






pending

pending



list

list



list->a





list->prev = pending // A->prev = NULL
pending = list // A
list = list->next // B
pending->next = NULL // A->next = NULL






foo



head

 

head

 



a

A

 

 



head:c->a






c

C

 

 



head:c->c






b

B

 

 



b:c->a






b:c->c






c:c->b






pending

pending



pending->a





list

list



list->b






count = 1

tail = &pending; // pending point to A

// enter for loop
tail = &(*tail)->prev // tail point to pending->prev (0x555555566eb8)






foo



head

 

head

 



a

A

 

 



head:c->a






c

C

 

 



head:c->c






b

B

 

 



b:c->a






b:c->c






c:c->b






tail

tail



pending

pending



tail->pending





pending->a





list

list



list->b





list->prev = pending // B->prev = A (nothing change)
pending = list // pending = B
list = list->next // list = C
pending->next = NULL // B->next = NULL






foo



head

 

head

 



a

A

 

 



head:c->a






c

C

 

 



head:c->c






b

B

 

 



b:c->a






c:c->b






tail

tail



pending

pending



tail->pending





pending->b





list

list



list->c






count = 2

// ready for merge
a = *tail // B
b = a->prev // A






foo



head

 

head

 



a

A

 

 



head:c->a






c

C

 

 



head:c->c






b

B

 

 



b:c->a






c:c->b






tail

tail



pending

pending



tail->pending





pending->b





list

list



list->c





newA

a



newA->b





newB

b



newB->a





merging

head = NULL
tail = &head

*tail = a; // head = A
tail = &a->next // tail = NULL (go to next term)
a = a->next // a = NULL (go to next term)

*tail = b // A->next = B






foo



head

 

head

 



a

A

 

 



head:c->a






c

C

 

 



head:c->c






b

B

 

 



a:c->b






b:c->a






c:c->b






headPtr

head



headPtr->a





tail

tail



tail->b





newA

a



newB

b



newB->b





after merge

// 被合併的list會由head到tail接好
// 尚未被合併的list會由tail利用prev一路往前接

// 此處應該是在處理順序調換後和原本list相接的部分
a->prev = b->prev // nothing change






foo



head

 

head

 



a

A

 

 



head:c->a






c

C

 

 



head:c->c






b

B

 

 



a:c->b






b:c->a






c:c->b






tail

tail



pending

pending



tail->pending





pending->a





list

list



list->c





newA

a



newA->a





newB

b



newB->a





list->prev = pending // C->prev = A
pending = list // pending = C
list = list->next // list = NULL (到底了)
pending->next = NULL






foo



head

 

head

 



a

A

 

 



head:c->a






c

C

 

 



head:c->c






b

B

 

 



a:c->b






b:c->a






c:c->a






tail

tail



pending

pending



tail->pending





pending->c





list

list



list = pending // list = C
pending = pending->prev // pending = A (要併進去的list頭)






foo



head

 

head

 



a

A

 

 



head:c->a






c

C

 

 



head:c->c






b

B

 

 



a:c->b






b:c->a






c:c->a






tail

tail



pending

pending



tail->pending





pending->a





list

list



list->c





prepare for merge remain nodes

// 盡可能地往前合併
next = pending->prev // next = NULL (沒東西能再併了)
// 跳出for loop

merge final

// 將所有剩餘節點合併並串起來
tail = head
count = 0


// 第一次迴圈
// cmp(a,b) < 0

// 重建double linked結構
tail->next = a
a->prev = tail
tail = a

// a轉到下一項
a = a->next






foo



head

 

head

 



a

A

 

 



head:c->a






c

C

 

 



head:c->c






a:c->head






b

B

 

 



a:c->b






b:c->a






c:c->a






tail

tail



tail->a





newA

a



newA->b





newB

b



newB->c





// 第二次迴圈
// cmp(a,b) < 0

// 重建double linked結構
tail->next = a // tail->next = B (A->next = B)
a->prev = tail // B->prev = A
tail = a // tail = B

// a轉到下一項
a = a->next  // a = NULL

跳出迴圈






foo



head

 

head

 



a

A

 

 



head:c->a






c

C

 

 



head:c->c






a:c->head






b

B

 

 



a:c->b






b:c->a






c:c->a






tail

tail



tail->b





newA

a



newB

b



newB->c





// 合併剩下還沒被併進去的節點
tail->next = b // B->next = C (直接把剩下還沒合併的接起來)

// enter while loop

// 重建 double linked 結構
b->prev = tail // C->prev = B
tail = b // tail = C
b = b->next; // b = NULL (後面沒東西併了)

跳出迴圈






foo



head

 

head

 



a

A

 

 



head:c->a






c

C

 

 



head:c->c






a:c->head






b

B

 

 



a:c->b






b:c->a






b:c->c






c:c->b






tail

tail



tail->c





newA

a



newB

b



newB->c





// 完成tail和head的link
tail->next = head // C->next = head
head->prev = tail // head->prev = C






foo



head

 

head

 



a

A

 

 



head:c->a






c

C

 

 



head:c->c






a:c->head






b

B

 

 



a:c->b






b:c->a






b:c->c






c:c->head






c:c->b






tail

tail



tail->c





newA

a



newB

b



newB->c