or
or
By clicking below, you agree to our terms of service.
New to HackMD? Sign up
Syntax | Example | Reference | |
---|---|---|---|
# Header | Header | 基本排版 | |
- Unordered List |
|
||
1. Ordered List |
|
||
- [ ] Todo List |
|
||
> Blockquote | Blockquote |
||
**Bold font** | Bold font | ||
*Italics font* | Italics font | ||
~~Strikethrough~~ | |||
19^th^ | 19th | ||
H~2~O | H2O | ||
++Inserted text++ | Inserted text | ||
==Marked text== | Marked text | ||
[link text](https:// "title") | Link | ||
 | Image | ||
`Code` | Code |
在筆記中貼入程式碼 | |
```javascript var i = 0; ``` |
|
||
:smile: | ![]() |
Emoji list | |
{%youtube youtube_id %} | Externals | ||
$L^aT_eX$ | LaTeX | ||
:::info This is a alert area. ::: |
This is a alert area. |
On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?
Please give us some advice and help us improve HackMD.
Do you want to remove this version name and description?
Syncing
## 介紹
介紹
根據作業 測驗 1 介紹的 qsort 演算法原理介紹
此處提到的方法是以 swap 為主體,
利用
L
與R
去紀錄需交換的數量,再用
begin[]
與end[]
作為堆疊,用來紀錄比較的範圍。假定下方是起始的陣列內容。
採取
head
作為pivot
,並且
L
會從左邊開始掃,紀錄有多少值小於 pivot,R
從右邊開始,紀錄有多少值大於 pivot。step 0
在
void quick_sort(node_t **list)
中會用到下列變數*begin[max_level]
和*end[max_level]
:當成堆疊,用來紀錄*list
的頭節點,尾端節點pivot
節點*left
串列的頭端和尾端節點*right
串列的頭端和尾端節點R 變數:會從右邊開始掃
*list
串列L 變數:會從左邊開始掃
*list
串列在 L 掃
*list
串列過程中,會用到*left
串列:用來紀錄有多少節點值小於 pivot,*right
串列:用來紀錄有多少節點值大於 pivot。陣列的 Graphviz 畫法參考
Graphviz draw array data structure
step 1
從
*begin[max_level]
取出一個 index 矩陣資料begin[i]
當成 L 節點從
*end[max_level]
取出一個 index 矩陣資料end[i]
當成 R 節點當
i=0;
時為例step 2.
比較的節點n value(
n->value
) 和 pivot 節點的 value (value
)list_add(n->value > value ? &right : &left, n);
n->value
值大於 pivot ,則放在right
串列(代表 pivot的右邊)n->value
值大於 pivot 為否,代表n->value
值小於 pivot ,則放在left
串列(代表 pivot 的左邊)因此經過
list_add(n->value > value ? &right : &left, n);
後right鍊結:
left鍊結:
step3.
比較結束,將
begin[i]
與end[i]
儲存left
的頭與尾,begin[i+1]
與end[i+1]
儲存pivot
,begin[i+2]
與end[i+2]
儲存right
的頭與尾,將 i 設為 i + 2 ,也就是堆疊的最上層
當
i=0;
時為例單步執行後面程式過程
當 i=2 時
step1
step2
因此經過
list_add(n->value > value ? &right : &left, n);
後right鍊結:
left鍊結:
step3
當
i=2;
時為例下一步執行 i=4 的情況
當 i=4 時
step1
因為
node_t *L = begin[4], *R = end[4];
取到的值都是 NULL ( L==R 的條件)所以直接跳到
執行完
i--
,回到i=3
的情況,重新執行 step1-step3 步驟回到 i=3 時
step1
因為
node_t *L = begin[3], *R = end[3];
取到的值都是 節點7 ( L==R 的條件)所以直接跳到
result
插入 L 節點執行完
i--
,回到i=2
的情況,重新執行 step1-step3 步驟回到 i=2 時
step1
因為
node_t *L = begin[2], *R = end[2];
取到的值都是 節點5 ( L==R 的條件)所以直接跳到
result
插入 L 節點執行完
i--
,回到i=1
的情況,重新執行 step1-step3 步驟回到 i=1 時
step1
因為
node_t *L = begin[1], *R = end[1];
取到的值都是 節點4 ( L==R 的條件)所以直接跳到
result
插入 L 節點執行完
i--
,回到i=1
的情況,重新執行 step1-step3 步驟回到 i=0 時
step1
當
i=0;
時step2
因此經過
list_add(n->value > value ? &right : &left, n);
後right鍊結:
left鍊結:
pivot:
step3
當
i=0;
時為例回到 i=2 時
step1
因為
都是
L==R
相同節點值所以都是重複執行,將 L 節點(
begin[2]~begin[0];
) 依序插入到result
串列中,變成總結
Quick Sort 分類成兩個串列
本來在 Quick Sort 遞迴版,
只要將這兩個串列再代入
void quick_sort(node_t **list)
就能進一步排序 right 串列,left 串列裡面的資料大小
但是我們 Quick Sort 是用 "非遞迴" 寫法,
所以得拆成兩個子陣列排序
例如 拆成
left
陣列 [5,7]right
陣列 [1,3,2]兩個子陣列得另外排序
幸好我們是用 link list 串列寫法,
所以不用再額外分配連續空間的子陣列空間
left 子串列 5–>7
right 子串列 1–>3–>2
為了方便管理每個子串列
因此用陣列
begin[]
和end[]
來管理每個子陣列的head 節點,尾節點,pivot
才能方便調閱每個子串列