contributed by < Shanola
>
1
考慮單向 linked list 結構,已知無 circular,嘗試以遞增順序進行 Quick sort,以下為有進行新增或修改的程式碼片段
static inline void list_concat(node_t **left, node_t *right) {
while (*left)
left = &((*left)->next);// LLL
*left = right;
}
void quicksort(node_t **list)
{
if (!*list)
return;
node_t *pivot = *list;
int value = pivot->value;
node_t *p = pivot->next;
pivot->next = NULL;
node_t *left = NULL, *right = NULL;
while (p) {
node_t *n = p;
p = p->next;
list_add_node_t(n->value > value ? &right/*AAA*/ : &left/*BBB*/, n);
}
quicksort(&left);
quicksort(&right);
node_t *result = NULL;
list_concat(&result, left);
list_concat(&result, pivot);
list_concat(&result, right); ///CCC
*list = result;
}
node_t *list_make_node_t(node_t *list, int value)
{
node_t *n = malloc(1 * sizeof(node_t));
if (!n) {
assert(n && "malloc error");
return NULL;
}
n->value = value;
n->next = NULL;
n->prev = NULL;
if (!list) {
return n;
} else {
node_t *tmp = list;
while (tmp->next) {
tmp = (tmp->next);
}
tmp->next = n;
n->prev = tmp;
return list;
}
}
void list_free(node_t **list)
{
if (!(*list)->next) {
free(*list);
} else {
list_free(&((*list)->next));
}
}
首先 list_add_node_t
是一個沒有回傳值 (void) 且在編譯時被展開到呼叫位置 (static inline) 的函式,具有一個指向 node_t 指標的指標 list
,及指向 node_t 的指標 node
兩個參數,負責將節點加到 list 前方:
static inline void list_add_node_t(node_t **list, node_t *node) {
node->next = *list;
*list = node;
}
再來 list_concat
負責將兩個 list 連接起來:
static inline void list_concat(node_t **left, node_t *right) {
while (*left)
left = &((*left))->next;// LLL
*left = right;
}
在這個遞迴式的 quicksort
函式中,會先以 list 中的第一個節點當作 pivot,將所有比 pivot 小的值連接到 left
list 上,而比較大的則會接到 right
list 上,然後再對這兩個 list 遞迴做 quick sort,最後再將 left, pivot, right 連接起來。
long int random(void)
是屬於 stdlib.h 標準函式庫中的函式,該函式根據 seed
去 table 找大小為 31 的 long int 的序列的其中一個值來回傳,但這個 seed 若沒有被指定時會自動餵入 1,也因此使得 random 每次回傳的亂數看似是固定的。
有一個常見的解決方法是使用 void srandom(unsigned int seed)
來填入 seed,填入的 seed 可以用一個隨時變化的值(譬如時間),如此一來 random 回傳的值所屬的序列便會隨時間變換,每次回傳的值的序列也不一樣。
將 __node
結構多一個指標以指向前一個節點:
typedef struct __node {
int value;
struct __node *next;
struct __node *prev;
} node_t;
有改寫過後的函式變成:
list_make_node_t
node_t *list_make_node_t(node_t *list, int value)
{
node_t *n = malloc(1 * sizeof(node_t));
if (!n) {
assert(n && "malloc error");
return NULL;
}
n->value = value;
n->next = NULL;
n->prev = NULL;
if (!list) {
return n;
} else {
node_t *tmp = list;
while (tmp->next) {
tmp = (tmp->next);
}
tmp->next = n;
n->prev = tmp;
return list;
}
}
linux2021
1. 什麼是區塊鏈,對我們有什麼好處 區塊鏈是分散式帳本 (Distributed Ledger Technology) 的一種應用,透過分散式的節點替人們保存有用的資訊,而不依靠中央存儲節點。因此區塊鏈也可視為一種資料庫,並以密碼學、共識演算法等技術保障其安全、同步。 區塊鏈的起源 (Bitcoin) 中本聰在 2008 年發表《Bitcoin: A Peer-to-Peer Electronic Cash System》,提到了如 P2P 網路、transaction、timestamp server、密碼學等區塊鏈的核心技術。並於 2009 年一月三號產生第一個區塊,稱為創世區塊 (Genesis block);一月九號產生第二個區塊,兩者相連誕生區塊鏈。 應用領域 舉凡會產生資料、保存資料、交換資料等需求的應用,都可以加入區塊鏈。 e.g., 數位貨幣、車載網路、工業控制網路等等
Aug 11, 2021(上) 前情提要 我發現我的程式會崩潰,甚至連第一個 entry 都加不進去,以下是我將 pointer to pointer 改寫為指標的程式片段 : void add_entry(node_t *h, int new_value) { /*create new_node*/ //printf(Address of h = %p, &h) if(h == NULL) h = new_node; else {
Apr 19, 2021contributed by < Shanola > 測驗 1 POSIX Thread (pthread) API 認識 透過 pthread 可以實現並行化的程式,對於多核或多處理器的系統中可以平行化或分散式執行,進而提高程式效能。相較於透過 forking 來產生的行程不必再配置記憶空間而是共享一個行程的資源。 Thread(執行緒) 的操作有 建立 終止 同步 排程 資料管理 行程互動: pthread_create() 建立新的執行緒,成功時回傳 0,反之回傳錯誤值。
Mar 21, 2021contributed by < tsengsam > 第一週測驗題 測驗 1 題目為一個沒有 circular 的 singly-linked list,其資料結構為 : typedef struct __node { int value; struct __node *next; } node_t;
Mar 4, 2021or
By clicking below, you agree to our terms of service.
New to HackMD? Sign up