- 電腦:Digital Ocean Basic Droplet(Premium AMD with NVMe SSD)
- 作業系統:debain 10
- CPU: 1 AMD vCPU
- RAM: 1GB
-
string(不唯一)
-
使用一個陣列儲存英文字母小寫"a" 到大寫"Z"
-
生成一個從0到51隨機數字,每次生成一個數字都代表一個英文字母
-
根據指定數字,生成一個陣列再將英文字母分別放到陣列中
function GenRandStr(length){ charset="abcde...."; for (i=0;i<length;i++){ index = rand()%52; randstring[i] = charset[index]; } return randstring; }
-
-
string(唯一)
-
使用hashtable確認之前的string是否出現過
string = GenRandStr(length); if (checkHashTable(string)){ //檢查是否出現過 print(string); }
-
-
Linked List
-
建立
-
定義一個Node struct內含Data以及一個pointer to Node
-
每次新增一筆資料就新增一個Node以及將上一個Node的pointer指向目前的Node
struct Node { var Data; Node* ptr; }; function insertLinkedList(node,data){ newNode = new Node(); newNode.Data = data; if(node == NULL) return newNode; node.ptr = newNode; return node; }
-
-
查詢
-
檢查當前Node的Data資料,若不是要找的資料則移到下一個,指到下一個是NULL
function findNode(node,value){ while(node!=NULL){ if (node.Data == value) return node; else node = node.ptr; } return NULL; }
-
-
-
Array
-
建立
-
建立一個array
-
將資料依序從0開始插入
var arr[]; function insert(arr,idx,value){ arr[idx] = value; } for (i=0;i<length;i++){ insert(arr,i,value); }
-
-
查詢
-
從第0 個位址開始一個一個檢查,若找不到則回傳-1
function searchArray(arr,value,length){ for(i=0;i<length;i++){ if(arr[i] == value) return i; } return -1; }
-
-
-
Array With Binary Search
-
建立
-
同Array,但最後將其資料排序
/* ... */ //同Array sort(arr);
-
-
查詢
-
將Array中最靠近中間的元素拿出來與被查詢值比較,並將Array以此分為左Array、中間、右Array
-
若值一樣則為找到元素,若較大則對左Array執行步驟1與2,若較小則對右Array執行步驟1與2,直到找到元素或無法拿出中間的元素。
function binarySearch(arr,value,start,end){ if(start > end) return -1; mid = (start + end) /2; if(arr[mid] == value){ return mid; } if (arr[mid] > value) return binarySearch(arr,value,start,mid-1); else return binarySearch(arr,value,mid+1,end); }
-
-
-
Binary Search Tree
-
建立
-
定義一個Node struct內含Data以及兩個pointer to Node名稱為left與right
-
插入資料時,若原本沒有node則新增個node
-
若已存在node則從root node開始比較,若node的值比查詢值大則往left node 走,若較小則往right node 走
-
重複步驟3直到right node 或 left node 為NULL
-
在當前位址新增一個node
struct Node { var Data; Node* left; Node* right; }; function insertBinarySearchTree(node,value){ if(node == NULL){ newNode = new Node(); newNode.Data = value; return newNode; } Node * last; while(node){ last = node; if(node.Data > value) node = node.left; else node = node.right; } node = new Node()); node.Data = value; if(last.Data > value) last.left = node; else last.right = node; }
-
-
查詢
-
從root node開始,若node的值比查詢值大則往left node 走,若較小則往right node 走
-
重複步驟一直到找到或node為NULL
function find(node,value){ while(node){ if (node.Data == value) return node; else if (node.Data > value) node = node.left; else node = node.right; } return NULL; }
-
-
-
AVL
-
建立
-
定義一個Node struct內含Data、Height以及兩個pointer to Node名稱為left與right
-
插入資料時,若原本node為NULL則新增個node,並將其Height設為1
-
若已存在node則從root node開始比較,若node的值比查詢值大則呼叫自己並將node.right傳入,若較小則往呼叫自己並將node.left傳入
-
步驟3會回傳node,計算此node的Height並將得到的hieght傳入node.Height
-
計算node的balancefactor並對其進行平衡
function insert(node,value){ if (node == NULL){ newNode = new Node(); newNode.Data = value; newNode.Height = 1; return newNode; } if (node.Data > value) node.right = insert(node.right,value); else node.left = insert(node.left,value); node.Height = getNodeHeight(node); //計算node高度 if (balanceFactor(node) == 2 && balanceFactor(node->left) == 1) return LL(node); //LL,LR,RR,RL 會對node進行平衡 else if (balanceFactor(node) == 2 && balanceFactor(p->left) == -1) return LR(p); else if (balanceFactor(p) == -2 && balanceFactor(p->right) == -1) return RR(p); else if (balanceFactor(p) == -2 && balanceFactor(p->right) == 1) return RL(p); return node }
-
-
查詢
- 與Binary Search Tree一樣
-
-
Hash
-
建立
-
建立一個大小為n的array其元素為指向linked list的pointer
-
使用hash function對要插入的資料產生一個大小小於n的值idx
-
檢查array[a]是否已有linked list 存在,若沒有則建立一個並將值插入,若有找linked list的最尾端並將值插入
function insert(array,value,index){ var idx = hashFunction(value); if(array[idx]==NULL) { array[idx] = new LinkedList(); array[idx].Data = value; return; } insertLinkedList(array[idx],value); //前述已有解釋 }
-
-
查詢
- 使用hash function對要插入的資料產生一個值idx
- 若array[idx]無值表示找不到
- 若array[idx]有值則對其linked list 執行查詢(如同第一點)
-
-
使用shell script 傳入使用者指定的資料區間給資料集生成程式(此次測試資料區間從10000到1000000)
-
使用shell script 傳入不同的argument 給以上不同的排序程式
-
程式輸出格式
| type | datalength | searchlength | datatime | searchtime |
|---|
-
使用python蒐集程式輸出資料並將資料傳入DataBase
-
使用sql查詢資料並用MetaBase圖像化,例如以下
SELECT datalength,searchlength, AVG(CASE WHEN type='string' THEN datatime END) AS "avl(data)" #使用AVG()取平均值,並用 GROUP BY datalength 可以處理傳入多次測試結果時,相同datalength會有重複資料的問題,並藉由取平均值使結果更準確 FROM "Result" GROUP BY datalength,searchlength ORDER BY datalength;
-
Linked List
時間複雜度
- 建立:Big-O(1)
- 查詢:Big-O(n)
空間複雜度: big-O(n)
-
Array
時間複雜度
- 建立:Big-O(1)
- 查詢:Big-O(n)
空間複雜度: big-O(n)
-
Array With Binary Search
時間複雜度
- 建立:Big-O(nlogn)
- 查詢:Big-O(logn)
空間複雜度: big-O(n)
-
Binary Search Tree
時間複雜度
- 建立:Big-O(logn)
- 查詢:Big-O(logn)
空間複雜度: big-O(n)
-
AVL
時間複雜度
- 建立:Big-O(logn)
- 查詢:Big-O(logn)
空間複雜度: big-O(n)
-
Hash
時間複雜度
- 建立:Big-O(1)
- 查詢:Big-O(1)
空間複雜度: big-O(n)
-
比較
從以上的折線圖中可知在建立資料時速度最快的是array和linkedlist估計是因為資料在插入時不需要做什麽處理,再來才是Hash因為Hash Function需要計算所以比較耗時間,接著是array with binary search因為資料要做排序所以耗時比 array多,最後才是BST因為每次插入都可能要比較多次,所以速度第二慢,最後是AVL因為除了要做跟BST一樣的事情還要平衡,所以速度最慢。而在查詢這方面可以明顯看出linkedlist、array最慢,但很奇特的是array在資料數量比較少的時候有時快有時慢,估計是因為測試次數不夠多或者測試資料有問題。撇除array和linked list不看後,可以由圖中得知Hash一直保持最快,而在資料量較少的時候,bst最快其次是avl再來是array with binary search,但在資料量增加後,這三個的排序剛好反過來。







