contributed by < POCHUN-CHEN >
I have created a note to document how to use Git.
Git基本功能教學
This can avoid using an additional conditional statement at the beginning of the data.
In the program I wrote for the first time, I used this code *indirect = (*indirect)->next;
. I think this can reduce the use of pointer once and make the program more fast.
Q: why can't we replace
indirect = &(*indirect)->next;
in line 9 by
*indirect = (*indirect)->next;
?
A: head
will be changed!
See the below flow diagram:
Wrong way: *indirect = (*indirect)->next;
Correct way: indirect = &(*indirect)->next;
This is the structure diagram that I initially thought of when I first tried to understand the linked list structure.
Below diagram is an example of a singly linked list.
I have a question, why can't we put a Node_head
structure in the first List_of_head
? As shown in the following figure.
This allows for more efficient use of the Node_head
for memory space.
container_of
structuretypedef
define a type struct{...}
to a new name element_t
.
Head
is a special case without Node. It just use to serch for the list.element_t
structure, we can know the value
address through counting the type size to get it. This is why we should use "container_of".Write in English more proficiently!
Homework Request:
Use INIT_LIST_HEAD
in librarylist.h
to initialize prev
& next
.
malloc(sizeof())
to allocate memorynew
, and check the allocated memory new
action is succesful or not.INIT_LIST_HEAD
to initialize the struct list_head
and return new
.l
exist.node
to run through whole list.list_del
to pick up each del
and use q_release_element
to delete it.Debug:
q_release_element()
, instead of free()
. Because there are not element
just has itself, there are value
.element_t *del
is exist. It must exist when we allocate memeory before.curr = curr->next;
must before list_del(&del->list)
& q_release_element(del)
, or curr
will pointer a cutted list node del
. It will pointer NULL, after we delete del
.Use list_add
in librarylist.h
to add a node next to head.
malloc(sizeof())
to allocate memorynew
, and check the allocated memory new
action is succesful or not.new->value
in element_t.s
to new->value
list_add()
to add a node next to head.Debug:
strncpy(new->value, s, strlen(s));
we don't need to add one char memory size in the third input.This function is similar to q_insert_head
.
The only different part is list_add(&new->list,head)
and list_add_tail(&new->list, head)
.
!!Segmentation fault occurred. You dereferenced a NULL or invalid pointer!!
Sol:
We need to check, if memory is fail allocation, free fail allocation memory.
We need to check head
is exist and not empty.
*(removed->value + bufsize-1) = '\0';
Debug:
*(sp + bufsize-1) = '\0';
removed->value
just exist in function q_remove_head
. This is not helpful for modifying parameters.
head
is existnode
size = 0
, and iterate plus it by list_for_each
Discussing:
Why can't we use queue_contex_t *entry
to get q_size?
head
list_head
,rabbit
、turtle
。rabbit->next
、rabbit->next->next
is not head
rabbit
two steps, and turtle
one steps. It decides when rabbit
arrived head
, turtle
will stand in the middle of list.list_del(turtle)
to delete turtle
.If list monents is odd, there is a middle node from 1.
If list monents is even, there is a middle node from 0.
e.g.
The middle node of a linked list of size n is the ⌊n / 2⌋th node from the start using 0-based indexing.
Update imformation is contributed by < Risheng1128 >
head
exist.list_head
structure curr
, first
, second
. curr
will make the list move next two steps each generation. first
and second
will chanege each other.Debug:
I didn't change the pointers first->prev->next
& second->next->prev
.
Better code thinking.
Reference guide line[q_swap] in 2022q1 Homework1 (lab0) 。
list_head
second
in while loop.list_del_init
, list_add(first, second)
.head
exist.*prev
、 *cuur
、 *next
.If we want to do the code in the function at lease once, we can use pointer to pointer to NULL
. After doing the code in the function the pointer which pointers to NULL
will get meaning, we can compare it in the function condition.
Discussing:
list_del_init(curr)
and list_add(curr,&list)
, but can use list_move(curr, &list)
?list_add_tail(&list,curr)
and list_move_tail(&list, curr)
, but can use list_splice_tail(&list, curr)
?list_move_tail(&list, curr)
better than change pointers' destinations?q_sort
has a same concept as Merge Two Sorted Lists.
Reference Source code quick-sort.c in sysprog21/linux-list programs 。
head
has more than two entry and not empty. If not return it.INIT_LIST_HEAD
to initialize two list structure we made.list_first_entry
to get first entry to set it as pivot.list_del
)list_for_each_entry_safe
). Use strncmp
to compare item->value
to pivot->value
, and seperate them to each list_less
and list_greater
.q_sort
to regress list_less
& list_greater
.list_less
before pivot in list.list_greater
after pivot in list.cmprint()
error: implicit declaration of function ‘cmpint’
Sol: use strcmp()
to replace cmprint()
or declarate function cmprint()
Merge k Sorted Lists is developed by Merge Two Sorted Lists. There is a concept that I don't really understand.
q_sort
has a same concept as Merge Two Sorted Lists.
head
is exist and not empty.list_for_each_entry
is a function which iterates over list entries. In queue_contex_t
struct, it like a 2D list. list_head *q
is a one component list, and list_head chain
is a group list made by many component lists.mergeTwoLists
to merge two lists.list_entry
is a function which gets the entry for the node.q_size
of (group_list->q)
.<stdint.h>
,when we use uintptr_t
.mergeTwoLists
: Put two lists together, and sequence them.mergesort_list
: Seperate lists.mergeTwoLists()
below.In line 4, *node = (*node)->next
has different data types. *node
is struct ListNode*
, and (*node)->next
is struct linked_head*
. Change struct ListNode*
to struct linked_head*
, and use list_entry()
to assigment element_t *L1_entry
.
node = (L1_entry->value < L2_entry->value) ? &L1 : &L2
& node = strcmp(L1_entry->value, L2_entry->value) < 0 ? &L1 : &L2
. Why strcmp()
doesn't cause "ERROR: Not sorted in ascending order (It might because of unsorted queues are merged or there're some flaws in 'q_merge')" or "ERROR: Removed value c != expected value r"?mergeTwoLists()
q_merge()
Experiment:
Output:
That means i++
is be done after once cycle of for
function done.
In 案例探討: LeetCode 21. Merge Two Sorted Lists case, why we use struct
in Line 1 ? It should be a function.
在非遞迴的實作中,原始的迭代版 merge sort 如下:
第12行程式碼意義為何?