├── .gitignore ├── LICENSE ├── README.txt ├── hashTable ├── README.txt ├── dictionary │ ├── Makefile │ ├── README.txt │ ├── dict.c │ ├── dict.h │ └── dictTestMain.c ├── open-addressing │ ├── Makefile │ ├── README.txt │ ├── oa.c │ ├── oa.h │ └── oaTestMain.c └── separate-chaining │ ├── Makefile │ ├── sc.c │ ├── sc.h │ └── scTestMain.c ├── heaps ├── BinaryHeap │ ├── Makefile │ ├── bh.c │ ├── bh.h │ └── bhTestMain.c └── min-max │ ├── Makefile │ ├── mm.c │ ├── mm.h │ └── mmTestMain.c ├── linkedList ├── generic │ ├── Makefile │ ├── linkedList.c │ ├── linkedList.h │ └── linkedListTestMain.c ├── integerList │ ├── Makefile │ ├── integerList.c │ ├── integerList.h │ └── integerListTestMain.c ├── josephus │ ├── Makefile │ ├── circularLinkedList.c │ ├── circularLinkedList.h │ ├── circularLinkedListTestMain.c │ ├── nonLinkedListSol.c │ └── nonLinkedListSol.h ├── lazy-deletion │ ├── Makefile │ ├── lazyDeleteLinkedList.c │ ├── lazyDeleteLinkedList.h │ └── lazyDeleteLinkedListTestMain.c ├── polynomial │ ├── Makefile │ ├── polynomial.c │ ├── polynomial.h │ └── polynomialTestMain.c └── self-adjusting │ ├── Makefile │ ├── arrayList.c │ ├── arrayList.h │ └── arrayListTestMain.c ├── queue ├── arrayImplementation │ ├── Makefile │ ├── queue.c │ ├── queue.h │ └── queueTestMain.c ├── deque │ ├── Makefile │ ├── deque.c │ ├── deque.h │ └── dequeTestMain.c └── linkedListImplementation │ ├── Makefile │ ├── queue.c │ ├── queue.h │ └── queueTestMain.c ├── sorting ├── Makefile ├── sort.c ├── sort.h └── sortTestMain.c ├── stack ├── 2-stack-1-array │ ├── Makefile │ ├── twoStacks.c │ ├── twoStacks.h │ └── twoStacksTestMain.c ├── 3-22 │ ├── Makefile │ ├── stack322.c │ ├── stack322.h │ └── stack322TestMain.c ├── 3-stack-1-array │ ├── Makefile │ ├── threeStacks.c │ ├── threeStacks.h │ └── threeStacksTestMain.c ├── balance-symbol │ ├── Makefile │ ├── balanceSymbolMain.c │ ├── stack2.c │ ├── stack2.h │ └── test-src-files │ │ ├── README.txt │ │ ├── brackets_correct_01.c │ │ ├── brackets_correct_02.c │ │ ├── brackets_fail_01.c │ │ ├── brackets_fail_02.c │ │ ├── brackets_fail_03.c │ │ ├── brackets_fail_04.c │ │ ├── brackets_fail_05.c │ │ ├── comments_correct_01.c │ │ ├── comments_fail_03.c │ │ ├── convertInputToLowerCase.c │ │ ├── curly_brackets_correct_01.c │ │ ├── curly_brackets_correct_02.c │ │ ├── curly_brackets_fail_01.c │ │ ├── curly_brackets_fail_02.c │ │ ├── curly_brackets_fail_03.c │ │ ├── curly_brackets_fail_04.c │ │ ├── curly_brackets_fail_05.c │ │ ├── square_brackets_correct_01.c │ │ ├── square_brackets_correct_02.c │ │ ├── square_brackets_fail_01.c │ │ ├── square_brackets_fail_02.c │ │ ├── square_brackets_fail_03.c │ │ ├── square_brackets_fail_04.c │ │ └── square_brackets_fail_05.c ├── generic │ ├── Makefile │ ├── postfix.c │ ├── postfix.h │ ├── stack.c │ ├── stack.h │ ├── stackTestMain.c │ └── test-posfix-expression │ │ └── expr1 ├── postfix-c │ ├── Makefile │ ├── postfix2.c │ ├── postfix2.h │ ├── postfix2TestMain.c │ ├── stack3.c │ ├── stack3.h │ └── test-posfix-expression │ │ ├── expr1 │ │ ├── expr2 │ │ ├── expr3 │ │ ├── post2infix1 │ │ ├── post2infix2 │ │ ├── post2infix3 │ │ └── post2infix4 └── postfix │ ├── Makefile │ ├── NOTICE │ ├── postfix2.c │ ├── postfix2.h │ ├── postfix2TestMain.c │ ├── stack3.c │ ├── stack3.h │ └── test-posfix-expression │ ├── expr1 │ ├── expr2 │ └── expr3 ├── trees ├── 2-d │ ├── 2d.c │ ├── 2d.h │ ├── 2dTestMain.c │ └── Makefile ├── AVL │ ├── Makefile │ ├── avl.c │ ├── avl.h │ ├── avlTestMain.c │ ├── cse100hw1.pdf │ └── lecture12.pdf ├── BinarySearchTree │ ├── Makefile │ ├── bst.c │ ├── bst.h │ └── bstTestMain.c ├── b-tree │ ├── Makefile │ ├── btree.c │ ├── btree.h │ └── btreeTestMain.c ├── child-sibling-pointer │ ├── Makefile │ ├── csp.c │ ├── csp.h │ └── cspTestMain.c ├── orderStatisticTree │ ├── Makefile │ ├── ost.c │ ├── ost.h │ └── ostTestMain.c ├── splay │ ├── Makefile │ ├── splay.c │ ├── splay.h │ └── splayTestMain.c └── threadedTree │ ├── Makefile │ ├── tt.c │ ├── tt.h │ └── ttTestMain.c ├── union-find ├── disjSet.h ├── quick-find │ ├── Makefile │ ├── quickFind.c │ └── testquickFind.c ├── quick-union │ ├── Makefile │ ├── quickUnion.c │ └── testquickUnion.c └── smart-union-with-path-compression │ ├── Makefile │ ├── smartUnion.c │ └── testsmartUnion.c └── utility ├── Makefile ├── utility.c ├── utility.h └── utilityTestMain.c /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | .vscode 3 | .cproject 4 | .project 5 | \#* 6 | .#* 7 | main 8 | *.out 9 | *.dot 10 | main.dSYM 11 | *.png 12 | scratch 13 | gdb.txt 14 | .idea/ 15 | CMakeLists.txt 16 | cmake-build-debug/ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Zack Hu 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.txt: -------------------------------------------------------------------------------- 1 | Implementation for by Mark Allen Weiss 2 | 3 | Solution coverage: 4 | 5 | [Chapter 3] 6 | 7 | 3.1, 3.2, 3.3, 3.4, 3.5, 3.6, 3.7.a;b;d, 3.8, 3.9, 3.10, 3.11, 3.12, 3.13, 3.15, 3.17, 3.18.b;c, 8 | 3.19, 3.20, 3.21, 3.22.a, 3.23, 3.25, 3.26 9 | 10 | [Chapter 4] 11 | 12 | 4.10, 4.18, 4.19, 4.20, 4.22, 4.27, 4.28, 4.29, 4.30, 4.31, 4.32, 4.35, 4.37.a, 4.40, 4.41, 4.42, 13 | 4.44, 4.45, 4.46.b;c 14 | 15 | [Chapter 5] 16 | 17 | 5.3, 5.11.d 18 | 19 | [Chapter 6] 20 | 21 | 6.4, 6.5, 6.11, 6.15.a;b;c;d, 22 | 23 | [Chapter 7] 24 | 25 | 7.14 26 | -------------------------------------------------------------------------------- /hashTable/README.txt: -------------------------------------------------------------------------------- 1 | This module implements the basic resolving collision techniques: 2 | 3 | - separate chaining 4 | - linear probing 5 | - quadratic probing 6 | - double hashing 7 | 8 | and some questions from MAW 9 | -------------------------------------------------------------------------------- /hashTable/dictionary/Makefile: -------------------------------------------------------------------------------- 1 | C_COMPILER=gcc 2 | CFLAGS = -Wall -g 3 | 4 | # Directories 5 | ROOT = ../../ 6 | 7 | SRC_FILES=\ 8 | $(wildcard ./*.c) \ 9 | $(ROOT)utility/utility.c 10 | 11 | INC_DIRS=\ 12 | -I$(ROOT)utility/ 13 | 14 | LIBS=\ 15 | -lm 16 | 17 | OUTPUT_FILE=main 18 | 19 | .PHONY: clean 20 | .PHONY: test 21 | 22 | test: 23 | $(C_COMPILER) $(CFLAGS) $(INC_DIRS) $(LIBS) $(SRC_FILES) -o $(OUTPUT_FILE) 24 | ./$(OUTPUT_FILE) -v 25 | 26 | clean: 27 | rm -rf $(OUTPUT_FILE) 28 | -------------------------------------------------------------------------------- /hashTable/dictionary/README.txt: -------------------------------------------------------------------------------- 1 | dictionary ADT iteself is not realated to any MAW 2 | question. This is implemented for future convenience. 3 | -------------------------------------------------------------------------------- /hashTable/dictionary/dict.c: -------------------------------------------------------------------------------- 1 | #include "dict.h" 2 | 3 | static Position find(int key, HashTable H); 4 | static HashTable rehash(HashTable H); 5 | 6 | 7 | enum KindOfEntry {Legitimate, Empty, Deleted}; 8 | 9 | struct data 10 | { 11 | int Key; 12 | int Value; 13 | }; 14 | 15 | struct HashEntry 16 | { 17 | ET Element; 18 | enum KindOfEntry Info; 19 | }; 20 | 21 | struct HashTbl 22 | { 23 | int TableSize; 24 | int numElements; // keep track of number of elements we store 25 | Cell *TheCells; 26 | }; 27 | 28 | HashTable 29 | initializeTable(int TableSize) 30 | { 31 | HashTable H; 32 | int i; 33 | 34 | H = malloc(sizeof(struct HashTbl)); 35 | assert(H); 36 | 37 | H->TableSize = TableSize; 38 | H->numElements = 0; 39 | H->TheCells = malloc(sizeof(Cell) * H->TableSize); 40 | assert(H->TheCells); 41 | 42 | for(i = 0; i < H->TableSize; i++) 43 | H->TheCells[i].Info = Empty; 44 | 45 | return H; 46 | } 47 | 48 | void 49 | DestroyTable(HashTable H) 50 | { 51 | free(H->TheCells); 52 | free(H); 53 | } 54 | 55 | static Position 56 | hash(int key, 57 | int TableSize) 58 | { 59 | return key % TableSize; 60 | } 61 | 62 | /* indicates whehter the currentPos is already tried before or not 63 | */ 64 | static int 65 | isTried(Position currentPos, HashTable T) 66 | { 67 | Position tmp = find(currentPos, T); 68 | if (T->TheCells[tmp].Element.Key == currentPos && 69 | T->TheCells[tmp].Info == Legitimate) 70 | return 1; 71 | else 72 | return 0; 73 | } 74 | 75 | static Position 76 | find(int key, 77 | HashTable H) 78 | { 79 | Position currentPos; 80 | int collisionNum; 81 | collisionNum = 0; 82 | 83 | // We use another hash table to prevent the infinite loop 84 | // when certain key cannot be inserted into the target hash table. 85 | HashTable T = initializeTable(H->TableSize); 86 | currentPos = hash(key, H->TableSize); 87 | 88 | while(H->TheCells[currentPos].Info != Empty && 89 | H->TheCells[currentPos].Element.Key != key) 90 | { 91 | currentPos += 2 * ++collisionNum - 1; // quadratic hashing 92 | if(currentPos >= H->TableSize) 93 | currentPos -= H->TableSize; 94 | if(isTried(currentPos, T)) 95 | { 96 | printf("%d cannot be inserted into the table\n", key); 97 | break; 98 | } 99 | T = put(currentPos, 0, T); // we don't really care what the corresponding value is 100 | } 101 | return currentPos; 102 | } 103 | 104 | HashTable 105 | put(int key, 106 | int value, 107 | HashTable H) 108 | { 109 | Position currentPos; 110 | 111 | currentPos = find(key, H); 112 | H->TheCells[currentPos].Element.Key = key; 113 | H->TheCells[currentPos].Element.Value = value; 114 | H->TheCells[currentPos].Info = Legitimate; 115 | H->numElements++; 116 | if(0.1 * H->numElements / H->TableSize >= 0.5) // avoid integer division 117 | H = rehash(H); 118 | return H; 119 | } 120 | 121 | int 122 | retrieve(int key, 123 | HashTable H) 124 | { 125 | Position pos = find(key, H); 126 | return H->TheCells[pos].Element.Value; 127 | } 128 | 129 | static HashTable 130 | rehash(HashTable H) 131 | { 132 | HashTable newH = initializeTable(nearestPrime(2*H->TableSize)); 133 | int i; 134 | for(i = 0; i < H->TableSize; i++) 135 | { 136 | put(H->TheCells[i].Element.Key, H->TheCells[i].Element.Value, newH); 137 | } 138 | DestroyTable(H); 139 | return newH; 140 | } 141 | 142 | void 143 | printDictionary(HashTable H) 144 | { 145 | int i; 146 | for(i = 0; i < H->TableSize; i++) 147 | { 148 | if(H->TheCells[i].Info == Legitimate) 149 | printf("%d|<%d,%d>\n", i, H->TheCells[i].Element.Key, H->TheCells[i].Element.Value); 150 | else 151 | printf("%d|\n", i); 152 | } 153 | } 154 | 155 | -------------------------------------------------------------------------------- /hashTable/dictionary/dict.h: -------------------------------------------------------------------------------- 1 | // NOTE: We implement a dictionary ADT with pair using 2 | // hashTable open addressing with quadratic probing 3 | 4 | 5 | #include 6 | #include 7 | #include 8 | #include "utility.h" 9 | #include 10 | 11 | #ifndef _DICT_H 12 | #define _DICT_H 13 | 14 | typedef unsigned int Index; 15 | typedef Index Position; 16 | 17 | struct data; 18 | typedef struct data ET; 19 | struct HashEntry; 20 | typedef struct HashEntry Cell; 21 | struct HashTbl; 22 | typedef struct HashTbl *HashTable; 23 | 24 | HashTable initializeTable(int TableSize); 25 | void DestroyTable(HashTable H); 26 | /* NOTE: if the key is already in the table, then we will update the value 27 | * to the given one. 28 | */ 29 | HashTable put(int key, int value, HashTable H); 30 | /* We retrieve the corresponding value from the given key 31 | */ 32 | int retrieve(int key, HashTable H); 33 | void printDictionary(HashTable H); 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /hashTable/dictionary/dictTestMain.c: -------------------------------------------------------------------------------- 1 | #include "dict.h" 2 | 3 | void test_dictionary(); 4 | 5 | int 6 | main(void) 7 | { 8 | printf("///////////////////////\n"); 9 | printf("// DICTIONARY \n"); 10 | printf("///////////////////////\n"); 11 | 12 | test_dictionary(); 13 | return 0; 14 | } 15 | 16 | void 17 | test_dictionary() 18 | { 19 | printf("TEST: dictionary\n"); 20 | HashTable H = initializeTable(10); 21 | H = put(1,2, H); 22 | H = put(10,1,H); 23 | printDictionary(H); 24 | printf("\n"); 25 | H = put(10,3,H); 26 | printDictionary(H); 27 | DestroyTable(H); 28 | } 29 | 30 | -------------------------------------------------------------------------------- /hashTable/open-addressing/Makefile: -------------------------------------------------------------------------------- 1 | C_COMPILER=gcc 2 | CFLAGS = -Wall -g 3 | 4 | # Directories 5 | ROOT = ../../ 6 | 7 | SRC_FILES=\ 8 | $(wildcard ./*.c) \ 9 | $(ROOT)utility/utility.c 10 | 11 | INC_DIRS=\ 12 | -I$(ROOT)utility/ 13 | 14 | LIBS=\ 15 | -lm 16 | 17 | OUTPUT_FILE=main 18 | 19 | .PHONY: clean 20 | .PHONY: test 21 | 22 | # Linear Hashing 23 | linear: 24 | $(C_COMPILER) $(CFLAGS) -DLINEARH $(INC_DIRS) $(LIBS) $(SRC_FILES) -o $(OUTPUT_FILE) 25 | ./$(OUTPUT_FILE) -v 26 | 27 | # Quadratic Hashing 28 | quad: 29 | $(C_COMPILER) $(CFLAGS) -DQUADH $(INC_DIRS) $(LIBS) $(SRC_FILES) -o $(OUTPUT_FILE) 30 | ./$(OUTPUT_FILE) -v 31 | 32 | # Double Hashing 33 | double: 34 | $(C_COMPILER) $(CFLAGS) -DDH $(INC_DIRS) $(LIBS) $(SRC_FILES) -o $(OUTPUT_FILE) 35 | ./$(OUTPUT_FILE) -v 36 | 37 | clean: 38 | rm -rf $(OUTPUT_FILE) 39 | -------------------------------------------------------------------------------- /hashTable/open-addressing/README.txt: -------------------------------------------------------------------------------- 1 | Linear hashing: make Linear 2 | Quadratic hashing: make quad 3 | double hashing: make double 4 | -------------------------------------------------------------------------------- /hashTable/open-addressing/oa.c: -------------------------------------------------------------------------------- 1 | #include "oa.h" 2 | 3 | enum KindOfEntry {Legitimate, Empty, Deleted}; 4 | 5 | struct HashEntry 6 | { 7 | int Element; 8 | enum KindOfEntry Info; 9 | }; 10 | 11 | struct HashTbl 12 | { 13 | int TableSize; 14 | Cell *TheCells; 15 | }; 16 | 17 | HashTable 18 | initializeTable(int TableSize) 19 | { 20 | HashTable H; 21 | int i; 22 | 23 | H = malloc(sizeof(struct HashTbl)); 24 | assert(H); 25 | 26 | H->TableSize = TableSize; 27 | H->TheCells = malloc(sizeof(Cell) * H->TableSize); 28 | assert(H->TheCells); 29 | 30 | for(i = 0; i < H->TableSize; i++) 31 | H->TheCells[i].Info = Empty; 32 | 33 | return H; 34 | } 35 | 36 | void 37 | DestroyTable(HashTable H) 38 | { 39 | free(H->TheCells); 40 | free(H); 41 | } 42 | 43 | static Position 44 | hash(int key, 45 | int TableSize) 46 | { 47 | return key % TableSize; 48 | } 49 | 50 | /* indicates whehter the currentPos is already tried before or not 51 | */ 52 | static int 53 | isTried(Position currentPos, HashTable T) 54 | { 55 | Position tmp = find(currentPos, T); 56 | if (T->TheCells[tmp].Element == currentPos && 57 | T->TheCells[tmp].Info == Legitimate) 58 | return 1; 59 | else 60 | return 0; 61 | } 62 | 63 | Position 64 | find(int key, 65 | HashTable H) 66 | { 67 | Position currentPos; 68 | #ifdef QUADH 69 | int collisionNum; 70 | collisionNum = 0; 71 | #endif 72 | 73 | // We use another hash table to prevent the infinite loop 74 | // when certain key cannot be inserted into the target hash table. 75 | HashTable T = initializeTable(H->TableSize); 76 | currentPos = hash(key, H->TableSize); 77 | 78 | while(H->TheCells[currentPos].Info != Empty && 79 | H->TheCells[currentPos].Element != key) 80 | { 81 | #ifdef LINEARH 82 | currentPos += 1; // linear hashing 83 | #elif QUADH 84 | currentPos += 2 * ++collisionNum - 1; // quadratic hashing 85 | #elif DH 86 | currentPos += 7 - hash(key, 7); // double hashing 87 | #endif 88 | if(currentPos >= H->TableSize) 89 | currentPos -= H->TableSize; 90 | if(isTried(currentPos, T)) 91 | { 92 | printf("%d cannot be inserted into the table\n", key); 93 | break; 94 | } 95 | insert(currentPos, T); 96 | } 97 | return currentPos; 98 | } 99 | 100 | void 101 | insert(int key, 102 | HashTable H) 103 | { 104 | Position currentPos; 105 | 106 | currentPos = find(key, H); 107 | if (H->TheCells[currentPos].Info != Legitimate) 108 | { 109 | H->TheCells[currentPos].Element = key; 110 | H->TheCells[currentPos].Info = Legitimate; 111 | } 112 | } 113 | 114 | int 115 | retrieve(Position P, HashTable H) 116 | { 117 | return H->TheCells[P].Element; 118 | } 119 | 120 | HashTable 121 | rehash(HashTable H) 122 | { 123 | HashTable newH = initializeTable(nearestPrime(2*H->TableSize)); 124 | int i; 125 | for(i = 0; i < H->TableSize; i++) 126 | { 127 | insert(H->TheCells[i].Element, newH); 128 | } 129 | DestroyTable(H); 130 | return newH; 131 | } 132 | 133 | void 134 | printHashTable(HashTable H) 135 | { 136 | int i; 137 | for(i = 0; i < H->TableSize; i++) 138 | { 139 | if(H->TheCells[i].Info == Legitimate) 140 | printf("%d|%d\n", i, H->TheCells[i].Element); 141 | else 142 | printf("%d|\n", i); 143 | } 144 | } 145 | 146 | HashTable 147 | initializeTableFromArray(int* array, 148 | int arrayLength, 149 | int TableSize) 150 | { 151 | HashTable H = initializeTable(TableSize); 152 | int i; 153 | for(i = 0; i < arrayLength; i++) 154 | insert(array[i], H); 155 | return H; 156 | } 157 | 158 | // We implement the hash function 159 | // described in MAW p.151 160 | static int 161 | characterHash(char* pattern, int patternLen) 162 | { 163 | int power = 0; 164 | int hashVal = 0; 165 | for(power = 0; power < patternLen; power++) 166 | hashVal += pow(32, power) * (pattern[power] - '\0'); 167 | return hashVal; 168 | } 169 | 170 | // hashing the pattern string, obtaining a hash value 171 | // Hp, and comparing this value with the hash value formed 172 | // from A1A2...Ak, A2A3...Ak+1,A3A4...Ak+2, and so on 173 | // until AN-k+1AN-k+2...AN. If we have a match of hash values, 174 | // we compare the strings character by character to verify the match. 175 | // We return the position (in A) if the string actually do match, and 176 | // we continue in the unlikely event that the match is false. 177 | int 178 | findPattern(char* pattern, char* input) 179 | { 180 | int k = strlen(pattern); 181 | int patternHashValue = characterHash(pattern, k); 182 | int tmpHashValue; 183 | int n = strlen(input); 184 | char tmp[k+1]; 185 | int i; 186 | for(i = 0; i + k <= n; i++) 187 | { 188 | strncpy(tmp, input+i, k); 189 | tmp[k] = '\0'; 190 | tmpHashValue = characterHash(tmp, k); 191 | if (tmpHashValue == patternHashValue && !strcmp(tmp, pattern)) 192 | return i; 193 | } 194 | return -1; 195 | } 196 | -------------------------------------------------------------------------------- /hashTable/open-addressing/oa.h: -------------------------------------------------------------------------------- 1 | // NOTE: 1. This implemntation is part of open addressing hashing, 2 | // which is linear hashing. 3 | // 2. Routines such as delete and makeEmpty are omitted 4 | 5 | #include 6 | #include 7 | #include 8 | #include "utility.h" 9 | #include 10 | 11 | #ifndef _OA_H 12 | #define _OA_H 13 | 14 | typedef unsigned int Index; 15 | typedef Index Position; 16 | 17 | struct HashEntry; 18 | typedef struct HashEntry Cell; 19 | struct HashTbl; 20 | typedef struct HashTbl *HashTable; 21 | 22 | HashTable initializeTable(int TableSize); 23 | void DestroyTable(HashTable H); 24 | Position find(int key, HashTable H); 25 | void insert(int key, HashTable H); 26 | int retrieve(Position P, HashTable H); 27 | HashTable rehash(HashTable H); 28 | void printHashTable(HashTable H); 29 | HashTable initializeTableFromArray(int* array, int arrayLength, int TableSize); 30 | 31 | /* 32 | * MAW 5.11.d Suppose we want to find the first occurrence of a string p1p2...pk 33 | * in a long input string A1A2...AN. 34 | * Return the start index of p1 in A1A2...AN 35 | */ 36 | int findPattern(char* pattern, char* input); 37 | 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /hashTable/open-addressing/oaTestMain.c: -------------------------------------------------------------------------------- 1 | #include "oa.h" 2 | 3 | void test_initalizeTableFromArray(); 4 | void test_rehashing(); 5 | void test_findPattern(); 6 | 7 | int 8 | main(void) 9 | { 10 | printf("///////////////////////\n"); 11 | printf("// OPEN ADDRESSING HASHING \n"); 12 | printf("///////////////////////\n"); 13 | test_initalizeTableFromArray(); printf("=======================\n"); 14 | test_rehashing(); printf("=======================\n"); 15 | test_findPattern(); printf("=======================\n"); 16 | 17 | return 0; 18 | } 19 | 20 | void 21 | test_initalizeTableFromArray() 22 | { 23 | printf("TEST: initializeTableFromArray\n"); 24 | int array[7] = {4371, 1323, 6173, 4199, 4344, 9679, 1989}; 25 | HashTable H = initializeTableFromArray(array, 7, 10); 26 | printHashTable(H); 27 | DestroyTable(H); 28 | } 29 | 30 | void 31 | test_rehashing() 32 | { 33 | printf("TEST: rehashing\n"); 34 | int array[7] = {4371, 1323, 6173, 4199, 4344, 9679, 1989}; 35 | HashTable H = initializeTableFromArray(array, 7, 10); 36 | printHashTable(H); 37 | H = rehash(H); 38 | printf("----- rehashed table ---\n"); 39 | printHashTable(H); 40 | DestroyTable(H); 41 | } 42 | 43 | void 44 | test_findPattern() 45 | { 46 | printf("TEST: findPattern\n"); 47 | char input[] = "This is a test!\n"; 48 | char pattern[] = "es"; 49 | printf("The position of pattern \"%s\" in input \"%s\" is: %d\n", pattern, input, findPattern(pattern, input)); 50 | } 51 | -------------------------------------------------------------------------------- /hashTable/separate-chaining/Makefile: -------------------------------------------------------------------------------- 1 | C_COMPILER=gcc 2 | CFLAGS = -Wall -g 3 | 4 | # Directories 5 | ROOT = ../../ 6 | 7 | SRC_FILES=\ 8 | $(wildcard ./*.c) \ 9 | $(ROOT)utility/utility.c 10 | 11 | INC_DIRS=\ 12 | -I$(ROOT)utility/ 13 | 14 | LIBS=\ 15 | -lm 16 | 17 | OUTPUT_FILE=main 18 | 19 | .PHONY: clean 20 | .PHONY: test 21 | 22 | test: 23 | $(C_COMPILER) $(CFLAGS) $(INC_DIRS) $(LIBS) $(SRC_FILES) -o $(OUTPUT_FILE) 24 | ./$(OUTPUT_FILE) -v 25 | 26 | clean: 27 | rm -rf $(OUTPUT_FILE) 28 | -------------------------------------------------------------------------------- /hashTable/separate-chaining/sc.c: -------------------------------------------------------------------------------- 1 | #include "sc.h" 2 | 3 | struct ListNode 4 | { 5 | int Element; 6 | Position Next; 7 | }; 8 | 9 | struct HashTbl 10 | { 11 | int TableSize; 12 | List *TheLists; // an array of lists, allocated later 13 | }; 14 | 15 | HashTable 16 | initializeTable( 17 | int TableSize) 18 | { 19 | HashTable H; 20 | int i; 21 | 22 | H = malloc(sizeof(struct HashTbl)); 23 | assert(H); 24 | 25 | H->TableSize = TableSize; 26 | 27 | H->TheLists = malloc(H->TableSize * sizeof(List)); 28 | assert(H->TheLists); 29 | 30 | for(i = 0; i < TableSize; i++) 31 | { 32 | H->TheLists[i] = malloc(sizeof(struct ListNode)); 33 | assert(H->TheLists[i]); 34 | H->TheLists[i]->Next = NULL; 35 | } 36 | return H; 37 | } 38 | 39 | // We assume dummy node 40 | static void 41 | deleteList(Position L) 42 | { 43 | Position dummyL, tmp; 44 | dummyL = L->Next; 45 | L->Next = NULL; 46 | 47 | while(dummyL != NULL) 48 | { 49 | tmp = dummyL->Next; 50 | free(dummyL); 51 | dummyL = tmp; 52 | } 53 | } 54 | 55 | void 56 | destroyTable(HashTable H) 57 | { 58 | int i; 59 | 60 | for(i = 0; i < H->TableSize; i++) 61 | { 62 | deleteList(H->TheLists[i]); 63 | free(H->TheLists[i]); //free the dummy node 64 | } 65 | free(H); 66 | } 67 | 68 | static int 69 | hash(int key, int TableSize) 70 | { 71 | return key % TableSize; 72 | } 73 | 74 | Position 75 | find(int key, HashTable H) 76 | { 77 | List L; 78 | Position P; 79 | L = H->TheLists[hash(key, H->TableSize)]; 80 | P = L->Next; 81 | while(P != NULL && P->Element != key) 82 | { 83 | P = P->Next; 84 | } 85 | return P; 86 | } 87 | 88 | void 89 | insert(int key, HashTable H) 90 | { 91 | Position tmp; 92 | List L; 93 | L = H->TheLists[hash(key, H->TableSize)]; 94 | tmp = malloc(sizeof(struct ListNode)); 95 | tmp->Element = key; 96 | tmp->Next = L->Next; 97 | L->Next = tmp; 98 | } 99 | 100 | int 101 | retrieve(Position P) 102 | { 103 | return P->Element; 104 | } 105 | 106 | static void 107 | printList(List L) 108 | { 109 | Position tmp; 110 | tmp = L->Next; 111 | while(tmp != NULL) 112 | { 113 | printf("%d%s", tmp->Element, (tmp->Next) ? ("->") : ("")); 114 | tmp = tmp->Next; 115 | } 116 | printf("\n"); 117 | } 118 | 119 | void 120 | printHashTable(HashTable H) 121 | { 122 | int i; 123 | for(i = 0; i < H->TableSize; i++) 124 | { 125 | printf("%d|", i); 126 | printList(H->TheLists[i]); 127 | } 128 | } 129 | 130 | HashTable 131 | initializeTableFromArray(int* array, int arrayLength, int TableSize) 132 | { 133 | int i; 134 | HashTable H; 135 | H = initializeTable(TableSize); 136 | for(i = 0; i < arrayLength; i++) 137 | { 138 | insert(array[i], H); 139 | } 140 | return H; 141 | } 142 | -------------------------------------------------------------------------------- /hashTable/separate-chaining/sc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * MAW 5.3 Write a program to compute the number of collisions required in a long random 3 | * sequence of insertions using linear probing, quadratic probing, and double hashing 4 | */ 5 | 6 | //NOTE: 1. I don't really care to run the actual experimentation. The result is the quadratic 7 | // probing is the best one among three. More details see Gonnet and Baeza-Yates [8] 8 | // 2. Routines such as delete and makeEmpty are omitted 9 | // 3. Ideally, TableSize is picked to be the prime with the lambda = 1 10 | // for separate chaining hashing. This task is left to caller. 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | #ifndef _SC_H 17 | #define _SC_H 18 | 19 | struct ListNode; 20 | typedef struct ListNode *Position; 21 | typedef Position List; 22 | struct HashTbl; 23 | typedef struct HashTbl *HashTable; 24 | 25 | HashTable initializeTable(int TableSize); 26 | void destroyTable(HashTable H); 27 | Position find(int key, HashTable H); 28 | void insert(int key, HashTable H); 29 | int retrieve(Position P); 30 | void printHashTable(HashTable H); 31 | HashTable initializeTableFromArray(int* array, int arrayLength, int TableSize); 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /hashTable/separate-chaining/scTestMain.c: -------------------------------------------------------------------------------- 1 | #include "sc.h" 2 | 3 | void test_initalizeTableFromArray(); 4 | 5 | int 6 | main(void) 7 | { 8 | printf("///////////////////////\n"); 9 | printf("// SEPARATE CHAINING HASHING \n"); 10 | printf("///////////////////////\n"); 11 | test_initalizeTableFromArray(); printf("\n"); 12 | 13 | return 0; 14 | } 15 | 16 | void 17 | test_initalizeTableFromArray() 18 | { 19 | printf("TEST: initializeTableFromArray\n"); 20 | int array[7] = {4371, 1323, 6173, 4199, 4344, 9679, 1989}; 21 | HashTable H = initializeTableFromArray(array, 7, 10); 22 | printHashTable(H); 23 | destroyTable(H); 24 | } 25 | -------------------------------------------------------------------------------- /heaps/BinaryHeap/Makefile: -------------------------------------------------------------------------------- 1 | C_COMPILER=gcc 2 | CFLAGS = -Wall -g 3 | 4 | # Directories 5 | ROOT = ../../ 6 | 7 | SRC_FILES=\ 8 | $(wildcard ./*.c) \ 9 | $(ROOT)utility/utility.c \ 10 | $(ROOT)hashTable/dictionary/dict.c 11 | 12 | INC_DIRS=\ 13 | -I$(ROOT)utility/ \ 14 | -I$(ROOT)hashTable/dictionary 15 | 16 | LIBS=\ 17 | -lm 18 | 19 | OUTPUT_FILE=main 20 | 21 | .PHONY: clean 22 | .PHONY: test 23 | 24 | test: 25 | $(C_COMPILER) $(CFLAGS) $(INC_DIRS) $(LIBS) $(SRC_FILES) -o $(OUTPUT_FILE) 26 | ./$(OUTPUT_FILE) -v 27 | dot -T png -O bh.dot 28 | 29 | clean: 30 | rm -rf $(OUTPUT_FILE) 31 | -------------------------------------------------------------------------------- /heaps/BinaryHeap/bh.h: -------------------------------------------------------------------------------- 1 | /* 2 | * MAW 6.4 Write the routines to do a percolate up and a percolate down in a binary heap. 3 | * 4 | * MAW 6.5 Write and test a program that performs the operations Insert, DeleteMin, BuildHeap, 5 | * FindMin, DecreaseKey, Delete, and IncreaseKey in a binary heap. 6 | */ 7 | 8 | // NOTE: The binary heap will be represented in an array. For any element in array position i, 9 | // the left child is in position 2i, the right child is in the cell after the left child 10 | // (2i+1), and the parent is in position \lceil{i/2}\rceil 11 | // *Advantage*: 1. No pointers 2. tree traversal can be done extremely simple and fast 12 | // *Disadvantage*: 1. an estimate of maximum heap size is required in advance 13 | // 14 | // I didn't use hash table as a way to store each node position as suggested by MAW p.186. 15 | 16 | #include 17 | #include 18 | #include "utility.h" 19 | #include 20 | #include 21 | 22 | #ifndef _BH_H 23 | #define _BH_H 24 | 25 | struct HeapStruct; 26 | typedef struct HeapStruct *BinHeap; 27 | typedef unsigned int Position; 28 | 29 | BinHeap initializeBH(int MaxElements); 30 | void destroyBinHeap(BinHeap H); 31 | void makeEmptyBH(BinHeap H); 32 | void insertBH(int X, BinHeap H); 33 | int deleteMinBH(BinHeap H); 34 | int findMinBH(BinHeap H); 35 | int isEmpty(BinHeap H); 36 | int isFull(BinHeap H); 37 | BinHeap initializeBinHeapFromArray(int* array, int arrayLength); 38 | void bh_print_dot(BinHeap H, FILE* stream); 39 | 40 | BinHeap buildHeap(int* array, int arrayLength); 41 | void decreaseKey(Position P, int delta, BinHeap H); 42 | void increaseKey(Position P, int delta, BinHeap H); 43 | void delete(Position P, BinHeap H); 44 | 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /heaps/BinaryHeap/bhTestMain.c: -------------------------------------------------------------------------------- 1 | #include "bh.h" 2 | 3 | void generate_dot(BinHeap H); 4 | void test_initializeBinHeapFromArray(void); 5 | void test_buildHeap(void); 6 | void test_decreaseKey(void); 7 | void test_increaseKey(void); 8 | void test_delete(void); 9 | void delete_heap(BinHeap H); 10 | 11 | int 12 | main(void) 13 | { 14 | printf("///////////////////////\n"); 15 | printf("// BINARY HEAP TEST\n"); 16 | printf("///////////////////////\n\n"); 17 | 18 | test_initializeBinHeapFromArray(); printf("\n"); 19 | test_buildHeap(); printf("\n"); 20 | test_decreaseKey(); printf("\n"); 21 | test_increaseKey(); printf("\n"); 22 | test_delete(); printf("\n"); 23 | return 0; 24 | } 25 | 26 | void 27 | generate_dot(BinHeap H) 28 | { 29 | char* dotFilename = "bh.dot"; 30 | FILE *fp = fopen(dotFilename, "w"); 31 | bh_print_dot(H, fp); 32 | fclose(fp); 33 | printFile(dotFilename); 34 | } 35 | 36 | void 37 | delete_heap(BinHeap H) 38 | { 39 | destroyBinHeap(H); 40 | } 41 | 42 | void 43 | test_initializeBinHeapFromArray(void) 44 | { 45 | printf("TEST: intializeBinHeapFromArray\n"); 46 | int test_array[] = {10, 12, 1, 14, 6, 5, 8, 15, 47 | 3, 9, 7, 4, 11,13,2}; 48 | BinHeap H = initializeBinHeapFromArray(test_array, 15); 49 | generate_dot(H); 50 | delete_heap(H); 51 | } 52 | 53 | void 54 | test_buildHeap(void) 55 | { 56 | printf("TEST: buildHeap\n"); 57 | /* int test_array[] = {10, 12, 1, 14, 6, 5, 8, 15, */ 58 | /* 3, 9, 7, 4, 11,13,2}; */ 59 | int test_array[] = {150, 80, 40, 30, 10, 70, 110, 100, 60 | 20, 90, 60, 50, 120,140,130}; 61 | BinHeap H = buildHeap(test_array, 15); 62 | generate_dot(H); 63 | delete_heap(H); 64 | } 65 | 66 | void 67 | test_decreaseKey() 68 | { 69 | printf("TEST: decreaseKey\n"); 70 | int test_array[] = {150, 80, 40, 30, 10, 70, 110, 100, 71 | 20, 90, 60, 50, 120,140,130}; 72 | BinHeap H = buildHeap(test_array, 15); 73 | generate_dot(H); 74 | // decreaseKey(15, 129, H); 75 | decreaseKey(10, 40, H); 76 | generate_dot(H); 77 | delete_heap(H); 78 | } 79 | 80 | void 81 | test_increaseKey() 82 | { 83 | printf("TEST: increaseKey\n"); 84 | int test_array[] = {150, 80, 40, 30, 10, 70, 110, 100, 85 | 20, 90, 60, 50, 120,140,130}; 86 | BinHeap H = buildHeap(test_array, 15); 87 | generate_dot(H); 88 | increaseKey(1, 1000, H); 89 | generate_dot(H); 90 | delete_heap(H); 91 | } 92 | 93 | void 94 | test_delete() 95 | { 96 | printf("TEST: delete\n"); 97 | int test_array[] = {150, 80, 40, 30, 10, 70, 110, 100, 98 | 20, 90, 60, 50, 120,140,130}; 99 | BinHeap H = buildHeap(test_array, 15); 100 | generate_dot(H); 101 | delete(1, H); 102 | generate_dot(H); 103 | delete_heap(H); 104 | } 105 | -------------------------------------------------------------------------------- /heaps/min-max/Makefile: -------------------------------------------------------------------------------- 1 | C_COMPILER=gcc 2 | CFLAGS = -Wall -g 3 | 4 | # Directories 5 | ROOT = ../../ 6 | 7 | SRC_FILES=\ 8 | $(wildcard ./*.c) \ 9 | $(ROOT)utility/utility.c \ 10 | $(ROOT)hashTable/dictionary/dict.c 11 | 12 | INC_DIRS=\ 13 | -I$(ROOT)utility/ \ 14 | -I$(ROOT)hashTable/dictionary 15 | 16 | LIBS=\ 17 | -lm 18 | 19 | OUTPUT_FILE=main 20 | 21 | .PHONY: clean 22 | .PHONY: test 23 | 24 | test: 25 | $(C_COMPILER) $(CFLAGS) $(INC_DIRS) $(LIBS) $(SRC_FILES) -o $(OUTPUT_FILE) 26 | ./$(OUTPUT_FILE) -v 27 | dot -T png -O mm.dot 28 | 29 | clean: 30 | rm -rf $(OUTPUT_FILE) 31 | -------------------------------------------------------------------------------- /heaps/min-max/mm.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "utility.h" 4 | #include 5 | #include 6 | 7 | /* 8 | * MAW 6.15 A min-max heap is a data structure that supports both 9 | * DeleteMin and DeleteMax in O(logN) per operation. The structure 10 | * is identical to a binary heap, but the heap order property is that 11 | * for any node, X, at even depth, the key stored at X is smaller than 12 | * the parent but larger than the grandparent, and for any node X at odd 13 | * depth, the key stored at X is larger than the parent but smaller 14 | * than the grandparent. 15 | */ 16 | 17 | 18 | #ifndef _MM_H 19 | #define _MM_H 20 | 21 | struct MinMaxHeapStruct; 22 | typedef struct MinMaxHeapStruct* MinMaxHeap; 23 | typedef unsigned int Position; 24 | 25 | MinMaxHeap initializeMMH(int maxElements); 26 | void destroyMinMaxHeap(MinMaxHeap H); 27 | void makeEmptyMMH(MinMaxHeap H); 28 | void insertMHH(int X, MinMaxHeap H); 29 | int deleteMinMHH(MinMaxHeap H); 30 | int deleteMaxMHH(MinMaxHeap H); 31 | int findMinMMH(MinMaxHeap H); 32 | int findMaxMMH(MinMaxHeap H); 33 | int isEmpty(MinMaxHeap H); 34 | int isFull(MinMaxHeap H); 35 | MinMaxHeap buildMMH(int* array, int arrayLength); 36 | MinMaxHeap initializeMinMaxHeapFromArray(int* array, int arrayLength); 37 | void mmh_print_dot(MinMaxHeap H, FILE* stream); 38 | 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /heaps/min-max/mmTestMain.c: -------------------------------------------------------------------------------- 1 | #include "mm.h" 2 | 3 | void generate_dot(MinMaxHeap H); 4 | void test_initializeMinMaxHeapFromArray(void); 5 | void test_deleteMinMHH(void); 6 | void test_deleteMaxMHH(void); 7 | void test_buildMMH(void); 8 | 9 | int 10 | main(void) 11 | { 12 | printf("///////////////////////\n"); 13 | printf("// MIN MAX HEAP TEST\n"); 14 | printf("///////////////////////\n\n"); 15 | 16 | test_initializeMinMaxHeapFromArray(); printf("\n"); 17 | test_deleteMinMHH(); printf("\n"); 18 | test_deleteMaxMHH(); printf("\n"); 19 | test_buildMMH(); printf("\n"); 20 | 21 | return 0; 22 | } 23 | 24 | void 25 | generate_dot(MinMaxHeap H) 26 | { 27 | char* dotFilename = "mm.dot"; 28 | FILE *fp = fopen(dotFilename, "w"); 29 | mmh_print_dot(H, fp); 30 | fclose(fp); 31 | printFile(dotFilename); 32 | } 33 | 34 | void 35 | delete_heap(MinMaxHeap H) 36 | { 37 | destroyMinMaxHeap(H); 38 | } 39 | 40 | void 41 | test_initializeMinMaxHeapFromArray(void) 42 | { 43 | printf("TEST: intializeMinMaxHeapFromArray\n"); 44 | int test_array[] = {81,6,87,14,17,12,28,71,25, 45 | 80,20,52,78,31,42,31,59,16, 46 | 24,79,63,18,19,32,13,15,48}; 47 | MinMaxHeap H = initializeMinMaxHeapFromArray(test_array, 27); 48 | generate_dot(H); 49 | delete_heap(H); 50 | } 51 | 52 | void 53 | test_deleteMinMHH(void) 54 | { 55 | printf("TEST: deleteMinMHH\n"); 56 | int test_array[] = {81,6,87,14,17,12,28,71,25, 57 | 80,20,52,78,31,42,31,59,16, 58 | 24,79,63,18,19,32,13,15,48}; 59 | MinMaxHeap H = initializeMinMaxHeapFromArray(test_array, 27); 60 | deleteMinMHH(H); 61 | generate_dot(H); 62 | delete_heap(H); 63 | } 64 | 65 | void 66 | test_deleteMaxMHH(void) 67 | { 68 | printf("TEST: deleteMaxMHH\n"); 69 | int test_array[] = {81,6,87,14,17,12,28,71,25, 70 | 80,20,52,78,31,42,31,59,16, 71 | 24,79,63,18,19,32,13,15,48}; 72 | MinMaxHeap H = initializeMinMaxHeapFromArray(test_array, 27); 73 | deleteMaxMHH(H); 74 | generate_dot(H); 75 | delete_heap(H); 76 | } 77 | 78 | void 79 | test_buildMMH() 80 | { 81 | printf("TEST: buildMMH\n"); 82 | int test_array[] = {48,15,78,20,32,11,80}; 83 | MinMaxHeap H = buildMMH(test_array, 7); 84 | generate_dot(H); 85 | delete_heap(H); 86 | } 87 | -------------------------------------------------------------------------------- /linkedList/generic/Makefile: -------------------------------------------------------------------------------- 1 | C_COMPILER=gcc 2 | CFLAGS = -Wall -g 3 | 4 | # Directories 5 | ROOT = ../../ 6 | 7 | SRC_FILES=\ 8 | $(wildcard ./*.c) \ 9 | $(ROOT)utility/utility.c 10 | 11 | INC_DIRS=\ 12 | -I$(ROOT)utility/ 13 | 14 | LIBS=\ 15 | -lm 16 | 17 | OUTPUT_FILE=main 18 | 19 | .PHONY: clean 20 | .PHONY: test 21 | 22 | test: 23 | $(C_COMPILER) $(CFLAGS) $(INC_DIRS) $(LIBS) $(SRC_FILES) -o $(OUTPUT_FILE) 24 | ./$(OUTPUT_FILE) -v 25 | 26 | clean: 27 | rm -rf $(OUTPUT_FILE) 28 | -------------------------------------------------------------------------------- /linkedList/generic/linkedList.h: -------------------------------------------------------------------------------- 1 | /* ET shorts for "ElementType" 2 | */ 3 | typedef int ET; 4 | 5 | //////////////////////////// 6 | // BASIC LIST DEFINITION 7 | //////////////////////////// 8 | 9 | /* we always assume there is a dummy node at the very beginning 10 | * of the list. 11 | */ 12 | #ifndef _LINKED_LIST_H 13 | #define _LINKED_LIST_H 14 | 15 | struct Node; 16 | typedef struct Node *PtrToNode; 17 | typedef PtrToNode List; 18 | typedef PtrToNode Pos; 19 | 20 | #endif 21 | 22 | ////////////////////////// 23 | // BASIC LIST OPERATION 24 | ////////////////////////// 25 | 26 | /* Insert (after legal position P) 27 | */ 28 | void insert(ET elem, List L, Pos position); 29 | 30 | /* Make empty linked list 31 | */ 32 | List makeEmpty(); 33 | 34 | /* We don't delete the header node. 35 | * In other words, the empty list contains a header node. 36 | */ 37 | void deleteList(List L); 38 | 39 | /* delete all: the list and the header node 40 | */ 41 | void deleteAll(List L); 42 | 43 | /* Give the element of the specified node 44 | */ 45 | ET getElement(Pos loc); 46 | 47 | /* Find the node contains "elem" in the given list and delete it. 48 | */ 49 | void deleteNode(ET elem, List L); 50 | 51 | /* 3.15.b self-adjusting lists insert. All the insertions 52 | * are performed at the front of the list. 53 | */ 54 | void selfAdjustInsert(ET elem, List L); 55 | 56 | /* 3.15.b self-adjusting lists find. When an element is accessed by a Find, 57 | * it is moved to the front of the list without changing the relative order of the 58 | * other items. Return the pointer to the element. 59 | */ 60 | Pos selfAdjustFind(ET elem, List L); 61 | 62 | /////////////////////////// 63 | // VARIOUS LIST PROBLEMS 64 | /////////////////////////// 65 | 66 | /* initialize a singly linked list from a given array 67 | */ 68 | List initializeList(ET A[], int arrayLen); 69 | 70 | /* 3.1 print out the elements of a singly linked list 71 | */ 72 | void printList(List L); 73 | 74 | /* print out the elements of a singly linked list 75 | * in reverse order 76 | */ 77 | void printListReverse(List L); 78 | 79 | /* 3.2 You are given a linked list, L, and another linked list, P, 80 | * containing integers sorted in acending order. The operation 81 | * printLots(L,P) will print the elements in L that are in positions 82 | * specified by P. For instance, if P = 1, 3, 4, 6, the first, third, 83 | * fourth, and sixth elements in L are printed. 84 | */ 85 | void printLots(List L, List P); 86 | 87 | /* 3.3.a Swap the node that contains the first appearance of the ET elem 88 | * with the following node. If node contains first appearance of the ET elem 89 | * is the last node, then print "Cannot swap because of the elem is the last node" 90 | */ 91 | void swapLL(List L, ET elem); 92 | 93 | /* 3.4 Given two sorted lists, L and P, write a procedure to compute the 94 | * intersection of two lists using only the basic list operations. 95 | */ 96 | List intersectionSortedLists(List L, List P); 97 | 98 | /* 3.5 Given two sorted lists, L and P, write a procedure to compute L1 union L2 99 | * using only the basic list operations. 100 | */ 101 | List unionSortedLists(List L, List P); 102 | 103 | /* 3.11 write a program to find a particular element in a singly linked list. "find" is nonrecursive. 104 | * "findRecursive" is recursive. 105 | */ 106 | Pos find(ET target, List L); 107 | Pos findRecursive(ET target, List L); 108 | 109 | /* 3.12.a write a nonrecursive procedure to reverse a singly linked list in O(N) time. 110 | */ 111 | List reverseList(List L); 112 | 113 | /* 3.12.b write a nonrecursive procedure to reverse a singly linked list in O(N) time 114 | * using constant extra space. 115 | */ 116 | void reverseListIterative(List L); 117 | void reverseListRecursive(List L); 118 | 119 | /* 3.13 You have to sort an array of student records by social security number. Write a program 120 | * to do this, using radix sort with 1000 buckets and three passes. 121 | */ 122 | int* radixSort(int studentRecords[], int N); 123 | -------------------------------------------------------------------------------- /linkedList/integerList/Makefile: -------------------------------------------------------------------------------- 1 | C_COMPILER=gcc 2 | CFLAGS = -Wall -g 3 | 4 | SRC_FILES=\ 5 | $(wildcard ./*.c) 6 | OUTPUT_FILE=main 7 | 8 | .PHONY: clean 9 | .PHONY: test 10 | 11 | test: 12 | $(C_COMPILER) $(CFLAGS) $(SRC_FILES) -o $(OUTPUT_FILE) 13 | ./$(OUTPUT_FILE) -v 14 | 15 | clean: 16 | rm -rf $(OUTPUT_FILE) 17 | -------------------------------------------------------------------------------- /linkedList/integerList/integerList.h: -------------------------------------------------------------------------------- 1 | /* maw 3.9 Write an arbitrary-precision integer arithmetic 2 | * package. 3 | */ 4 | 5 | #include 6 | #include 7 | 8 | /* We use a header node in our implementation. 9 | * The digits in integer, implemented in linked list, 10 | * is in reverse order. The least significant digit is 11 | * the first data node. The most significant digit is the 12 | * last data node. 13 | */ 14 | #ifndef _INTEGER_LIST_H 15 | #define _INTEGER_LIST_H 16 | 17 | typedef struct Node* PtrToNode; 18 | typedef PtrToNode integerList; 19 | 20 | struct Node 21 | { 22 | int Digit; 23 | PtrToNode NextDigit; 24 | }; 25 | 26 | #endif 27 | 28 | /* Initialize an integer. The input is 29 | * an array of digits in normal order 30 | */ 31 | integerList initializeInteger(int digits[], int numDigits); 32 | 33 | /* Make empty integer list 34 | */ 35 | integerList makeEmpty(); 36 | 37 | /* Delete the whole integerList and 38 | * we keep the header node. 39 | */ 40 | void deleteIntegerList(integerList L); 41 | 42 | /* Delete the whole integerList plus the header node 43 | */ 44 | void deleteAll(integerList L); 45 | 46 | /* Add the digit immediately after the PtrToNode 47 | */ 48 | void addDigit(int digit, PtrToNode P); 49 | 50 | /* Print the integer 51 | */ 52 | void printIntegerList(integerList L); 53 | 54 | /* Add two non-negative integers 55 | */ 56 | integerList add(integerList A, integerList B); 57 | 58 | /* Mutiply two non-negative integers 59 | */ 60 | integerList multiply(integerList A, integerList B); 61 | 62 | /* Power 63 | */ 64 | integerList powIntegerList(integerList A, int power); 65 | 66 | /* Compute the distribution of the digits 0 to 9 in 2^4000. 67 | */ 68 | void count(integerList A); 69 | -------------------------------------------------------------------------------- /linkedList/integerList/integerListTestMain.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "integerList.h" 4 | 5 | void test_intializeInteger(); 6 | void test_add(); 7 | void test_multiply(); 8 | void test_powIntegerList(); 9 | void test_count(); 10 | 11 | int main() 12 | { 13 | printf("///////////////////////\n"); 14 | printf("// INTEGERLIST TEST\n"); 15 | printf("///////////////////////\n\n"); 16 | 17 | test_intializeInteger(); 18 | test_add(); 19 | test_multiply(); 20 | test_powIntegerList(); 21 | test_count(); 22 | 23 | return 0; 24 | } 25 | 26 | void 27 | test_intializeInteger() 28 | { 29 | printf("TEST: initializeInteger\n"); 30 | int digits0[] = {3,4,2}; 31 | integerList int0 = initializeInteger(digits0, 3); 32 | printIntegerList(int0); 33 | deleteAll(int0); 34 | printf("\n"); 35 | } 36 | 37 | void 38 | test_add() 39 | { 40 | printf("TEST: add\n"); 41 | int digits0[] = {3,4,2}; 42 | int digits1[] = {4,6,5}; 43 | int digits2[] = {9,7}; 44 | int digits3[] = {7,0,6}; 45 | int digits4[] = {1,1,7,7,7}; 46 | integerList int0 = initializeInteger(digits0, 3); 47 | integerList int1 = initializeInteger(digits1, 3); 48 | integerList int2 = initializeInteger(digits2, 2); 49 | integerList int3 = initializeInteger(digits3, 3); 50 | integerList int4 = initializeInteger(digits4, 5); 51 | integerList test1 = add(int0, int1); 52 | integerList test2 = add(int0, int2); 53 | integerList test3 = add(int0, int3); 54 | integerList test4 = add(int0, int4); 55 | printIntegerList(test1); 56 | printf("\n"); 57 | printIntegerList(test2); 58 | printf("\n"); 59 | printIntegerList(test3); 60 | printf("\n"); 61 | printIntegerList(test4); 62 | printf("\n"); 63 | deleteAll(int0); 64 | deleteAll(int1); 65 | deleteAll(int2); 66 | deleteAll(int3); 67 | deleteAll(int4); 68 | deleteAll(test1); 69 | deleteAll(test2); 70 | deleteAll(test3); 71 | deleteAll(test4); 72 | } 73 | 74 | void 75 | test_multiply() 76 | { 77 | printf("TEST: multiply\n"); 78 | int digits0[] = {3,4,2}; 79 | int digits1[] = {4,6,5}; 80 | integerList int0 = initializeInteger(digits0, 3); 81 | printIntegerList(int0); 82 | printf("\n"); 83 | integerList int1 = initializeInteger(digits1, 3); 84 | printIntegerList(int1); 85 | printf("\n"); 86 | integerList test1 = multiply(int0, int1); 87 | printIntegerList(test1); 88 | printf("\n"); 89 | deleteAll(int0); 90 | deleteAll(int1); 91 | deleteAll(test1); 92 | } 93 | 94 | void 95 | test_powIntegerList() 96 | { 97 | printf("TEST: power\n"); 98 | int digits5[] = {2}; 99 | integerList int5 = initializeInteger(digits5, 1); 100 | integerList test0 = powIntegerList(int5, 2); 101 | printIntegerList(test0); 102 | printf("\n"); 103 | deleteAll(int5); 104 | deleteAll(test0); 105 | } 106 | 107 | void 108 | test_count() 109 | { 110 | printf("TEST: distribution of digits 0 to 9 in 2^4000\n"); 111 | int digits0[] = {2}; 112 | integerList int0 = initializeInteger(digits0, 1); 113 | integerList test0 = powIntegerList(int0, 4000); 114 | printIntegerList(test0); 115 | printf("\n"); 116 | count(test0); 117 | } 118 | -------------------------------------------------------------------------------- /linkedList/josephus/Makefile: -------------------------------------------------------------------------------- 1 | C_COMPILER=gcc 2 | CFLAGS = -Wall -g 3 | 4 | SRC_FILES=\ 5 | $(wildcard ./*.c) 6 | OUTPUT_FILE=main 7 | 8 | .PHONY: clean 9 | .PHONY: test 10 | 11 | test: 12 | $(C_COMPILER) $(CFLAGS) $(SRC_FILES) -o $(OUTPUT_FILE) 13 | ./$(OUTPUT_FILE) -v 14 | 15 | clean: 16 | rm -rf $(OUTPUT_FILE) 17 | -------------------------------------------------------------------------------- /linkedList/josephus/circularLinkedList.c: -------------------------------------------------------------------------------- 1 | #include "circularLinkedList.h" 2 | #include 3 | #include 4 | 5 | struct Node 6 | { 7 | ET Element; 8 | Pos Prev; 9 | Pos Next; 10 | }; 11 | 12 | /**---- BASIC LIST OPERATION ----**/ 13 | 14 | List 15 | makeEmpty() 16 | { 17 | List L = malloc(sizeof(struct Node)); 18 | L->Next = NULL; 19 | L->Prev = NULL; 20 | return L; 21 | } 22 | 23 | void 24 | insert(ET elem, List L, Pos position) 25 | { 26 | Pos tmpNode; 27 | tmpNode = malloc(sizeof(struct Node)); 28 | tmpNode->Element = elem; 29 | tmpNode->Next = position->Next; 30 | if (position->Next != NULL) 31 | { 32 | position->Next->Prev = tmpNode; 33 | } 34 | tmpNode->Prev = position; 35 | position->Next = tmpNode; 36 | } 37 | 38 | void 39 | deleteNode(Pos position) 40 | { 41 | Pos tmp = position; 42 | tmp->Prev->Next = tmp->Next; 43 | tmp->Next->Prev = tmp->Prev; 44 | free(tmp); 45 | } 46 | 47 | 48 | /**---- VARIOUS LIST PROBLEMS ----**/ 49 | 50 | List 51 | initializeList(ET A[], int arrayLen) 52 | { 53 | List L = makeEmpty(); 54 | Pos dummyL = L; 55 | int i; 56 | 57 | for(i = 0; i < arrayLen; i++) 58 | { 59 | insert(A[i], L, dummyL); 60 | dummyL = dummyL->Next; 61 | } 62 | dummyL->Next = L; 63 | L->Prev = dummyL; 64 | return L; 65 | } 66 | 67 | void 68 | printList(List L) 69 | { 70 | Pos dummyL; 71 | dummyL = L->Next; 72 | 73 | while(dummyL != NULL && dummyL != L) 74 | { 75 | printf("%s %d <->", (dummyL->Prev == L) ? ("<->") : (""), dummyL->Element); 76 | dummyL = dummyL->Next; 77 | } 78 | } 79 | 80 | /* Runtime analysis: O(MN) 81 | */ 82 | ET 83 | circularDoubleLinkedListJosephus(ET N, ET M) 84 | { 85 | /* int i; */ 86 | /* ET people[N] = {0}; */ 87 | /* for (i = 0; i < N; i++) */ 88 | /* { */ 89 | /* people[i] = i + 1; */ 90 | /* } */ 91 | 92 | int counter = N; // count how many elements left 93 | int j = 1; // count how many element we have traversed for each round 94 | 95 | // initialize the arr 96 | int i; 97 | int* people; 98 | 99 | people = calloc(N, sizeof(int)); 100 | //people = malloc(N*sizeof(int)); // can use either 'malloc' or 'calloc' in this case 101 | 102 | for ( i = 0; i < N; i++) 103 | { 104 | *(people + i) = i + 1; 105 | } 106 | 107 | // construct the list 108 | List L = initializeList(people, N); 109 | Pos dummyL = L->Next; 110 | 111 | // start to work on the problem 112 | ET M_prime = M % N; 113 | 114 | while (counter > 1) 115 | { 116 | while (j < M_prime) 117 | { 118 | dummyL = dummyL->Next; 119 | // handle the case when a data node is followed by a header. 120 | // in that case, we don't want to remove the header node and we 121 | // want to move on to the actual data node. 122 | if (dummyL != L) 123 | { 124 | j++; 125 | } 126 | } 127 | Pos tmp = dummyL->Next; 128 | deleteNode(dummyL); 129 | dummyL = tmp; 130 | 131 | counter--; 132 | j = 1; 133 | // we should start to count M when we on a data node, not a header node. 134 | if (dummyL == L) 135 | { 136 | dummyL = dummyL->Next; 137 | } 138 | } 139 | 140 | return dummyL->Element; 141 | } 142 | -------------------------------------------------------------------------------- /linkedList/josephus/circularLinkedList.h: -------------------------------------------------------------------------------- 1 | /* We use double circularly linked list to solve Josephus problem 2 | */ 3 | 4 | typedef int ET; // ET shorts for "ElementType" 5 | 6 | /** BASIC LIST DEFINITION **/ 7 | 8 | // we always assume there is a dummy node at the very beginning 9 | // of the list. In the double circluarly linked list, the dummy node's 10 | // previous pointer points to the last data node. The last data node's 11 | // next pointer points to the dummy node. 12 | #ifndef _CIRCULAR_LINKED_LIST_H 13 | #define _CIRCULAR_LINKED_LIST_H 14 | 15 | struct Node; 16 | typedef struct Node *PtrToNode; 17 | typedef PtrToNode List; 18 | typedef PtrToNode Pos; 19 | 20 | #endif 21 | 22 | /**---- BASIC LIST OPERATION ----**/ 23 | 24 | /* Make an empty list 25 | */ 26 | List makeEmpty(); 27 | 28 | /* Insert (after legal position P) 29 | */ 30 | void insert(ET elem, List L, Pos position); 31 | 32 | /* Delete node 33 | */ 34 | void deleteNode(Pos position); 35 | 36 | /**---- VARIOUS LIST PROBLEMS ----**/ 37 | 38 | /* initialize a double circulaly linked list from a given array 39 | */ 40 | List initializeList(ET A[], int arrayLen); 41 | 42 | /* print out the elements of a double circularly linked list. 43 | * The structure looks like: <-> ET <-> ET <-> ET <-> 44 | */ 45 | void printList(List L); 46 | 47 | /* 3.10 Write a program to solve the Josephus problem for general 48 | * values of M and N. 49 | */ 50 | ET circularDoubleLinkedListJosephus(ET N, ET M); 51 | -------------------------------------------------------------------------------- /linkedList/josephus/nonLinkedListSol.c: -------------------------------------------------------------------------------- 1 | #include "assert.h" 2 | #include "nonLinkedListSol.h" 3 | #include "strings.h" 4 | #include 5 | 6 | #ifndef fls 7 | /* 8 | * Find Last Set bit. This is exactly opposite of "ffs". 9 | * The reason I include this routine here is that not every system 10 | * has "fls" by default. 11 | */ 12 | int 13 | fls(int mask) 14 | { 15 | int bit; 16 | if (mask == 0) 17 | { 18 | return (0); 19 | } 20 | for (bit = 1; mask != 1; bit++) 21 | { 22 | mask = (unsigned int) mask >> 1; 23 | } 24 | return (bit); 25 | } 26 | #endif 27 | 28 | int 29 | cyclicShiftJosephus(int N, int M) 30 | { 31 | assert(M == 2); 32 | return 2 * (N - (1 << ((fls(N)) - 1))) + 1; 33 | } 34 | 35 | int 36 | recurrenceJosephus(int N, int M) 37 | { 38 | if (N == 1) 39 | { 40 | return 1; 41 | } 42 | return (M - 1 + recurrenceJosephus(N-1, M)) % N + 1; 43 | } 44 | 45 | static int 46 | recurrenceJosephusZeroHelper(int N, int M) 47 | { 48 | if (N == 1) 49 | { 50 | return 0; 51 | } 52 | return (M + recurrenceJosephusZeroHelper(N-1, M)) % N; 53 | } 54 | 55 | int 56 | recurrenceJosephusZero(int N, int M) 57 | { 58 | return recurrenceJosephusZeroHelper(N, M) + 1; 59 | } 60 | 61 | static xint2 62 | recurrenceImprovedHelper(xint2 N, xint2 M) 63 | { 64 | if (N == 1LL) 65 | { 66 | return 0LL; 67 | } 68 | if (M == 1LL) 69 | { 70 | return N-1LL; 71 | } 72 | if (M > N) 73 | { 74 | return (M + recurrenceImprovedHelper(N-1LL, M)) % N; 75 | } 76 | xint2 cnt = N / M; 77 | xint2 res = recurrenceImprovedHelper(N - cnt, M); 78 | res -= N % M; 79 | if (res < 0LL) 80 | { 81 | res += N; 82 | } 83 | else 84 | { 85 | res += res/(M - 1LL); 86 | } 87 | return res; 88 | } 89 | 90 | xint2 91 | recurrenceImproved(xint2 N, xint2 M) 92 | { 93 | return recurrenceImprovedHelper(N, M) + 1; 94 | } 95 | 96 | xint josephus(xint people, xint skip ) 97 | { 98 | if( people <= 1 ) return 1; 99 | //people = 0 is actually invalid, and people = 1 is trivial 100 | 101 | //Imagine an array that can contain two values, "not josephus" and "josephus" 102 | //rather than actually have the array, we will only save the index 103 | //that contains josephus and the size of the array 104 | //We are going to kill the first person in line, and then "rotate" the array 105 | //to set our sights on the next guy 106 | //only we are doing it backwards, starting with 2 people, 107 | //Josephus is smartly not the first in line. 108 | 109 | //josephus' position, 0 based position 110 | xint result = 1; 111 | 112 | //number of people remaining, including josephus 113 | xint n=2; 114 | 115 | if( skip <= 1 ) 116 | { 117 | //simple case, separated out to avoid a divide by zero 118 | result = people-1; 119 | } 120 | else while (n people ) 129 | { 130 | iterations = people - n; 131 | } 132 | //skip people and set sights on the next victim 133 | //by "rotating" the "array" 134 | result += skip*iterations; 135 | n+=iterations; 136 | //don't let josephus past the end of the line 137 | while( result >= n ) 138 | { 139 | result-=(n-1) ; 140 | } 141 | } 142 | //person 0 (the next to be killed) is really in position "skip" 143 | return ( ( result + skip - 1 ) % people ) + 1; 144 | } 145 | -------------------------------------------------------------------------------- /linkedList/josephus/nonLinkedListSol.h: -------------------------------------------------------------------------------- 1 | /* Contains the non linked List solutions to Josephus problem 2 | */ 3 | typedef unsigned long long xint; 4 | typedef long long xint2; 5 | 6 | /* We use the cyclic shift property 7 | * WARNING: only applies to M = 2 8 | */ 9 | int cyclicShiftJosephus(int N, int M); 10 | 11 | /* We use the general recurrence equation 12 | * WARNING: This routine applies to arbitrary M; we use one-index. 13 | */ 14 | int recurrenceJosephus(int N, int M); 15 | 16 | /* We use the general recurrence equation 17 | * WARNING: This routine applies to arbitrary M; we use zero-index. 18 | */ 19 | int recurrenceJosephusZero(int N, int M); 20 | 21 | /* We use an improved recurrence solution to handle large N and large M 22 | * find here: http://stackoverflow.com/questions/4845260/josephus-for-large-n-facebook-hacker-cup 23 | * TODO: this algorithm cannot use xint, will return incorrect result. 24 | * cannot calculate J(10^12, 10^4) 25 | */ 26 | xint2 recurrenceImproved(xint2 N, xint2 M); 27 | 28 | /* TODO: Found here: https://www.reddit.com/r/dailyprogrammer/comments/12qicm/1162012_challenge_111_difficult_the_josephus/ 29 | * not sure how the algorithm works. Need to revisit. In addition, there is similar but more succint algorithm through the link 30 | * You may also want to check out: https://rosettacode.org/wiki/Josephus_problem#C 31 | */ 32 | xint josephus(xint people, xint skip); 33 | -------------------------------------------------------------------------------- /linkedList/lazy-deletion/Makefile: -------------------------------------------------------------------------------- 1 | C_COMPILER=gcc 2 | CFLAGS = -Wall -g 3 | 4 | # Directories 5 | ROOT = ../../ 6 | 7 | SRC_FILES=\ 8 | $(wildcard ./*.c) \ 9 | $(ROOT)utility/utility.c 10 | 11 | INC_DIRS=\ 12 | -I$(ROOT)utility/ 13 | 14 | LIBS=\ 15 | -lm 16 | 17 | OUTPUT_FILE=main 18 | 19 | .PHONY: clean 20 | .PHONY: test 21 | 22 | test: 23 | $(C_COMPILER) $(CFLAGS) $(INC_DIRS) $(LIBS) $(SRC_FILES) -o $(OUTPUT_FILE) 24 | ./$(OUTPUT_FILE) -v 25 | 26 | clean: 27 | rm -rf $(OUTPUT_FILE) 28 | -------------------------------------------------------------------------------- /linkedList/lazy-deletion/lazyDeleteLinkedList.h: -------------------------------------------------------------------------------- 1 | /* ET shorts for "ElementType" 2 | */ 3 | typedef int ET; 4 | 5 | /* 3.17 An alternative to the deletion strategy 6 | * we have given is to use lazy deletion. To delete 7 | * an element, we merely mark it deleted (using an extra bit field). 8 | * The number of deleted and nondeleted elements in the list 9 | * is kept as part of the data structure. If there are as many 10 | * deleted element as nondeleted elements, we traverse the entire list, 11 | * performing the standard deletion algorithm on all marked nodes. 12 | * 13 | * ADVANTAGE : It takes less time to mark a node as deleted than to change pointers. In addition, it is simpler to code, 14 | * and there is a possible savings if deleted keys are subsequently reinserted (in the same place). 15 | * DISADVANTAGE : Once a node has been "lazily deleted" it still needs to be traversed in a search for another node. 16 | * Also, you then use up a lump amount of time to delete all the "lazily deleted elements". Use more space, 17 | * because each cell needs an extra bit (which is typically a byte), and unused cells are not freed. 18 | */ 19 | 20 | //////////////////////////// 21 | // BASIC LIST DEFINITION 22 | //////////////////////////// 23 | 24 | /* we always assume there is a dummy node at the very beginning 25 | * of the list. 26 | */ 27 | #ifndef _LAZY_DELETE_LINKED_LIST_H 28 | #define _LAZY_DELETE_LINKED_LIST_H 29 | 30 | struct Node; 31 | typedef struct Node *PtrToNode; 32 | typedef PtrToNode List; 33 | typedef PtrToNode Pos; 34 | 35 | #endif 36 | 37 | ////////////////////////// 38 | // BASIC LIST OPERATION 39 | ////////////////////////// 40 | 41 | /* Make empty linked list 42 | */ 43 | List makeEmpty(); 44 | 45 | int IsEmpty(List L); 46 | 47 | int IsLast(Pos P, List L); 48 | 49 | Pos Find(ET elem, List L); 50 | 51 | /* Find the node contains "elem" in the given list and delete it. 52 | */ 53 | void deleteNode(ET elem, List L); 54 | 55 | Pos FindPrevious(ET elem, List L); 56 | 57 | /* Insert (after legal position P) 58 | */ 59 | void insert(ET elem, List L, Pos position); 60 | 61 | /* Delete all the nodes with deleted == true 62 | */ 63 | void deleteMarkedNodes(List L); 64 | 65 | /* We don't delete the header node. 66 | * In other words, the empty list contains a header node. 67 | */ 68 | void deleteList(List L); 69 | 70 | /* delete all: the list and the header node 71 | */ 72 | void deleteAll(List L); 73 | 74 | Pos Header(List L); 75 | 76 | Pos First(List L); 77 | 78 | Pos Advance(Pos P); 79 | 80 | /* Give the element of the specified node 81 | */ 82 | ET getElement(Pos loc); 83 | 84 | /* Get the number of nodes 85 | */ 86 | int getNumNodes(); 87 | 88 | /* Set the number of nodes 89 | */ 90 | void setNumNodes(int N); 91 | 92 | /* Get the number of nodes marked as deleted 93 | */ 94 | int getNumDeleted(); 95 | 96 | /* Set the number of nodes marked as deleted 97 | */ 98 | void setNumDeleted(int N); 99 | 100 | /* print out the elements of a singly linked list 101 | */ 102 | void printList(List L); 103 | 104 | /* initialize a singly linked list from a given array 105 | */ 106 | List initializeList(ET A[], int arrayLen); 107 | -------------------------------------------------------------------------------- /linkedList/lazy-deletion/lazyDeleteLinkedListTestMain.c: -------------------------------------------------------------------------------- 1 | #include "lazyDeleteLinkedList.h" 2 | #include 3 | #include 4 | #include 5 | #include "utility.h" 6 | 7 | void test_printList(); 8 | void test_find(); 9 | void test_deleteNode(); 10 | void test_deleteMarkedNodes(); 11 | void test_list_independence(); 12 | 13 | int main() 14 | { 15 | printf("///////////////////////\n"); 16 | printf("// LAZY DELETION LINKED LIST TEST\n"); 17 | printf("///////////////////////\n\n"); 18 | 19 | test_printList(); printf("\n"); 20 | 21 | test_find(); printf("\n"); 22 | 23 | test_deleteNode(); printf("\n"); 24 | 25 | test_deleteMarkedNodes(); printf("\n"); 26 | 27 | test_list_independence(); printf("\n"); 28 | return 0; 29 | } 30 | 31 | void 32 | test_printList() 33 | { 34 | printf("TEST: printList\n"); 35 | ET test_L[] = {23, 44, 45, 57, 89, -1}; 36 | List L = initializeList(test_L, 6); 37 | printList(L); 38 | deleteAll(L); 39 | } 40 | 41 | void 42 | test_find() 43 | { 44 | printf("TEST: find\n"); 45 | Pos loc; 46 | ET test_Q1[] = {1,2,3}; 47 | List Q1 = initializeList(test_Q1, 3); 48 | loc = Find(3, Q1); 49 | assert(getElement(loc) == 3); 50 | printf("Pass all\n"); 51 | deleteAll(Q1); 52 | } 53 | 54 | void 55 | test_deleteNode() 56 | { 57 | printf("TEST: deleteNode\n"); 58 | ET test_Q1[] = {1,2,3}; 59 | List Q1 = initializeList(test_Q1, 3); 60 | printf("Original list: "); 61 | printList(Q1); 62 | deleteNode(2, Q1); 63 | printf("After deletion: "); 64 | printList(Q1); 65 | deleteAll(Q1); 66 | 67 | ET test_Q2[] = {1,2,3,4}; 68 | List Q2 = initializeList(test_Q2, 4); 69 | printf("Original list: "); 70 | printList(Q2); 71 | deleteNode(1, Q1); 72 | deleteNode(2, Q1); 73 | printf("After deletion: "); 74 | printList(Q2); 75 | deleteAll(Q2); 76 | } 77 | 78 | void 79 | test_deleteMarkedNodes() 80 | { 81 | printf("TEST: deleteMarkedNodes\n"); 82 | ET test_Q1[] = {1,2,3}; 83 | List Q1 = initializeList(test_Q1, 3); 84 | printf("Original list: "); 85 | printList(Q1); 86 | deleteNode(2, Q1); 87 | printf("After deletion: "); 88 | printList(Q1); 89 | deleteMarkedNodes(Q1); 90 | printf("After deleteMarkedNodes: "); 91 | printList(Q1); 92 | deleteAll(Q1); 93 | } 94 | 95 | 96 | void 97 | test_list_independence() 98 | { 99 | /* Test out whether static global variables 100 | * will stay independence (i.e. numNodes, numDeleted) 101 | * for different instantiation. The answer is YES! 102 | */ 103 | printf("TEST: list_independence\n"); 104 | ET test_Q1[] = {1,2,3}; 105 | List Q1 = initializeList(test_Q1, 3); 106 | printf("Original list: "); 107 | printList(Q1); 108 | deleteNode(2, Q1); 109 | printf("After deletion: "); 110 | printList(Q1); 111 | deleteAll(Q1); 112 | ET test_L[] = {23, 44, 45, 57, 89, -1}; 113 | List L = initializeList(test_L, 6); 114 | printList(L); 115 | deleteNode(45,L); 116 | printf("After deletion: "); 117 | printList(L); 118 | deleteAll(L); 119 | } 120 | 121 | -------------------------------------------------------------------------------- /linkedList/polynomial/Makefile: -------------------------------------------------------------------------------- 1 | C_COMPILER=gcc 2 | CFLAGS = -Wall -g 3 | 4 | SRC_FILES=\ 5 | $(wildcard ./*.c) 6 | OUTPUT_FILE=main 7 | 8 | .PHONY: clean 9 | .PHONY: test 10 | 11 | test: 12 | $(C_COMPILER) $(CFLAGS) $(SRC_FILES) -o $(OUTPUT_FILE) 13 | ./$(OUTPUT_FILE) -v 14 | 15 | clean: 16 | rm -rf $(OUTPUT_FILE) 17 | -------------------------------------------------------------------------------- /linkedList/polynomial/polynomial.h: -------------------------------------------------------------------------------- 1 | #ifndef _POLYNOMIALL_H 2 | #define _POLYNOMIALL_H 3 | 4 | /* We assume the nodes sorted by exponents 5 | * and again, our linked list implementation 6 | * uses sentinel node 7 | */ 8 | typedef struct Node *PtrToNode; 9 | 10 | struct Node 11 | { 12 | int coefficient; 13 | int exponent; 14 | PtrToNode Next; 15 | }; 16 | 17 | typedef PtrToNode Polynomial; 18 | 19 | #endif 20 | 21 | /**---- BASIC LIST OPERATION POLYNOMIAL VERSION ----**/ 22 | 23 | /* Insert (after legal term P) 24 | */ 25 | void insert(int coefficent, int exponent, PtrToNode p); 26 | 27 | /* We don't delete the header node. 28 | * In ohter words, the empty polynomial contains a header node. 29 | */ 30 | void deletePolynomial(Polynomial A); 31 | 32 | /**---- VARIOUS POLYNOMIAL PROBLEMS ----**/ 33 | 34 | /* Create a polynomial from given arrays. 35 | * The first input array represents all the coefficients of the polynomial. 36 | * The second input array represents all the corresponding exponents. 37 | */ 38 | Polynomial initializePolynomial(int coefficient[], int exponent[], int numterms); 39 | 40 | /* Print out a polynomial 41 | */ 42 | void printPolynomial(Polynomial A); 43 | 44 | 45 | /* 3.6 Write a function to add two polynomials. Do not 46 | * destroy the input. Use a linked list implementation. 47 | * We assume the input polynomials are sorted in descending order. 48 | */ 49 | Polynomial add(Polynomial A, Polynomial B); 50 | 51 | /* 3.7 Write a function to multiply two polynomials, using a linked list 52 | * implementation. You must make sure that the output polynomial is sorted 53 | * by exponent and has at most one term of any power. 54 | * We assume the output is sorted in descending order. 55 | */ 56 | 57 | /* 3.7.a Give an algorithm to solve this problem in O(M^2 N^2) time. 58 | */ 59 | Polynomial multiply1(Polynomial A, Polynomial B); 60 | 61 | /* 3.7.b Write a program to perform the multiplication in O(M^2 N) time, where 62 | * M is the number of terms in the polynomial of fewer terms. 63 | */ 64 | Polynomial multiply2(Polynomial A, Polynomial B); 65 | 66 | /* 3.7.c Write a program to perform the multiplication in O(MNlog(MN)) time. 67 | */ 68 | Polynomial mutliply3(Polynomial A, Polynomial B); 69 | 70 | /* 3.8 Write a program that takes a polynomial, F(X), and computes (F(x))^P. 71 | */ 72 | Polynomial powPolynomial(Polynomial A, int P); 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /linkedList/polynomial/polynomialTestMain.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "polynomial.h" 4 | 5 | int main() 6 | { 7 | printf("///////////////////////\n"); 8 | printf("// POLYNOMIAL TEST\n"); 9 | printf("///////////////////////\n\n"); 10 | 11 | printf("TEST: initializePolynomial\n"); 12 | int coefficient0[] = {3,2,1}; 13 | int exponent0[] = {3,2,1}; 14 | Polynomial A0 = initializePolynomial(coefficient0, exponent0, 3); 15 | printPolynomial(A0); 16 | 17 | printf("TEST: add two Polynomials\n"); 18 | Polynomial B1 = initializePolynomial(coefficient0, exponent0, 3); 19 | int coefficient1[] = {4}; 20 | int exponent1[] = {4}; 21 | Polynomial D1 = initializePolynomial(coefficient1, exponent1, 1); 22 | Polynomial C10 = add(A0,B1); 23 | Polynomial C11 = add(A0,D1); 24 | printPolynomial(C10); 25 | printPolynomial(C11); 26 | 27 | printf("TEST: multiply two Polynomials\n"); 28 | printf("Algorithm 1\n"); 29 | int coefficient20[] = {3,2}; 30 | int exponent20[] = {3,2}; 31 | int coefficient21[] = {5,6}; 32 | int exponent21[] = {5,4}; 33 | Polynomial B2 = initializePolynomial(coefficient20, exponent20, 2); 34 | Polynomial B3 = initializePolynomial(coefficient21, exponent21, 2); 35 | Polynomial C20 = multiply1(B2,B3); 36 | printPolynomial(C20); 37 | 38 | printf("Algorithm 2\n"); 39 | Polynomial C21 = multiply2(B2,B3); 40 | printPolynomial(C21); 41 | 42 | printf("TEST: power of Polynomials\n"); 43 | int coefficient30[] = {1,1}; 44 | int exponent30[] = {1,0}; 45 | Polynomial B4 = initializePolynomial(coefficient30, exponent30, 2); 46 | Polynomial C3 = powPolynomial(B4, 2); 47 | printPolynomial(C3); 48 | 49 | 50 | return 0; 51 | } 52 | -------------------------------------------------------------------------------- /linkedList/self-adjusting/Makefile: -------------------------------------------------------------------------------- 1 | C_COMPILER=gcc 2 | CFLAGS = -Wall -g 3 | 4 | # Directories 5 | ROOT = ../../ 6 | 7 | SRC_FILES=\ 8 | $(wildcard ./*.c) \ 9 | $(ROOT)utility/utility.c 10 | 11 | INC_DIRS=\ 12 | -I$(ROOT)utility \ 13 | -I$(ROOT)linkedList/generic \ 14 | 15 | LIBS=\ 16 | -lm 17 | 18 | OUTPUT_FILE=main 19 | 20 | .PHONY: clean 21 | .PHONY: test 22 | 23 | test: 24 | $(C_COMPILER) $(CFLAGS) $(INC_DIRS) $(LIBS) $(SRC_FILES) -o $(OUTPUT_FILE) 25 | ./$(OUTPUT_FILE) -v 26 | 27 | clean: 28 | rm -rf $(OUTPUT_FILE) 29 | -------------------------------------------------------------------------------- /linkedList/self-adjusting/arrayList.c: -------------------------------------------------------------------------------- 1 | #include "arrayList.h" 2 | 3 | int* 4 | arrayTranslate(int B[], int length) 5 | { 6 | int* res = calloc(length, sizeof(int)); 7 | int i; 8 | for (i = 0; i < length; i++) 9 | { 10 | *(res+i) = B[i]; 11 | } 12 | return res; 13 | } 14 | 15 | void 16 | printArrayList(int* A, int length) 17 | { 18 | int i; 19 | for (i = 0; i < length; i++) 20 | { 21 | printf("%d, ", A[i]); 22 | } 23 | printf("\n"); 24 | } 25 | 26 | void 27 | arrayInsert(int elem, int** list, int length) 28 | { 29 | *list = realloc(*list, sizeof(int) * (length+1)); 30 | int i; 31 | for (i = 0; i < length; i++) 32 | { 33 | (*list)[length - i] = (*list)[length-i-1]; 34 | } 35 | *((*list)) = elem; 36 | } 37 | 38 | int 39 | arrayFind(int elem, int* list, int length) 40 | { 41 | int i, j; 42 | for( i = 0; i < length; i++) 43 | { 44 | if (list[i] == elem) 45 | { 46 | for( j = 0; j < i; j++) 47 | { 48 | list[i - j] = list[i - j -1]; 49 | } 50 | list[0] = elem; 51 | return 0; 52 | } 53 | } 54 | return -1; 55 | } 56 | -------------------------------------------------------------------------------- /linkedList/self-adjusting/arrayList.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | /* 3.15.a Write an array implementation 5 | * of self-adjusting lists. A self-adjusting 6 | * list is like a regular list, except that 7 | * all insertions are performed at the front, 8 | * and when an element is accessed by a Find, 9 | * it is moved to the front of the list without 10 | * changing the relative order of the other items. 11 | */ 12 | 13 | /* Stack array translates to the heap array 14 | */ 15 | int* arrayTranslate(int B[], int length); 16 | 17 | /* Print the list 18 | */ 19 | void printArrayList(int* A, int length); 20 | 21 | /* insert an element elem at front 22 | */ 23 | void arrayInsert(int elem, int** list, int length); 24 | 25 | /* find the first appreance of the elem and return 0 if find. 26 | * -1 if not found. 27 | */ 28 | int arrayFind(int elem, int* list, int length); 29 | -------------------------------------------------------------------------------- /linkedList/self-adjusting/arrayListTestMain.c: -------------------------------------------------------------------------------- 1 | #include "arrayList.h" 2 | #include "utility.h" 3 | #include 4 | #include 5 | 6 | void test_insert(); 7 | void test_findArray(); 8 | 9 | int 10 | main() 11 | { 12 | test_insert(); printf("\n"); 13 | test_findArray(); printf("\n"); 14 | return 0; 15 | } 16 | 17 | void test_insert() 18 | { 19 | printf("TEST: arrayInsert\n"); 20 | int test[] = {1,2,3}; 21 | int* list = arrayTranslate(test, 3); 22 | printf("Before arrayInsert: \n"); 23 | printArrayList(list,3); 24 | arrayInsert(5, &list, 3); 25 | printf("After arrayInsert: \n"); 26 | printArrayList(list,4); 27 | } 28 | 29 | void 30 | test_findArray() 31 | { 32 | printf("TEST: arrayInsert\n"); 33 | int test[] = {1,2,3}; 34 | int* list = arrayTranslate(test, 3); 35 | printf("Before arrayFind: \n"); 36 | printArrayList(list,3); 37 | int index = arrayFind(3, list, 3); 38 | printf("target location: %d\n", index); 39 | printArrayList(list,3); 40 | } 41 | -------------------------------------------------------------------------------- /queue/arrayImplementation/Makefile: -------------------------------------------------------------------------------- 1 | C_COMPILER=gcc 2 | CFLAGS = -Wall -g 3 | 4 | # Directories 5 | ROOT = ../../ 6 | 7 | SRC_FILES=\ 8 | $(wildcard ./*.c) \ 9 | $(ROOT)utility/utility.c 10 | 11 | INC_DIRS=\ 12 | -I$(ROOT)utility/ 13 | 14 | LIBS=\ 15 | -lm 16 | 17 | OUTPUT_FILE=main 18 | 19 | .PHONY: clean 20 | .PHONY: test 21 | 22 | test: 23 | $(C_COMPILER) $(CFLAGS) $(INC_DIRS) $(LIBS) $(SRC_FILES) -o $(OUTPUT_FILE) 24 | ./$(OUTPUT_FILE) -v 25 | 26 | clean: 27 | rm -rf $(OUTPUT_FILE) 28 | -------------------------------------------------------------------------------- /queue/arrayImplementation/queue.c: -------------------------------------------------------------------------------- 1 | #include "queue.h" 2 | 3 | struct QueueRecord 4 | { 5 | int Capacity; 6 | int Front; 7 | int Rear; 8 | int Size; 9 | ET *Array; 10 | }; 11 | 12 | int 13 | isEmpty(Queue Q) 14 | { 15 | return Q->Size == 0; 16 | } 17 | 18 | int 19 | isFull(Queue Q) 20 | { 21 | return Q->Capacity == Q->Size; 22 | } 23 | 24 | Queue 25 | createQueue(int maxElements) 26 | { 27 | Queue Q = malloc(sizeof(struct QueueRecord)); 28 | Q->Capacity = maxElements; 29 | Q->Front = Q->Capacity / 2; 30 | Q->Rear = Q->Front; 31 | Q->Size = 0; 32 | Q->Array = calloc(Q->Capacity, sizeof(ET)); 33 | return Q; 34 | } 35 | 36 | void 37 | disposeQueue(Queue Q) 38 | { 39 | free(Q->Array); 40 | free(Q); 41 | } 42 | 43 | void 44 | makeEmpty(Queue Q) 45 | { 46 | while(!isEmpty(Q)) 47 | { 48 | dequeue(Q); 49 | } 50 | } 51 | 52 | void 53 | enqueue(ET elem, Queue Q) 54 | { 55 | if (Q->Size == Q->Capacity) 56 | { 57 | fatal("Queue is full!"); 58 | } 59 | // there is enough space 60 | if (Q->Rear < Q->Capacity - 1) 61 | { 62 | Q->Array[Q->Rear++] = elem; 63 | Q->Size++; 64 | } 65 | // We wrap around the array 66 | else if (Q->Rear == Q->Capacity - 1) 67 | { 68 | Q->Array[Q->Rear] = elem; 69 | Q->Size++; 70 | Q->Rear = 0; 71 | } 72 | } 73 | 74 | ET 75 | front(Queue Q) 76 | { 77 | return Q->Array[Q->Front]; 78 | } 79 | 80 | void 81 | dequeue(Queue Q) 82 | { 83 | Q->Size--; 84 | Q->Array[Q->Front] = 0; 85 | Q->Front++; 86 | if (Q->Front >= Q->Capacity) 87 | { 88 | Q->Front = 0; 89 | } 90 | } 91 | 92 | ET 93 | frontAndDequeue(Queue Q) 94 | { 95 | int res = Q->Array[Q->Front]; 96 | dequeue(Q); 97 | return res; 98 | } 99 | 100 | Queue 101 | initializeQueue(ET array[], int lengthArray) 102 | { 103 | Queue Q = createQueue(lengthArray); 104 | int i; 105 | for (i = 0; i < lengthArray; i++) 106 | { 107 | enqueue(array[i], Q); 108 | } 109 | return Q; 110 | } 111 | 112 | void 113 | printQueue(Queue Q) 114 | { 115 | int i; 116 | for(i = 0; i < Q->Capacity; i++) 117 | { 118 | printf("|%s%d%s|", 119 | (i == Q->Front) ? ("Front:") : (""), 120 | Q->Array[i], 121 | (i == Q->Rear) ? (":Rear") : ("")); 122 | } 123 | printf("\n"); 124 | } 125 | 126 | -------------------------------------------------------------------------------- /queue/arrayImplementation/queue.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "utility.h" 4 | 5 | /* 6 | * MAW 3.25.b Write the routines to implement queues using: Arrays 7 | * 8 | * We use a circular array implementation. 9 | * Whenever Front or Rear gets to the end of the array, it is wrapped around to the 10 | * beginning. 11 | */ 12 | #ifndef _QUEUE_H 13 | #define _QUEUE_H 14 | 15 | typedef int ET; 16 | 17 | struct QueueRecord; 18 | typedef struct QueueRecord* Queue; 19 | 20 | int isEmpty(Queue Q); 21 | int isFull(Queue Q); 22 | Queue createQueue(int maxElements); 23 | void disposeQueue(Queue Q); 24 | void makeEmpty(Queue Q); 25 | void enqueue(ET elem, Queue Q); 26 | ET front(Queue Q); 27 | void dequeue(Queue Q); 28 | ET frontAndDequeue(Queue Q); 29 | 30 | Queue initializeQueue(ET array[], int lengthArray); 31 | void printQueue(Queue Q); 32 | 33 | #endif 34 | 35 | -------------------------------------------------------------------------------- /queue/arrayImplementation/queueTestMain.c: -------------------------------------------------------------------------------- 1 | #include "queue.h" 2 | #include 3 | #include 4 | #include 5 | #include "utility.h" 6 | 7 | void test_isEmpty(); 8 | void test_createQueue(); 9 | void test_makeEmpty(); 10 | void test_enqueue(); 11 | void test_front(); 12 | void test_dequeue(); 13 | void test_frontAndDequeue(); 14 | void test_initializeQueue(); 15 | 16 | int main() 17 | { 18 | printf("///////////////////////\n"); 19 | printf("// QUEUE TEST\n"); 20 | printf("///////////////////////\n\n"); 21 | 22 | test_createQueue(); printf("\n"); 23 | test_initializeQueue(); printf("\n"); 24 | test_isEmpty(); printf("\n"); 25 | test_makeEmpty(); printf("\n"); 26 | test_enqueue(); printf("\n"); 27 | test_front(); printf("\n"); 28 | test_dequeue(); printf("\n"); 29 | test_frontAndDequeue(); printf("\n"); 30 | return 0; 31 | } 32 | 33 | void 34 | test_isEmpty() 35 | { 36 | printf("TEST: isEmpty\n"); 37 | Queue Q = createQueue(3); 38 | printQueue(Q); 39 | printf("is Queue empty: %s\n", (isEmpty(Q)) ? ("Yes") : ("No")); 40 | disposeQueue(Q); 41 | ET test_Q1[3] = {99, 1, 20}; 42 | printf("test_Q1: "); 43 | printArray(test_Q1, 3); 44 | Q = initializeQueue(test_Q1, 3); 45 | printQueue(Q); 46 | printf("is Queue empty: %s\n", (isEmpty(Q)) ? ("Yes") : ("No")); 47 | disposeQueue(Q); 48 | } 49 | 50 | void 51 | test_createQueue() 52 | { 53 | printf("TEST: createQueue\n"); 54 | Queue Q = createQueue(3); 55 | printQueue(Q); 56 | disposeQueue(Q); 57 | } 58 | 59 | void 60 | test_makeEmpty() 61 | { 62 | printf("TEST: makeEmpty\n"); 63 | ET test_Q1[3] = {99, 1, 20}; 64 | printf("test_Q1: "); 65 | printArray(test_Q1, 3); 66 | Queue Q = initializeQueue(test_Q1, 3); 67 | printQueue(Q); 68 | makeEmpty(Q); 69 | printf("test_Q1 after makeEmpty: \n"); 70 | printQueue(Q); 71 | printf("Is test_Q1 empty?: %s\n", (isEmpty(Q)) ? ("Yes") : ("False")); 72 | } 73 | 74 | void 75 | test_enqueue() 76 | { 77 | printf("TEST: enqueue\n"); 78 | ET test_Q1[3] = {99, 1, 20}; 79 | printf("test_Q1: "); 80 | printArray(test_Q1, 3); 81 | Queue Q = createQueue(10); 82 | printQueue(Q); 83 | int i; 84 | for (i = 0; i < 3; i++) 85 | { 86 | printf("enqueue: %d\n", test_Q1[i]); 87 | enqueue(test_Q1[i], Q); 88 | } 89 | printQueue(Q); 90 | disposeQueue(Q); 91 | } 92 | 93 | void 94 | test_front() 95 | { 96 | printf("TEST: front\n"); 97 | ET test_Q1[3] = {99, 1, 20}; 98 | printf("test_Q1: "); 99 | printArray(test_Q1, 3); 100 | Queue Q = initializeQueue(test_Q1, 3); 101 | printQueue(Q); 102 | printf("front: %d\n", front(Q)); 103 | disposeQueue(Q); 104 | } 105 | 106 | void 107 | test_dequeue() 108 | { 109 | printf("TEST: dequeue\n"); 110 | ET test_Q1[3] = {99, 1, 20}; 111 | printf("test_Q1: "); 112 | printArray(test_Q1, 3); 113 | Queue Q = initializeQueue(test_Q1, 3); 114 | printQueue(Q); 115 | printf("After dequeue once: \n"); 116 | dequeue(Q); 117 | printQueue(Q); 118 | disposeQueue(Q); 119 | } 120 | 121 | void 122 | test_frontAndDequeue() 123 | { 124 | printf("TEST: frontAndDequeue\n"); 125 | ET test_Q1[3] = {99, 1, 20}; 126 | printf("test_Q1: "); 127 | printArray(test_Q1, 3); 128 | Queue Q = initializeQueue(test_Q1, 3); 129 | printQueue(Q); 130 | printf("After dequeue the element: %d\n", frontAndDequeue(Q)); 131 | printQueue(Q); 132 | disposeQueue(Q); 133 | } 134 | 135 | void 136 | test_initializeQueue() 137 | { 138 | printf("TEST: createQueue\n"); 139 | ET test_Q1[3] = {99, 1, 20}; 140 | printf("test_Q1: "); 141 | printArray(test_Q1, 3); 142 | Queue Q = initializeQueue(test_Q1, 3); 143 | printQueue(Q); 144 | disposeQueue(Q); 145 | } 146 | -------------------------------------------------------------------------------- /queue/deque/Makefile: -------------------------------------------------------------------------------- 1 | C_COMPILER=gcc 2 | CFLAGS = -Wall -g 3 | 4 | # Directories 5 | ROOT = ../../ 6 | 7 | SRC_FILES=\ 8 | $(wildcard ./*.c) \ 9 | $(ROOT)utility/utility.c 10 | 11 | INC_DIRS=\ 12 | -I$(ROOT)utility/ 13 | 14 | LIBS=\ 15 | -lm 16 | 17 | OUTPUT_FILE=main 18 | 19 | .PHONY: clean 20 | .PHONY: test 21 | 22 | test: 23 | $(C_COMPILER) $(CFLAGS) $(INC_DIRS) $(LIBS) $(SRC_FILES) -o $(OUTPUT_FILE) 24 | ./$(OUTPUT_FILE) -v 25 | 26 | clean: 27 | rm -rf $(OUTPUT_FILE) 28 | -------------------------------------------------------------------------------- /queue/deque/deque.c: -------------------------------------------------------------------------------- 1 | #include "deque.h" 2 | 3 | struct DequeRecord 4 | { 5 | int Capacity; 6 | int Front; 7 | int Rear; 8 | int Size; 9 | ET *Array; 10 | }; 11 | 12 | int 13 | isEmpty(Deque D) 14 | { 15 | return D->Size == 0; 16 | } 17 | 18 | int 19 | isFull(Deque D) 20 | { 21 | return D->Capacity == D->Size; 22 | } 23 | 24 | Deque 25 | createDeque(int maxElements) 26 | { 27 | Deque D = malloc(sizeof(struct DequeRecord)); 28 | D->Capacity = maxElements; 29 | D->Front = D->Capacity / 2; 30 | D->Rear = D->Front; 31 | D->Size = 0; 32 | D->Array = calloc(D->Capacity, sizeof(ET)); 33 | return D; 34 | } 35 | 36 | void 37 | disposeDeque(Deque D) 38 | { 39 | free(D->Array); 40 | free(D); 41 | } 42 | 43 | void 44 | makeEmpty(Deque D) 45 | { 46 | while(!isEmpty(D)) 47 | { 48 | pop(D); 49 | } 50 | } 51 | 52 | void 53 | inject(ET elem, Deque D) 54 | { 55 | if (D->Size == D->Capacity) 56 | { 57 | fatal("Deque is full!"); 58 | } 59 | // there is enough space 60 | if (D->Rear < D->Capacity - 1) 61 | { 62 | D->Array[D->Rear++] = elem; 63 | D->Size++; 64 | } 65 | // We wrap around the array 66 | else if (D->Rear == D->Capacity - 1) 67 | { 68 | D->Array[D->Rear] = elem; 69 | D->Size++; 70 | D->Rear = 0; 71 | } 72 | } 73 | 74 | ET 75 | pop(Deque D) 76 | { 77 | int res = D->Array[D->Front]; 78 | D->Size--; 79 | D->Array[D->Front] = 0; 80 | D->Front++; 81 | if (D->Front >= D->Capacity) 82 | { 83 | D->Front = 0; 84 | } 85 | return res; 86 | } 87 | 88 | void 89 | push(ET elem, Deque D) 90 | { 91 | if(D->Size == D->Capacity) 92 | { 93 | fatal("Deque is full!"); 94 | } 95 | // if there is enough space 96 | if (D->Front > 0) 97 | { 98 | D->Array[D->Front--] = elem; 99 | D->Size++; 100 | } 101 | // wrap around 102 | else if (D->Front == 0) 103 | { 104 | D->Array[D->Front] = elem; 105 | D->Front = D->Capacity - 1; 106 | D->Size++; 107 | } 108 | } 109 | 110 | ET 111 | eject(Deque D) 112 | { 113 | int res = D->Array[D->Rear]; 114 | D->Size--; 115 | D->Array[D->Rear] = 0; 116 | D->Rear--; 117 | if (D->Rear <= 0) 118 | { 119 | D->Rear = D->Capacity - 1; 120 | } 121 | return res; 122 | } 123 | 124 | Deque 125 | initializeDeque(ET array[], int lengthArray) 126 | { 127 | Deque D = createDeque(lengthArray); 128 | int i; 129 | for (i = 0; i < lengthArray; i++) 130 | { 131 | inject(array[i], D); 132 | } 133 | return D; 134 | } 135 | 136 | void 137 | printDeque(Deque D) 138 | { 139 | int i; 140 | for(i = 0; i < D->Capacity; i++) 141 | { 142 | printf("|%s%d%s|", 143 | (i == D->Front) ? ("Front:") : (""), 144 | D->Array[i], 145 | (i == D->Rear) ? (":Rear") : ("")); 146 | } 147 | printf("\n"); 148 | } 149 | 150 | -------------------------------------------------------------------------------- /queue/deque/deque.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "utility.h" 4 | 5 | /* 6 | * MAW 3.26 A deque is a data structure consisting of a list of items, 7 | * on which the following operations are possible: 8 | * 9 | * Push(X,D): Insert item X on the front end of deque D. 10 | * Pop(D): Remove the front item fron deque D and return it. 11 | * Inject(X,D): Insert item X on the rear end of deque D. 12 | * Reject(D): Remove the rear item from deque D and return it. 13 | * 14 | * Write routines to support the deque that take O(1) time per operation. 15 | * 16 | * We use a circular array implementation. 17 | * Whenever Rear gets to the end of the array, it is wrapped around to the 18 | * beginning. Whenever Front gets to the beginning of the array, it is wrapped around to the 19 | * end. 20 | * 21 | * For a linked list version, we can have a single linked list with two 22 | * header nodes: one at the beginning and one at the end of the list. 23 | */ 24 | #ifndef _DEQUE_H 25 | #define _DEQUE_H 26 | 27 | typedef int ET; 28 | 29 | struct DequeRecord; 30 | typedef struct DequeRecord* Deque; 31 | 32 | int isEmpty(Deque D); 33 | int isFull(Deque D); 34 | Deque createDeque(int maxElements); 35 | void disposeDeque(Deque D); 36 | void makeEmpty(Deque D); 37 | void push(ET elem, Deque D); 38 | ET pop(Deque D); 39 | void inject(ET elem, Deque D); 40 | ET eject(Deque D); 41 | 42 | Deque initializeDeque(ET array[], int lengthArray); 43 | void printDeque(Deque D); 44 | 45 | #endif 46 | 47 | -------------------------------------------------------------------------------- /queue/deque/dequeTestMain.c: -------------------------------------------------------------------------------- 1 | #include "deque.h" 2 | #include 3 | #include 4 | #include 5 | #include "utility.h" 6 | 7 | void test_createDeque(); 8 | void test_push(); 9 | void test_initializeDeque(); 10 | void test_pop(); 11 | void test_inject(); 12 | void test_eject(); 13 | void test_isEmpty(); 14 | void test_makeEmpty(); 15 | 16 | 17 | int main() 18 | { 19 | printf("///////////////////////\n"); 20 | printf("// DEQUE TEST\n"); 21 | printf("///////////////////////\n\n"); 22 | 23 | test_createDeque(); printf("\n"); 24 | test_push(); printf("\n"); 25 | test_initializeDeque(); printf("\n"); 26 | test_pop(); printf("\n"); 27 | test_inject(); printf("\n"); 28 | test_eject(); printf("\n"); 29 | test_isEmpty(); printf("\n"); 30 | test_makeEmpty(); printf("\n"); 31 | return 0; 32 | } 33 | 34 | void 35 | test_createDeque() 36 | { 37 | printf("TEST: createDeque\n"); 38 | Deque D = createDeque(3); 39 | printDeque(D); 40 | disposeDeque(D); 41 | } 42 | 43 | void 44 | test_push() 45 | { 46 | printf("TEST: push\n"); 47 | ET test_Q1[3] = {99, 1, 20}; 48 | printf("test_Q1: "); 49 | printArray(test_Q1, 3); 50 | Deque D = createDeque(10); 51 | printDeque(D); 52 | int i; 53 | for (i = 0; i < 3; i++) 54 | { 55 | printf("push: %d\n", test_Q1[i]); 56 | push(test_Q1[i], D); 57 | } 58 | printDeque(D); 59 | disposeDeque(D); 60 | } 61 | 62 | void 63 | test_initializeDeque() 64 | { 65 | printf("TEST: initializeDeque\n"); 66 | ET test_Q1[3] = {99, 1, 20}; 67 | printf("test_Q1: "); 68 | printArray(test_Q1, 3); 69 | Deque D = initializeDeque(test_Q1, 3); 70 | printDeque(D); 71 | disposeDeque(D); 72 | } 73 | 74 | void 75 | test_pop() 76 | { 77 | printf("TEST: pop\n"); 78 | ET test_Q1[3] = {99, 1, 20}; 79 | printf("test_Q1: "); 80 | printArray(test_Q1, 3); 81 | Deque D = initializeDeque(test_Q1, 3); 82 | printf("Pop element: %d\n", pop(D)); 83 | printDeque(D); 84 | disposeDeque(D); 85 | } 86 | 87 | void 88 | test_inject() 89 | { 90 | printf("TEST: inject\n"); 91 | ET test_Q1[3] = {99, 1, 20}; 92 | printf("test_Q1: "); 93 | printArray(test_Q1, 3); 94 | Deque D = createDeque(10); 95 | printDeque(D); 96 | int i; 97 | for (i = 0; i < 3; i++) 98 | { 99 | printf("inject: %d\n", test_Q1[i]); 100 | inject(test_Q1[i], D); 101 | } 102 | printDeque(D); 103 | disposeDeque(D); 104 | } 105 | 106 | void 107 | test_eject() 108 | { 109 | printf("TEST: eject\n"); 110 | ET test_Q1[3] = {99, 1, 20}; 111 | printf("test_Q1: "); 112 | printArray(test_Q1, 3); 113 | Deque D = initializeDeque(test_Q1, 3); 114 | printDeque(D); 115 | printf("Eject element: %d\n", eject(D)); 116 | printDeque(D); 117 | disposeDeque(D); 118 | } 119 | 120 | void 121 | test_isEmpty() 122 | { 123 | printf("TEST: isEmpty\n"); 124 | Deque D = createDeque(3); 125 | printDeque(D); 126 | printf("is Deque empty: %s\n", (isEmpty(D)) ? ("Yes") : ("No")); 127 | disposeDeque(D); 128 | ET test_Q1[3] = {99, 1, 20}; 129 | printf("test_Q1: "); 130 | printArray(test_Q1, 3); 131 | D = initializeDeque(test_Q1, 3); 132 | printDeque(D); 133 | printf("is Deque empty: %s\n", (isEmpty(D)) ? ("Yes") : ("No")); 134 | disposeDeque(D); 135 | } 136 | 137 | void 138 | test_makeEmpty() 139 | { 140 | printf("TEST: makeEmpty\n"); 141 | ET test_Q1[3] = {99, 1, 20}; 142 | printf("test_Q1: "); 143 | printArray(test_Q1, 3); 144 | Deque D = initializeDeque(test_Q1, 3); 145 | printDeque(D); 146 | makeEmpty(D); 147 | printf("test_Q1 after makeEmpty: \n"); 148 | printDeque(D); 149 | printf("Is test_Q1 empty?: %s\n", (isEmpty(D)) ? ("Yes") : ("False")); 150 | } 151 | 152 | -------------------------------------------------------------------------------- /queue/linkedListImplementation/Makefile: -------------------------------------------------------------------------------- 1 | C_COMPILER=gcc 2 | CFLAGS = -Wall -g 3 | 4 | # Directories 5 | ROOT = ../../ 6 | 7 | SRC_FILES=\ 8 | $(wildcard ./*.c) \ 9 | $(ROOT)utility/utility.c 10 | 11 | INC_DIRS=\ 12 | -I$(ROOT)utility/ 13 | 14 | LIBS=\ 15 | -lm 16 | 17 | OUTPUT_FILE=main 18 | 19 | .PHONY: clean 20 | .PHONY: test 21 | 22 | test: 23 | $(C_COMPILER) $(CFLAGS) $(INC_DIRS) $(LIBS) $(SRC_FILES) -o $(OUTPUT_FILE) 24 | ./$(OUTPUT_FILE) -v 25 | 26 | clean: 27 | rm -rf $(OUTPUT_FILE) 28 | -------------------------------------------------------------------------------- /queue/linkedListImplementation/queue.c: -------------------------------------------------------------------------------- 1 | #include "queue.h" 2 | 3 | struct QueueRecord 4 | { 5 | ET Element; 6 | PtrToNode Next; 7 | }; 8 | 9 | struct QueueCDT 10 | { 11 | PtrToNode Front; 12 | PtrToNode Rear; 13 | }; 14 | 15 | int 16 | isEmpty(QueueADT Q) 17 | { 18 | return Q->Front == Q->Rear; 19 | } 20 | 21 | QueueADT 22 | createQueue() 23 | { 24 | QueueADT Q = malloc(sizeof(struct QueueCDT)); 25 | Q->Front = malloc(sizeof(struct QueueRecord)); 26 | Q->Front->Next = NULL; 27 | Q->Rear = Q->Front; 28 | return Q; 29 | } 30 | 31 | void 32 | disposeQueue(QueueADT Q) 33 | { 34 | makeEmpty(Q); 35 | free(Q->Front); 36 | free(Q); 37 | } 38 | 39 | void 40 | makeEmpty(QueueADT Q) 41 | { 42 | while(!isEmpty(Q)) 43 | { 44 | dequeue(Q); 45 | } 46 | } 47 | 48 | void 49 | enqueue(ET elem, QueueADT Q) 50 | { 51 | PtrToNode tmpNode = malloc(sizeof(struct QueueRecord)); 52 | tmpNode->Element = elem; 53 | tmpNode->Next = NULL; 54 | Q->Rear->Next = tmpNode; 55 | Q->Rear = tmpNode; 56 | } 57 | 58 | ET 59 | front(QueueADT Q) 60 | { 61 | return Q->Front->Next->Element; 62 | } 63 | 64 | void 65 | dequeue(QueueADT Q) 66 | { 67 | PtrToNode dummyQ; 68 | dummyQ = Q->Front->Next; 69 | Q->Front->Next = dummyQ->Next; 70 | // we don't want to accidentally delete Q->Rear when there is only one data node left 71 | if (dummyQ->Next == NULL) 72 | { 73 | Q->Rear = Q->Front; 74 | } 75 | free(dummyQ); 76 | } 77 | 78 | ET 79 | frontAndDequeue(QueueADT Q) 80 | { 81 | ET tmp = Q->Front->Next->Element; 82 | dequeue(Q); 83 | return tmp; 84 | } 85 | 86 | QueueADT 87 | initializeQueue(ET array[], int lengthArray) 88 | { 89 | QueueADT Q = createQueue(); 90 | int i; 91 | for (i = 0; i < lengthArray; i++) 92 | { 93 | enqueue(array[i], Q); 94 | } 95 | return Q; 96 | } 97 | 98 | void 99 | printQueue(QueueADT Q) 100 | { 101 | PtrToNode dummyQ = Q->Front->Next; 102 | printf("Front:"); 103 | while(dummyQ != NULL) 104 | { 105 | printf("|%d|%s", dummyQ->Element, (dummyQ->Next == NULL) ? (""): ("->")); 106 | dummyQ = dummyQ->Next; 107 | } 108 | printf(":Rear\n"); 109 | } 110 | 111 | -------------------------------------------------------------------------------- /queue/linkedListImplementation/queue.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "utility.h" 4 | 5 | /* 6 | * MAW 3.25.a Write the routines to implement queues using: Linked Lists 7 | * 8 | * We use a header node at the very beginning of the linked list. 9 | * 10 | * Front: | header node | -> | data node | -> | data node | :Rear 11 | */ 12 | #ifndef _QUEUE_H 13 | #define _QUEUE_H 14 | 15 | typedef int ET; 16 | 17 | struct QueueRecord; 18 | struct QueueCDT; 19 | typedef struct QueueRecord* PtrToNode; 20 | 21 | // CDT: concrete-type-of-a-queue 22 | // ADT: abstract-type-of-a-queue 23 | typedef struct QueueCDT* QueueADT; // naming convention: https://www.cs.bu.edu/teaching/c/queue/linked-list/types.html 24 | 25 | int isEmpty(QueueADT Q); 26 | QueueADT createQueue(); 27 | void disposeQueue(QueueADT Q); 28 | void makeEmpty(QueueADT Q); 29 | void enqueue(ET elem, QueueADT Q); 30 | ET front(QueueADT Q); 31 | void dequeue(QueueADT Q); 32 | ET frontAndDequeue(QueueADT Q); 33 | 34 | QueueADT initializeQueue(ET array[], int lengthArray); 35 | void printQueue(QueueADT Q); 36 | 37 | #endif 38 | 39 | -------------------------------------------------------------------------------- /queue/linkedListImplementation/queueTestMain.c: -------------------------------------------------------------------------------- 1 | #include "queue.h" 2 | #include 3 | #include 4 | #include 5 | #include "utility.h" 6 | 7 | void test_isEmpty(); 8 | void test_createQueue(); 9 | void test_makeEmpty(); 10 | void test_enqueue(); 11 | void test_front(); 12 | void test_dequeue(); 13 | void test_frontAndDequeue(); 14 | void test_initializeQueue(); 15 | 16 | int main() 17 | { 18 | printf("///////////////////////\n"); 19 | printf("// QUEUE TEST\n"); 20 | printf("///////////////////////\n\n"); 21 | 22 | test_createQueue(); printf("\n"); 23 | test_initializeQueue(); printf("\n"); 24 | test_isEmpty(); printf("\n"); 25 | test_makeEmpty(); printf("\n"); 26 | test_enqueue(); printf("\n"); 27 | test_front(); printf("\n"); 28 | test_dequeue(); printf("\n"); 29 | test_frontAndDequeue(); printf("\n"); 30 | return 0; 31 | } 32 | 33 | void 34 | test_isEmpty() 35 | { 36 | printf("TEST: isEmpty\n"); 37 | QueueADT Q = createQueue(); 38 | printQueue(Q); 39 | printf("is Queue empty: %s\n", (isEmpty(Q)) ? ("Yes") : ("No")); 40 | disposeQueue(Q); 41 | ET test_Q1[3] = {99, 1, 20}; 42 | printf("test_Q1: "); 43 | printArray(test_Q1, 3); 44 | Q = initializeQueue(test_Q1, 3); 45 | printQueue(Q); 46 | printf("is Queue empty: %s\n", (isEmpty(Q)) ? ("Yes") : ("No")); 47 | disposeQueue(Q); 48 | } 49 | 50 | void 51 | test_createQueue() 52 | { 53 | printf("TEST: createQueue\n"); 54 | QueueADT Q = createQueue(); 55 | printQueue(Q); 56 | disposeQueue(Q); 57 | } 58 | 59 | void 60 | test_makeEmpty() 61 | { 62 | printf("TEST: makeEmpty\n"); 63 | ET test_Q1[3] = {99, 1, 20}; 64 | printf("test_Q1: "); 65 | printArray(test_Q1, 3); 66 | QueueADT Q = initializeQueue(test_Q1, 3); 67 | printQueue(Q); 68 | makeEmpty(Q); 69 | printf("test_Q1 after makeEmpty: \n"); 70 | printQueue(Q); 71 | } 72 | 73 | void 74 | test_enqueue() 75 | { 76 | printf("TEST: enqueue\n"); 77 | ET test_Q1[3] = {99, 1, 20}; 78 | printf("test_Q1: "); 79 | printArray(test_Q1, 3); 80 | QueueADT Q = initializeQueue(test_Q1, 3); 81 | printQueue(Q); 82 | ET elem1 = 10; 83 | enqueue(elem1, Q); 84 | printf("enqueue: %d\n", elem1); 85 | printQueue(Q); 86 | disposeQueue(Q); 87 | } 88 | 89 | void 90 | test_front() 91 | { 92 | printf("TEST: front\n"); 93 | ET test_Q1[3] = {99, 1, 20}; 94 | printf("test_Q1: "); 95 | printArray(test_Q1, 3); 96 | QueueADT Q = initializeQueue(test_Q1, 3); 97 | printQueue(Q); 98 | printf("front: %d\n", front(Q)); 99 | disposeQueue(Q); 100 | } 101 | 102 | void 103 | test_dequeue() 104 | { 105 | printf("TEST: dequeue\n"); 106 | ET test_Q1[3] = {99, 1, 20}; 107 | printf("test_Q1: "); 108 | printArray(test_Q1, 3); 109 | QueueADT Q = initializeQueue(test_Q1, 3); 110 | printQueue(Q); 111 | printf("After dequeue once: \n"); 112 | dequeue(Q); 113 | printQueue(Q); 114 | disposeQueue(Q); 115 | } 116 | 117 | void 118 | test_frontAndDequeue() 119 | { 120 | printf("TEST: frontAndDequeue\n"); 121 | ET test_Q1[3] = {99, 1, 20}; 122 | printf("test_Q1: "); 123 | printArray(test_Q1, 3); 124 | QueueADT Q = initializeQueue(test_Q1, 3); 125 | printQueue(Q); 126 | printf("After dequeue the element: %d\n", frontAndDequeue(Q)); 127 | printQueue(Q); 128 | disposeQueue(Q); 129 | } 130 | 131 | void 132 | test_initializeQueue() 133 | { 134 | printf("TEST: createQueue\n"); 135 | ET test_Q1[3] = {99, 1, 20}; 136 | printf("test_Q1: "); 137 | printArray(test_Q1, 3); 138 | QueueADT Q = initializeQueue(test_Q1, 3); 139 | printQueue(Q); 140 | disposeQueue(Q); 141 | } 142 | -------------------------------------------------------------------------------- /sorting/Makefile: -------------------------------------------------------------------------------- 1 | C_COMPILER=gcc 2 | CFLAGS = -Wall -g 3 | 4 | # Directories 5 | ROOT = ../ 6 | 7 | SRC_FILES=\ 8 | $(wildcard ./*.c) \ 9 | $(ROOT)utility/utility.c 10 | 11 | INC_DIRS=\ 12 | -I$(ROOT)utility/ 13 | 14 | LIBS=\ 15 | -lm 16 | 17 | OUTPUT_FILE=main 18 | 19 | .PHONY: clean 20 | .PHONY: test 21 | 22 | test: 23 | $(C_COMPILER) $(CFLAGS) $(INC_DIRS) $(LIBS) $(SRC_FILES) -o $(OUTPUT_FILE) 24 | ./$(OUTPUT_FILE) -v 25 | 26 | clean: 27 | rm -rf $(OUTPUT_FILE) 28 | -------------------------------------------------------------------------------- /sorting/sort.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "utility.h" 5 | 6 | #define Cutoff (3) // Used in quickSort, Qselect 7 | 8 | void shellSort(int A[], int N); 9 | void bubbleSort(int A[], int N); 10 | void selectionSort(int A[], int N); 11 | void insertionSort(int A[], int N); 12 | void heapSort(int A[], int N); 13 | void mergeSort(int A[], int N); 14 | void quickSort(int A[], int N); 15 | 16 | /* Select the kth smallest element from the given array. 17 | * Place the kth smallest element in the kth position. 18 | * Because arrays start at 0, this will be index k-1. 19 | * NOTE: the original ordering will be destroyed. 20 | */ 21 | void Qselect(int A[], int k, int Left, int Right); 22 | 23 | /* 24 | * 7.14 How would you implement mergesort without 25 | * using recursion? 26 | */ 27 | void mergeSortNonRecursive(int A[], int N); 28 | -------------------------------------------------------------------------------- /sorting/sortTestMain.c: -------------------------------------------------------------------------------- 1 | #include "sort.h" 2 | #include "utility.h" 3 | 4 | void test_shellSort(void); 5 | void test_bubbleSort(void); 6 | void test_selectionSort(void); 7 | void test_insertionSort(void); 8 | void test_heapSort(void); 9 | void test_mergeSort(void); 10 | void test_quickSort(void); 11 | void test_Qselect(void); 12 | void test_mergeSortNonRecursive(void); 13 | 14 | int 15 | main(void) 16 | { 17 | printf("///////////////////////\n"); 18 | printf("// SORTING TEST\n"); 19 | printf("///////////////////////\n\n"); 20 | 21 | test_shellSort(); printf("===============\n\n"); 22 | test_bubbleSort(); printf("===============\n\n"); 23 | test_selectionSort(); printf("===============\n\n"); 24 | test_insertionSort(); printf("===============\n\n"); 25 | test_heapSort(); printf("===============\n\n"); 26 | test_mergeSort(); printf("===============\n\n"); 27 | test_quickSort(); printf("===============\n\n"); 28 | test_Qselect(); printf("===============\n\n"); 29 | test_mergeSortNonRecursive(); printf("===============\n\n"); 30 | 31 | return 0; 32 | } 33 | 34 | void 35 | test_shellSort(void) 36 | { 37 | printf("TEST: shellSort\n"); 38 | int test[] = {81,94,11,96,12,35,17,95,28,58,41,75,15}; 39 | printf("Befor shellSort: "); 40 | printArray(test, 13); 41 | shellSort(test, 13); 42 | printf("After shellSort: "); 43 | printArray(test, 13); 44 | } 45 | 46 | void 47 | test_bubbleSort(void) 48 | { 49 | printf("TEST: bubbleSort\n"); 50 | int test[] = {34,8,64,51,32,21}; 51 | printf("Befor bubbleSort: "); 52 | printArray(test, 6); 53 | bubbleSort(test, 6); 54 | printf("After bubbleSort: "); 55 | printArray(test, 6); 56 | } 57 | 58 | void 59 | test_selectionSort(void) 60 | { 61 | printf("TEST: selectionSort\n"); 62 | int test[] = {34,8,64,51,32,21}; 63 | printf("Befor selectionSort: "); 64 | printArray(test, 6); 65 | selectionSort(test, 6); 66 | printf("After selectionSort: "); 67 | printArray(test, 6); 68 | 69 | int test2[] = {34}; 70 | printf("Befor selectionSort: "); 71 | printArray(test2, 1); 72 | selectionSort(test2, 1); 73 | printf("After selectionSort: "); 74 | printArray(test2, 1); 75 | } 76 | 77 | void 78 | test_insertionSort() 79 | { 80 | printf("TEST: insertionSort\n"); 81 | //int test[] = {34,8,64,51,32,21}; 82 | int test[] = {64,51,34,32,21,8}; 83 | printf("Befor insertionSort: "); 84 | printArray(test, 6); 85 | insertionSort(test, 6); 86 | printf("After insertionSort: "); 87 | printArray(test, 6); 88 | } 89 | 90 | void 91 | test_heapSort() 92 | { 93 | printf("TEST: heapSort\n"); 94 | int test[] = {31,41,59,26,53,58,97}; 95 | printf("Before heapSort: "); 96 | printArray(test, 7); 97 | heapSort(test, 7); 98 | printf("After heapSort: "); 99 | printArray(test, 7); 100 | } 101 | 102 | void 103 | test_mergeSort() 104 | { 105 | printf("TEST: mergeSort\n"); 106 | int test[] = {31,41,59,26,53,58,97}; 107 | printf("Before mergeSort: "); 108 | printArray(test, 7); 109 | mergeSort(test, 7); 110 | printf("After mergeSort: "); 111 | printArray(test, 7); 112 | } 113 | 114 | void 115 | test_quickSort() 116 | { 117 | printf("TEST: quickSort\n"); 118 | int test[] = {8,1,4,9,0,3,5,2,7,6}; 119 | printf("Before quickSort: "); 120 | printArray(test, 10); 121 | quickSort(test, 10); 122 | printf("After quickSort: "); 123 | printArray(test, 10); 124 | } 125 | 126 | void 127 | test_Qselect() 128 | { 129 | printf("TEST: Qselect\n"); 130 | int test[] = {8,1,4,9,0,3,5,2,7,6}; 131 | printf("test array: "); 132 | printArray(test, 10); 133 | printf("select 3rd smallest element (i.e. 2)\n"); 134 | Qselect(test, 3, 0, 9); 135 | assert(test[2] == 2); 136 | } 137 | 138 | void 139 | test_mergeSortNonRecursive() 140 | { 141 | printf("TEST: mergeSort (non-Recursive)\n"); 142 | int test[] = {31,41,59,26,53,58,97}; 143 | printf("Before mergeSort: "); 144 | printArray(test, 7); 145 | mergeSortNonRecursive(test, 7); 146 | printf("After mergeSort: "); 147 | printArray(test, 7); 148 | } 149 | -------------------------------------------------------------------------------- /stack/2-stack-1-array/Makefile: -------------------------------------------------------------------------------- 1 | C_COMPILER=gcc 2 | CFLAGS = -Wall -g 3 | 4 | # Directories 5 | ROOT = ../../ 6 | 7 | SRC_FILES=\ 8 | $(wildcard ./*.c) \ 9 | $(ROOT)utility/utility.c 10 | 11 | INC_DIRS=\ 12 | -I$(ROOT)utility/ 13 | 14 | LIBS=\ 15 | -lm 16 | 17 | OUTPUT_FILE=main 18 | 19 | .PHONY: clean 20 | .PHONY: test 21 | 22 | test: 23 | $(C_COMPILER) $(CFLAGS) $(INC_DIRS) $(LIBS) $(SRC_FILES) -o $(OUTPUT_FILE) 24 | ./$(OUTPUT_FILE) -v 25 | 26 | clean: 27 | rm -rf $(OUTPUT_FILE) 28 | -------------------------------------------------------------------------------- /stack/2-stack-1-array/twoStacks.c: -------------------------------------------------------------------------------- 1 | #include "twoStacks.h" 2 | #include "utility.h" 3 | #include 4 | #include 5 | 6 | struct StackRecord 7 | { 8 | int Capacity; 9 | int TopOfTopStack; 10 | int TopOfBottomStack; 11 | ET *Array; 12 | }; 13 | 14 | int 15 | isEmpty(int stackNo, TwoStacks s) 16 | { 17 | if (stackNo == TOP_STACK) 18 | { 19 | return s->TopOfTopStack == EmptyToS; 20 | } 21 | else 22 | { 23 | return s->TopOfBottomStack == s->Capacity; 24 | } 25 | } 26 | 27 | int 28 | isFull(int stackNo, TwoStacks s) 29 | { 30 | if (stackNo == TOP_STACK) 31 | { 32 | return s->TopOfTopStack == s->TopOfBottomStack - 1; 33 | } 34 | else 35 | { 36 | return s->TopOfBottomStack == s->TopOfTopStack + 1; 37 | } 38 | } 39 | 40 | TwoStacks 41 | createTwoStacks(int maxElements) 42 | { 43 | TwoStacks s = malloc(sizeof(struct StackRecord)); 44 | s->Capacity = maxElements; 45 | s->TopOfTopStack = EmptyToS; 46 | s->TopOfBottomStack = s->Capacity; 47 | s->Array = calloc(s->Capacity, sizeof(ET)); 48 | return s; 49 | } 50 | 51 | void 52 | disposeTwoStacks(TwoStacks s) 53 | { 54 | free(s->Array); 55 | free(s); 56 | } 57 | 58 | void 59 | makeEmpty(int stackNo, TwoStacks s) 60 | { 61 | if (stackNo == TOP_STACK) 62 | { 63 | s->TopOfTopStack = EmptyToS; 64 | } 65 | else 66 | { 67 | s->TopOfBottomStack = s->Capacity; 68 | } 69 | } 70 | 71 | void 72 | push (ET elem, int stackNo, TwoStacks s) 73 | { 74 | if (stackNo == TOP_STACK) 75 | { 76 | if (s->TopOfTopStack + 1 < s->TopOfBottomStack) 77 | { 78 | s->Array[++s->TopOfTopStack] = elem; 79 | } 80 | else 81 | { 82 | fatal("Stack is full!"); 83 | } 84 | } 85 | else 86 | { 87 | if (s->TopOfBottomStack - 1 > s->TopOfTopStack) 88 | { 89 | s->Array[--s->TopOfBottomStack] = elem; 90 | } 91 | else 92 | { 93 | fatal("Stack is full!"); 94 | } 95 | } 96 | } 97 | 98 | ET 99 | top(int stackNo, TwoStacks s) 100 | { 101 | if (stackNo == TOP_STACK) 102 | { 103 | return s->Array[s->TopOfTopStack]; 104 | } 105 | else 106 | { 107 | return s->Array[s->TopOfBottomStack]; 108 | } 109 | } 110 | 111 | void 112 | pop(int stackNo, TwoStacks s) 113 | { 114 | if(stackNo == TOP_STACK && !isEmpty(stackNo, s)) 115 | { 116 | s->TopOfTopStack--; 117 | } 118 | else if (stackNo == BOTTOM_STACK && !isEmpty(stackNo, s)) 119 | { 120 | s->TopOfBottomStack--; 121 | } 122 | else 123 | { 124 | fatal("Error in pop!"); 125 | } 126 | } 127 | 128 | ET 129 | topAndPop(int stackNo, TwoStacks s) 130 | { 131 | if (stackNo == TOP_STACK && !isEmpty(stackNo, s)) 132 | { 133 | return s->Array[s->TopOfTopStack--]; 134 | } 135 | else if (stackNo == BOTTOM_STACK && !isEmpty(stackNo, s)) 136 | { 137 | return s->Array[s->TopOfBottomStack--]; 138 | } 139 | else 140 | { 141 | fatal("Error in topAndPop!"); 142 | } 143 | } 144 | 145 | int 146 | getCapacity(TwoStacks s) 147 | { 148 | return s->Capacity; 149 | } 150 | 151 | ET* 152 | getArray(TwoStacks s) 153 | { 154 | return s->Array; 155 | } 156 | 157 | TwoStacks 158 | initializeTwoStacks(int *arrayTop, 159 | int lengthTop, 160 | int *arrayBottom, 161 | int lengthBottom, 162 | int distanceBetweenTwoStacks) 163 | { 164 | TwoStacks s = createTwoStacks(lengthTop + lengthBottom + distanceBetweenTwoStacks); 165 | int i; 166 | for(i = 0; i < lengthTop; i++) 167 | { 168 | push(arrayTop[i], TOP_STACK, s); 169 | } 170 | for(i = 0; i < lengthBottom; i++) 171 | { 172 | push(arrayBottom[i], BOTTOM_STACK, s); 173 | } 174 | return s; 175 | } 176 | 177 | void 178 | printTwoStacks(TwoStacks s) 179 | { 180 | ET* arrayS = getArray(s); 181 | int i; 182 | for(i = 0; i < s->Capacity; i++) 183 | { 184 | printf("|%d", arrayS[i]); 185 | if (i == s->TopOfTopStack && i+1 != s->TopOfBottomStack) 186 | { 187 | printf("|"); 188 | } 189 | else if (i == s->TopOfTopStack && i + 1 == s->TopOfBottomStack) 190 | { 191 | printf("|"); 192 | } 193 | else if (i + 1 == s->TopOfBottomStack) 194 | { 195 | printf("|"); 196 | } 197 | else if (i + 1 == s->Capacity) 198 | { 199 | printf("|"); 200 | } 201 | } 202 | printf("\n"); 203 | } 204 | -------------------------------------------------------------------------------- /stack/2-stack-1-array/twoStacks.h: -------------------------------------------------------------------------------- 1 | /* 2 | * MAW 3.21 Write routines to implement two stacks using only 3 | * one array. Your stack routines should not declare an overflow 4 | * unless every slot in the array is used. 5 | * 6 | * ==== <--- top stack 7 | * | | | 8 | * ---- V 9 | * | | 10 | * ---- ^ 11 | * | | | 12 | * ==== <--- bottom stack 13 | */ 14 | #ifndef _TWO_STACKS_H 15 | #define _TWO_STACKS_H 16 | 17 | // stack that starts at the top and grows towards the bottom 18 | #define TOP_STACK 1 19 | // stack that starts at the bottom and grows towards the top 20 | #define BOTTOM_STACK 0 21 | #define EmptyToS (-1) 22 | 23 | /* ET shorts for "ElementType" 24 | */ 25 | typedef int ET; 26 | 27 | struct StackRecord; 28 | typedef struct StackRecord* TwoStacks; 29 | 30 | /* Check if the given stack is empty 31 | */ 32 | int isEmpty(int, TwoStacks); 33 | 34 | /* Check if the given stack is full 35 | */ 36 | int isFull(int, TwoStacks); 37 | 38 | /* Creat an array that contains two empty stacks 39 | */ 40 | TwoStacks createTwoStacks(int); 41 | 42 | /* Delete the array that contains two stacks 43 | */ 44 | void disposeTwoStacks(TwoStacks); 45 | 46 | /* Make the given stack empty 47 | */ 48 | void makeEmpty(int, TwoStacks); 49 | 50 | /* Push an element onto the given stack 51 | */ 52 | void push (ET, int, TwoStacks); 53 | 54 | /* Check the top element of the given stack 55 | */ 56 | ET top(int, TwoStacks); 57 | 58 | /* Pop the top element out of the given stack 59 | */ 60 | void pop(int, TwoStacks); 61 | 62 | /* Check the top element and pop it out of stack 63 | */ 64 | ET topAndPop(int, TwoStacks); 65 | 66 | /* Return the capacity of a TwoStacks structure 67 | */ 68 | int getCapacity(TwoStacks); 69 | 70 | /* Return the Array of a TwoStacks structure 71 | */ 72 | ET* getArray(TwoStacks); 73 | 74 | /* initialize an array containing two stacks from the given two array 75 | */ 76 | TwoStacks initializeTwoStacks(int*, int, int*, int, int); 77 | 78 | /* print out the array with two stacks with the following format: 79 | * |elem|elem||elem|elem| 80 | */ 81 | void printTwoStacks(TwoStacks); 82 | 83 | #endif 84 | 85 | 86 | -------------------------------------------------------------------------------- /stack/2-stack-1-array/twoStacksTestMain.c: -------------------------------------------------------------------------------- 1 | #include "twoStacks.h" 2 | #include "utility.h" 3 | #include 4 | #include 5 | #include 6 | 7 | void test_initalizeTwoStacks(); 8 | void test_push(); 9 | void test_top(); 10 | void test_pop(); 11 | void test_topAndPop(); 12 | 13 | int 14 | main(int argc, char** argv) 15 | { 16 | printf("/////////////////////////////////\n"); 17 | printf("// TWO STACKS IN ONE ARRAY TEST\n"); 18 | printf("/////////////////////////////////\n\n"); 19 | test_initalizeTwoStacks(); printf("\n"); 20 | test_push(); printf("\n"); 21 | test_top(); printf("\n"); 22 | test_pop(); printf("\n"); 23 | test_topAndPop(); printf("\n"); 24 | exit(0); 25 | } 26 | 27 | void 28 | test_initalizeTwoStacks() 29 | { 30 | printf("TEST: initializeTwoStacks\n"); 31 | 32 | ET test_Q1[3] = {1,2,3}; 33 | ET test_Q2[4] = {78,99,85,40}; 34 | TwoStacks Q1 = initializeTwoStacks(test_Q1, 3, test_Q2, 4, 4); 35 | printTwoStacks(Q1); 36 | disposeTwoStacks(Q1); 37 | } 38 | 39 | void 40 | test_push() 41 | { 42 | printf("TEST: push\n"); 43 | ET elem1 = 14; 44 | ET elem2 = 30; 45 | ET elem3 = 20; 46 | ET test_Q1[3] = {1,2,3}; 47 | ET test_Q2[4] = {78,99,85,40}; 48 | TwoStacks Q1 = initializeTwoStacks(test_Q1, 3, test_Q2, 4, 4); 49 | printTwoStacks(Q1); 50 | printf("Push elem1: %d to TOP_STACK: Q1\n", elem1); 51 | push(elem1, TOP_STACK, Q1); 52 | printTwoStacks(Q1); 53 | printf("Push elem1: %d to BOTTOM_STACK: Q2\n", elem1); 54 | push(elem1, BOTTOM_STACK, Q1); 55 | printf("Push elem2: %d to BOTTOM_STACK: Q2\n", elem2); 56 | push(elem2, BOTTOM_STACK, Q1); 57 | printTwoStacks(Q1); 58 | printf("Push elem3: %d to TOP_STACK: Q1\n", elem2); 59 | push(elem3, TOP_STACK, Q1); 60 | printTwoStacks(Q1); 61 | /* printf("Push elem1: %d to TOP_STACK: Q1\n", elem1); */ 62 | /* push(elem1, TOP_STACK, Q1); */ 63 | /* printTwoStacks(Q1); */ 64 | disposeTwoStacks(Q1); 65 | } 66 | 67 | void 68 | test_top() 69 | { 70 | printf("TEST: top\n"); 71 | ET test_Q1[3] = {1,2,3}; 72 | ET test_Q2[4] = {78,99,85,40}; 73 | TwoStacks Q1 = initializeTwoStacks(test_Q1, 3, test_Q2, 4, 4); 74 | printTwoStacks(Q1); 75 | printf("Top element of TOP_STACK Q1: %d\n", top(TOP_STACK, Q1)); 76 | printf("Top element of BOTTOM_STACK Q2: %d\n", top(BOTTOM_STACK, Q1)); 77 | disposeTwoStacks(Q1); 78 | } 79 | 80 | void 81 | test_pop() 82 | { 83 | printf("TEST: pop\n"); 84 | ET test_Q1[3] = {1,2,3}; 85 | ET test_Q2[4] = {78,99,85,40}; 86 | TwoStacks Q1 = initializeTwoStacks(test_Q1, 3, test_Q2, 4, 4); 87 | printTwoStacks(Q1); 88 | printf("Remove the top element of TOP_STACK Q1\n"); 89 | pop(TOP_STACK, Q1); 90 | printTwoStacks(Q1); 91 | disposeTwoStacks(Q1); 92 | } 93 | 94 | void 95 | test_topAndPop() 96 | { 97 | printf("TEST: topAndPop\n"); 98 | ET test_Q1[3] = {1,2,3}; 99 | ET test_Q2[4] = {78,99,85,40}; 100 | TwoStacks Q1 = initializeTwoStacks(test_Q1, 3, test_Q2, 4, 4); 101 | printTwoStacks(Q1); 102 | printf("Top and pop the TOP_STACK Q1 and the element is: %d\n", topAndPop(TOP_STACK, Q1)); 103 | printTwoStacks(Q1); 104 | disposeTwoStacks(Q1); 105 | } 106 | -------------------------------------------------------------------------------- /stack/3-22/Makefile: -------------------------------------------------------------------------------- 1 | C_COMPILER=gcc 2 | CFLAGS = -Wall -g 3 | 4 | # Directories 5 | ROOT = ../../ 6 | 7 | SRC_FILES=\ 8 | $(wildcard ./*.c) \ 9 | $(ROOT)utility/utility.c 10 | 11 | INC_DIRS=\ 12 | -I$(ROOT)utility/ 13 | 14 | LIBS=\ 15 | -lm 16 | 17 | OUTPUT_FILE=main 18 | 19 | .PHONY: clean 20 | .PHONY: test 21 | 22 | test: 23 | $(C_COMPILER) $(CFLAGS) $(INC_DIRS) $(LIBS) $(SRC_FILES) -o $(OUTPUT_FILE) 24 | ./$(OUTPUT_FILE) -v 25 | 26 | clean: 27 | rm -rf $(OUTPUT_FILE) 28 | -------------------------------------------------------------------------------- /stack/3-22/stack322.c: -------------------------------------------------------------------------------- 1 | #include "stack322.h" 2 | #include "utility.h" 3 | #include 4 | #include 5 | 6 | static void resizeStack(Stack); 7 | static int isEmptyArrayMin(Stack); 8 | static ET topArrayMin(Stack); 9 | static void popArrayMin(Stack); 10 | static void pushArrayMin(ET, Stack); 11 | 12 | struct StackRecord 13 | { 14 | int Capacity; 15 | int TopOfStack; 16 | int TopOfStackMin; 17 | ET *Array; 18 | ET *ArrayMin; 19 | }; 20 | 21 | int 22 | isEmptyArrayMin(Stack S) 23 | { 24 | return S->TopOfStackMin == EmptyToS; 25 | } 26 | 27 | int 28 | isEmpty(Stack S) 29 | { 30 | return S->TopOfStack == EmptyToS; 31 | } 32 | 33 | int 34 | isFull(Stack S) 35 | { 36 | return S->TopOfStack == S->Capacity - 1; 37 | } 38 | 39 | Stack 40 | createStack(int maxElements) 41 | { 42 | Stack s = malloc(sizeof(struct StackRecord)); 43 | s->Capacity = maxElements; 44 | s->TopOfStack = EmptyToS; 45 | s->TopOfStackMin = EmptyToS; 46 | s->Array = calloc(s->Capacity, sizeof(ET)); 47 | s->ArrayMin = calloc(MinStackSize, sizeof(ET)); 48 | return s; 49 | } 50 | 51 | void 52 | disposeStack(Stack S) 53 | { 54 | if (S != NULL) 55 | { 56 | free(S->Array); 57 | free(S->ArrayMin); 58 | free(S); 59 | } 60 | } 61 | 62 | void 63 | makeEmpty(Stack S) 64 | { 65 | S->TopOfStack = EmptyToS; 66 | S->TopOfStackMin = EmptyToS; 67 | } 68 | 69 | static void 70 | pushArrayMin(ET elem, Stack S) 71 | { 72 | S->ArrayMin[++S->TopOfStackMin] = elem; 73 | } 74 | 75 | void 76 | push (ET elem, Stack S) 77 | { 78 | if (isFull(S)) 79 | { 80 | resizeStack(S); 81 | } 82 | if (isEmptyArrayMin(S)) 83 | { 84 | pushArrayMin(elem, S); 85 | } 86 | if (elem < topArrayMin(S)) 87 | { 88 | popArrayMin(S); 89 | pushArrayMin(elem, S); 90 | } 91 | S->Array[++S->TopOfStack] = elem; 92 | } 93 | 94 | static ET 95 | topArrayMin(Stack S) 96 | { 97 | if (!isEmptyArrayMin(S)) 98 | return S->ArrayMin[S->TopOfStackMin]; 99 | fatal("Empty stack!"); 100 | return 0; 101 | } 102 | 103 | ET 104 | top(Stack S) 105 | { 106 | if (!isEmpty(S)) 107 | return S->Array[S->TopOfStack]; 108 | fatal("Empty stack!"); 109 | return 0; 110 | } 111 | 112 | static void 113 | popArrayMin(Stack S) 114 | { 115 | S->TopOfStackMin--; 116 | } 117 | 118 | void 119 | pop(Stack S) 120 | { 121 | if (top(S) == topArrayMin(S)) 122 | popArrayMin(S); 123 | S->TopOfStack--; 124 | } 125 | 126 | ET 127 | topAndPop(Stack S) 128 | { 129 | if (top(S) == topArrayMin(S)) 130 | popArrayMin(S); 131 | return S->Array[S->TopOfStack--]; 132 | } 133 | 134 | ET 135 | findMin(Stack S) 136 | { 137 | return S->ArrayMin[S->TopOfStackMin]; 138 | } 139 | 140 | Stack 141 | initializeStack(int array[], int length) 142 | { 143 | Stack s = createStack(length); 144 | int i; 145 | for ( i = 0; i < length; i++) 146 | { 147 | push(array[i], s); 148 | } 149 | s->TopOfStack = s->Capacity - 1; 150 | return s; 151 | } 152 | 153 | void 154 | printStack(Stack S) 155 | { 156 | ET* arrayS = S->Array; 157 | ET* arrayMin = S->ArrayMin; 158 | int i; 159 | for (i = 0; i <= S->TopOfStack; i++) 160 | { 161 | printf("%s%d%s", 162 | "|", 163 | arrayS[i], 164 | (i == S->TopOfStack) ? ("| <-topOfStack") : ("")); 165 | } 166 | printf("\n"); 167 | for (i = 0; i <= S->TopOfStackMin; i++) 168 | { 169 | printf("%s%d%s", 170 | "|", 171 | arrayMin[i], 172 | (i == S->TopOfStackMin) ? ("| <-topOfStackMin") : ("")); 173 | } 174 | printf("\n"); 175 | } 176 | 177 | static void 178 | resizeStackArray(ET** array, int length) 179 | { 180 | *array = realloc(*array, sizeof(ET) * length); 181 | } 182 | 183 | static void 184 | resizeStack(Stack S) 185 | { 186 | S->Capacity *= 2; 187 | resizeStackArray(&(S->Array), S->Capacity); 188 | } 189 | -------------------------------------------------------------------------------- /stack/3-22/stack322.h: -------------------------------------------------------------------------------- 1 | /* MAW 3.22.a Propose a data structure that supports 2 | * the stack Push and pop operations and a third operation 3 | * FindMin, which returns the smallest element in the data structure, 4 | * all in O(1) worst case time. 5 | */ 6 | #ifndef _STACK_322_H 7 | #define _STACK_322_H 8 | 9 | /* ET shorts for "ElementType" 10 | */ 11 | typedef int ET; 12 | 13 | #define EmptyToS (-1) 14 | #define MinStackSize (1) 15 | 16 | struct StackRecord; 17 | typedef struct StackRecord* Stack; 18 | 19 | /* Check if stack is empty 20 | */ 21 | int isEmpty(Stack S); 22 | 23 | /* Check if stack is full 24 | */ 25 | int isFull(Stack S); 26 | 27 | /* Creat a stack 28 | */ 29 | Stack createStack(int maxElements); 30 | 31 | /* Delete the stack 32 | */ 33 | void disposeStack(Stack S); 34 | 35 | /* Make the stack empty 36 | */ 37 | void makeEmpty(Stack S); 38 | 39 | /* Push an element on the stack 40 | */ 41 | void push (ET elem, Stack S); 42 | 43 | /* Check the top element of the stack 44 | */ 45 | ET top(Stack S); 46 | 47 | /* Pop the top element out of the stack 48 | */ 49 | void pop(Stack S); 50 | 51 | /* Check the top element and pop it out of stack 52 | */ 53 | ET topAndPop(Stack S); 54 | 55 | /* Find the minimum element in the stack 56 | */ 57 | ET findMin(Stack S); 58 | 59 | #endif 60 | 61 | /* initialize the stack from the given array 62 | * with the array[0] being the bottom of the stack 63 | */ 64 | Stack initializeStack(int array[], int length); 65 | 66 | /* print out the stack with the following format: 67 | * |elem|elem|elem| <-top 68 | */ 69 | void printStack(Stack S); 70 | -------------------------------------------------------------------------------- /stack/3-22/stack322TestMain.c: -------------------------------------------------------------------------------- 1 | #include "stack322.h" 2 | #include "utility.h" 3 | #include 4 | #include 5 | #include 6 | 7 | void test_initalizeStack(); 8 | void test_push(); 9 | void test_top(); 10 | void test_pop(); 11 | void test_topAndPop(); 12 | void test_findMin(); 13 | 14 | int main(int argc, char** argv) 15 | { 16 | printf("///////////////////////\n"); 17 | printf("// STACK 3-22 TEST\n"); 18 | printf("///////////////////////\n\n"); 19 | test_initalizeStack(); printf("\n"); 20 | test_push(); printf("\n"); 21 | test_top(); printf("\n"); 22 | test_pop(); printf("\n"); 23 | test_topAndPop(); printf("\n"); 24 | test_findMin(); printf("\n"); 25 | exit(0); 26 | } 27 | 28 | void 29 | test_initalizeStack() 30 | { 31 | printf("TEST: initializeStack\n"); 32 | 33 | ET test_Q1[3] = {1,2,3}; 34 | Stack Q1 = initializeStack(test_Q1, 3); 35 | printStack(Q1); 36 | disposeStack(Q1); 37 | } 38 | 39 | void 40 | test_push() 41 | { 42 | printf("TEST: push\n"); 43 | 44 | ET test_Q1[1] = {1}; 45 | Stack Q1 = initializeStack(test_Q1, 1); 46 | printStack(Q1); 47 | push(2, Q1); 48 | printf("After push 2:\n"); 49 | printStack(Q1); 50 | disposeStack(Q1); 51 | } 52 | 53 | void 54 | test_top() 55 | { 56 | printf("TEST: top\n"); 57 | ET test_Q1[1] = {1}; 58 | Stack Q1 = initializeStack(test_Q1, 1); 59 | printStack(Q1); 60 | printf("Top element of Stack: %d\n", top(Q1)); 61 | disposeStack(Q1); 62 | } 63 | 64 | void 65 | test_pop() 66 | { 67 | printf("TEST: pop\n"); 68 | ET test_Q1[3] = {1,2,3}; 69 | Stack Q1 = initializeStack(test_Q1, 3); 70 | printStack(Q1); 71 | printf("After pop the element:\n"); 72 | pop(Q1); 73 | printStack(Q1); 74 | push(2, Q1); 75 | printf("After push 2:\n"); 76 | printStack(Q1); 77 | disposeStack(Q1); 78 | } 79 | 80 | void 81 | test_topAndPop() 82 | { 83 | printf("TEST: topAndPop\n"); 84 | ET test_Q1[3] = {1,2,3}; 85 | Stack Q1 = initializeStack(test_Q1, 3); 86 | printStack(Q1); 87 | printf("Pop the element: %d\n", topAndPop(Q1)); 88 | printf("After pop the element:\n"); 89 | printStack(Q1); 90 | disposeStack(Q1); 91 | } 92 | 93 | void 94 | test_findMin() 95 | { 96 | printf("TEST: findMin\n"); 97 | ET test_Q1[4] = {1,10,1,100}; 98 | Stack Q1 = initializeStack(test_Q1, 4); 99 | printStack(Q1); 100 | printf("The smallest element in the stack: %d\n", findMin(Q1)); 101 | disposeStack(Q1); 102 | } 103 | -------------------------------------------------------------------------------- /stack/3-stack-1-array/Makefile: -------------------------------------------------------------------------------- 1 | C_COMPILER=gcc 2 | CFLAGS = -Wall -g 3 | 4 | # Directories 5 | ROOT = ../../ 6 | 7 | SRC_FILES=\ 8 | $(wildcard ./*.c) \ 9 | $(ROOT)utility/utility.c 10 | 11 | INC_DIRS=\ 12 | -I$(ROOT)utility/ 13 | 14 | LIBS=\ 15 | -lm 16 | 17 | OUTPUT_FILE=main 18 | 19 | .PHONY: clean 20 | .PHONY: test 21 | 22 | test: 23 | $(C_COMPILER) $(CFLAGS) $(INC_DIRS) $(LIBS) $(SRC_FILES) -o $(OUTPUT_FILE) 24 | ./$(OUTPUT_FILE) -v 25 | 26 | clean: 27 | rm -rf $(OUTPUT_FILE) 28 | -------------------------------------------------------------------------------- /stack/3-stack-1-array/threeStacks.h: -------------------------------------------------------------------------------- 1 | /* 2 | * MAW 3.23 Show how to implement three stacks in one array. 3 | * 4 | * ==== <--- top stack 5 | * | | | 6 | * ---- V 7 | * | | 8 | * ==== <--- middle stack 9 | * | | | 10 | * ---- V 11 | * | | 12 | * ---- ^ 13 | * | | | 14 | * ==== <--- bottom stack 15 | */ 16 | #ifndef _THREE_STACKS_H 17 | #define _THREE_STACKS_H 18 | 19 | // stack that starts at the top and grows towards the bottom 20 | #define TOP_STACK 1 21 | // stack that starts at the bottom and grows towards the top 22 | #define BOTTOM_STACK 0 23 | // stack that resides in the middle and grows towards the bottom 24 | #define MIDDLE_STACK 2 25 | #define EmptyToS (-1) 26 | 27 | /* ET shorts for "ElementType" 28 | */ 29 | typedef int ET; 30 | 31 | struct StackRecord; 32 | typedef struct StackRecord* ThreeStacks; 33 | 34 | /* Check if the given stack is empty 35 | */ 36 | int isEmpty(int, ThreeStacks); 37 | 38 | /* Check if the given stack is full 39 | */ 40 | int isFull(int, ThreeStacks); 41 | 42 | /* Creat an array that contains two empty stacks 43 | */ 44 | ThreeStacks createThreeStacks(int); 45 | 46 | /* Delete the array that contains two stacks 47 | */ 48 | void disposeThreeStacks(ThreeStacks); 49 | 50 | /* Make the given stack empty 51 | */ 52 | void makeEmpty(int, ThreeStacks); 53 | 54 | /* Push an element onto the given stack 55 | */ 56 | void push (ET, int, ThreeStacks); 57 | 58 | /* Check the top element of the given stack 59 | */ 60 | ET top(int, ThreeStacks); 61 | 62 | /* Pop the top element out of the given stack 63 | */ 64 | void pop(int, ThreeStacks); 65 | 66 | /* Check the top element and pop it out of stack 67 | */ 68 | ET topAndPop(int, ThreeStacks); 69 | 70 | /* Return the capacity of a ThreeStacks structure 71 | */ 72 | int getCapacity(ThreeStacks); 73 | 74 | /* Return the Array of a ThreeStacks structure 75 | */ 76 | ET* getArray(ThreeStacks); 77 | 78 | /* initialize an array containing two stacks from the given two array 79 | */ 80 | ThreeStacks initializeThreeStacks(int*, int, int*, int, int*, int, int, int); 81 | 82 | /* print out the array with two stacks with the following format: 83 | * |elem|elem||elem|elem| 84 | */ 85 | void printThreeStacks(ThreeStacks); 86 | 87 | #endif 88 | 89 | 90 | -------------------------------------------------------------------------------- /stack/3-stack-1-array/threeStacksTestMain.c: -------------------------------------------------------------------------------- 1 | #include "threeStacks.h" 2 | #include "utility.h" 3 | #include 4 | #include 5 | #include 6 | 7 | void test_createThreeStacks(); 8 | void test_initalizeThreeStacks(); 9 | void test_push(); 10 | void test_top(); 11 | void test_pop(); 12 | void test_topAndPop(); 13 | 14 | int 15 | main(int argc, char** argv) 16 | { 17 | printf("/////////////////////////////////\n"); 18 | printf("// THREE STACKS IN ONE ARRAY TEST\n"); 19 | printf("/////////////////////////////////\n\n"); 20 | test_createThreeStacks(); printf("\n"); 21 | test_initalizeThreeStacks(); printf("\n"); 22 | test_push(); printf("\n"); 23 | test_top(); printf("\n"); 24 | test_pop(); printf("\n"); 25 | test_topAndPop(); printf("\n"); 26 | exit(0); 27 | } 28 | 29 | void 30 | test_createThreeStacks() 31 | { 32 | printf("TEST: createThreeStacks\n"); 33 | ThreeStacks Q1 = createThreeStacks(10); 34 | printThreeStacks(Q1); 35 | disposeThreeStacks(Q1); 36 | } 37 | 38 | void 39 | test_initalizeThreeStacks() 40 | { 41 | printf("TEST: initializeThreeStacks\n"); 42 | 43 | ET test_Q1[3] = {1,2,3}; 44 | ET test_Q2[3] = {5,4,3}; 45 | ET test_Q3[2] = {1,2}; 46 | ThreeStacks Q1 = initializeThreeStacks(test_Q1, 3, test_Q2, 3, test_Q3, 2, 1, 1); 47 | printThreeStacks(Q1); 48 | disposeThreeStacks(Q1); 49 | } 50 | 51 | void 52 | test_push() 53 | { 54 | printf("TEST: push\n"); 55 | ET test_Q1[3] = {1,2,3}; 56 | ET test_Q2[3] = {5,4,3}; 57 | ET test_Q3[2] = {1,2}; 58 | ThreeStacks Q1 = initializeThreeStacks(test_Q1, 3, test_Q2, 3, test_Q3, 2, 1, 1); 59 | printThreeStacks(Q1); 60 | ET elem1 = 99; 61 | ET elem2 = 10; 62 | printf("Push: %d to bottom stack\n", elem1); 63 | push(elem1, BOTTOM_STACK, Q1); 64 | printThreeStacks(Q1); 65 | printf("Push: %d to top stack\n", elem2); 66 | push(elem2, TOP_STACK, Q1); 67 | printThreeStacks(Q1); 68 | /* printf("Push: %d to top stack\n", elem2); */ 69 | /* push(elem2, TOP_STACK, Q1); */ 70 | disposeThreeStacks(Q1); 71 | } 72 | 73 | void 74 | test_top() 75 | { 76 | printf("TEST: top\n"); 77 | ET test_Q1[3] = {1,2,3}; 78 | ET test_Q2[3] = {5,4,3}; 79 | ET test_Q3[2] = {1,2}; 80 | ThreeStacks Q1 = initializeThreeStacks(test_Q1, 3, test_Q2, 3, test_Q3, 2, 1, 1); 81 | printThreeStacks(Q1); 82 | printf("Top element of TOP_STACK: %d\n", top(TOP_STACK, Q1)); 83 | printf("Top element of BOTTOM_STACK: %d\n", top(BOTTOM_STACK, Q1)); 84 | printf("Top element of MIDDLE_STACK: %d\n", top(MIDDLE_STACK, Q1)); 85 | disposeThreeStacks(Q1); 86 | } 87 | 88 | void 89 | test_pop() 90 | { 91 | printf("TEST: pop\n"); 92 | ET test_Q1[3] = {1,2,3}; 93 | ET test_Q2[3] = {5,4,3}; 94 | ET test_Q3[2] = {1,2}; 95 | ThreeStacks Q1 = initializeThreeStacks(test_Q1, 3, test_Q2, 3, test_Q3, 2, 1, 1); 96 | printThreeStacks(Q1); 97 | printf("Remove the top element of TOP_STACK Q1\n"); 98 | pop(TOP_STACK, Q1); 99 | printThreeStacks(Q1); 100 | disposeThreeStacks(Q1); 101 | } 102 | 103 | void 104 | test_topAndPop() 105 | { 106 | printf("TEST: topAndPop\n"); 107 | ET test_Q1[3] = {1,2,3}; 108 | ET test_Q2[3] = {5,4,3}; 109 | ET test_Q3[2] = {1,2}; 110 | ThreeStacks Q1 = initializeThreeStacks(test_Q1, 3, test_Q2, 3, test_Q3, 2, 1, 1); 111 | printThreeStacks(Q1); 112 | printf("Top and pop the TOP_STACK Q1 and the element is: %d\n", topAndPop(TOP_STACK, Q1)); 113 | printThreeStacks(Q1); 114 | disposeThreeStacks(Q1); 115 | } 116 | -------------------------------------------------------------------------------- /stack/balance-symbol/Makefile: -------------------------------------------------------------------------------- 1 | C_COMPILER=gcc 2 | CFLAGS = -Wall -g 3 | 4 | # Directories 5 | ROOT = ../../ 6 | 7 | SRC_FILES=\ 8 | $(wildcard ./*.c) \ 9 | $(ROOT)utility/utility.c 10 | 11 | INC_DIRS=\ 12 | -I$(ROOT)utility/ \ 13 | 14 | LIBS=\ 15 | -lm 16 | 17 | OUTPUT_FILE=main 18 | 19 | .PHONY: clean 20 | .PHONY: test 21 | 22 | test: 23 | $(C_COMPILER) $(CFLAGS) $(INC_DIRS) $(LIBS) $(SRC_FILES) -o $(OUTPUT_FILE) 24 | 25 | clean: 26 | rm -rf $(OUTPUT_FILE) 27 | -------------------------------------------------------------------------------- /stack/balance-symbol/stack2.c: -------------------------------------------------------------------------------- 1 | #include "stack2.h" 2 | #include "utility.h" 3 | #include 4 | #include 5 | #include 6 | 7 | struct Node 8 | { 9 | char* Symbol; 10 | int LineNo; 11 | PtrToNode Next; 12 | }; 13 | 14 | int 15 | isEmpty(Stack S) 16 | { 17 | return S->Next == NULL; 18 | } 19 | 20 | Stack 21 | createStack() 22 | { 23 | PtrToNode tmp = malloc(sizeof(struct Node)); 24 | tmp->Next = NULL; 25 | return tmp; 26 | } 27 | 28 | void 29 | disposeStack(Stack S) 30 | { 31 | makeEmpty(S); 32 | free(S); 33 | } 34 | 35 | void 36 | makeEmpty(Stack S) 37 | { 38 | while(!isEmpty(S)) 39 | { 40 | pop(S); 41 | } 42 | } 43 | 44 | void 45 | push (char* symbol, int lineNo, Stack S) 46 | { 47 | PtrToNode tmp = malloc(sizeof(struct Node)); 48 | char* dupSymbol = malloc(strlen(symbol) * sizeof(char)); 49 | strcpy(dupSymbol, symbol); 50 | tmp->Symbol = dupSymbol; 51 | tmp->LineNo = lineNo; 52 | tmp->Next = S->Next; 53 | S->Next = tmp; 54 | } 55 | 56 | char* 57 | topSymbol(Stack S) 58 | { 59 | return S->Next->Symbol; 60 | } 61 | 62 | int 63 | topLineNo(Stack S) 64 | { 65 | return S->Next->LineNo; 66 | } 67 | 68 | void 69 | pop(Stack S) 70 | { 71 | PtrToNode tmp = S->Next; 72 | S->Next = tmp->Next; 73 | free(tmp); 74 | } 75 | 76 | static void 77 | printStackHelper(Stack S) 78 | { 79 | if (S == NULL) 80 | return; 81 | else 82 | printStackHelper(S->Next); 83 | printf("[ '%s' %d %s", 84 | S->Symbol, 85 | S->LineNo, 86 | "]"); 87 | } 88 | 89 | void 90 | printStack(Stack S) 91 | { 92 | PtrToNode tmp = S->Next; 93 | printStackHelper(tmp); 94 | printf("<-top"); 95 | printf("\n"); 96 | } 97 | 98 | -------------------------------------------------------------------------------- /stack/balance-symbol/stack2.h: -------------------------------------------------------------------------------- 1 | /* We use a linked list implementation. 2 | * The top of the stack is the first data node. 3 | */ 4 | #ifndef _STACK_H 5 | 6 | struct Node; 7 | typedef struct Node* PtrToNode; 8 | typedef PtrToNode Stack; 9 | 10 | /* Check if stack is empty 11 | */ 12 | int isEmpty(Stack S); 13 | 14 | /* Creat a stack 15 | */ 16 | Stack createStack(void); 17 | 18 | /* Delete the stack 19 | */ 20 | void disposeStack(Stack S); 21 | 22 | /* Make the stack empty 23 | */ 24 | void makeEmpty(Stack S); 25 | 26 | /* Push an element on the stack 27 | */ 28 | void push (char* symbol, int lineNo, Stack S); 29 | 30 | /* Check the top element's symbol of the stack 31 | */ 32 | char* topSymbol(Stack S); 33 | 34 | /* Check the top element's line number of the stack 35 | */ 36 | int topLineNo(Stack S); 37 | 38 | /* Pop the top element out of the stack 39 | */ 40 | void pop(Stack S); 41 | 42 | #endif 43 | 44 | /* print out the stack with the following format: 45 | * |elem|elem|elem| <-top 46 | */ 47 | void printStack(Stack S); 48 | -------------------------------------------------------------------------------- /stack/balance-symbol/test-src-files/README.txt: -------------------------------------------------------------------------------- 1 | This is the README file for /test-src-files 2 | 3 | The various source files contained inside this directory 4 | are for the test input for the balance-symbol program, 5 | which is MAW 3.18. 6 | -------------------------------------------------------------------------------- /stack/balance-symbol/test-src-files/brackets_correct_01.c: -------------------------------------------------------------------------------- 1 | () 2 | -------------------------------------------------------------------------------- /stack/balance-symbol/test-src-files/brackets_correct_02.c: -------------------------------------------------------------------------------- 1 | (()) 2 | -------------------------------------------------------------------------------- /stack/balance-symbol/test-src-files/brackets_fail_01.c: -------------------------------------------------------------------------------- 1 | ( 2 | -------------------------------------------------------------------------------- /stack/balance-symbol/test-src-files/brackets_fail_02.c: -------------------------------------------------------------------------------- 1 | ) 2 | -------------------------------------------------------------------------------- /stack/balance-symbol/test-src-files/brackets_fail_03.c: -------------------------------------------------------------------------------- 1 | ()) 2 | -------------------------------------------------------------------------------- /stack/balance-symbol/test-src-files/brackets_fail_04.c: -------------------------------------------------------------------------------- 1 | (() 2 | -------------------------------------------------------------------------------- /stack/balance-symbol/test-src-files/brackets_fail_05.c: -------------------------------------------------------------------------------- 1 | ( 2 | ( 3 | ) 4 | ) 5 | ) 6 | -------------------------------------------------------------------------------- /stack/balance-symbol/test-src-files/comments_correct_01.c: -------------------------------------------------------------------------------- 1 | /**/ 2 | -------------------------------------------------------------------------------- /stack/balance-symbol/test-src-files/comments_fail_03.c: -------------------------------------------------------------------------------- 1 | /**/*/ 2 | -------------------------------------------------------------------------------- /stack/balance-symbol/test-src-files/convertInputToLowerCase.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | /* lower: convert input to lower case 5 | */ 6 | main() 7 | { 8 | int c; 9 | 10 | while ((c = getchar()) != EOF) 11 | putchar(tolower(c)); 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /stack/balance-symbol/test-src-files/curly_brackets_correct_01.c: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /stack/balance-symbol/test-src-files/curly_brackets_correct_02.c: -------------------------------------------------------------------------------- 1 | {{}} 2 | -------------------------------------------------------------------------------- /stack/balance-symbol/test-src-files/curly_brackets_fail_01.c: -------------------------------------------------------------------------------- 1 | { 2 | -------------------------------------------------------------------------------- /stack/balance-symbol/test-src-files/curly_brackets_fail_02.c: -------------------------------------------------------------------------------- 1 | } 2 | -------------------------------------------------------------------------------- /stack/balance-symbol/test-src-files/curly_brackets_fail_03.c: -------------------------------------------------------------------------------- 1 | {}} 2 | -------------------------------------------------------------------------------- /stack/balance-symbol/test-src-files/curly_brackets_fail_04.c: -------------------------------------------------------------------------------- 1 | {{} 2 | -------------------------------------------------------------------------------- /stack/balance-symbol/test-src-files/curly_brackets_fail_05.c: -------------------------------------------------------------------------------- 1 | { 2 | { 3 | } 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /stack/balance-symbol/test-src-files/square_brackets_correct_01.c: -------------------------------------------------------------------------------- 1 | [] 2 | -------------------------------------------------------------------------------- /stack/balance-symbol/test-src-files/square_brackets_correct_02.c: -------------------------------------------------------------------------------- 1 | [[]] 2 | -------------------------------------------------------------------------------- /stack/balance-symbol/test-src-files/square_brackets_fail_01.c: -------------------------------------------------------------------------------- 1 | [ 2 | -------------------------------------------------------------------------------- /stack/balance-symbol/test-src-files/square_brackets_fail_02.c: -------------------------------------------------------------------------------- 1 | ] 2 | -------------------------------------------------------------------------------- /stack/balance-symbol/test-src-files/square_brackets_fail_03.c: -------------------------------------------------------------------------------- 1 | []] 2 | -------------------------------------------------------------------------------- /stack/balance-symbol/test-src-files/square_brackets_fail_04.c: -------------------------------------------------------------------------------- 1 | [[] 2 | -------------------------------------------------------------------------------- /stack/balance-symbol/test-src-files/square_brackets_fail_05.c: -------------------------------------------------------------------------------- 1 | [ 2 | [ 3 | ] 4 | ] 5 | ] 6 | -------------------------------------------------------------------------------- /stack/generic/Makefile: -------------------------------------------------------------------------------- 1 | C_COMPILER=gcc 2 | CFLAGS = -Wall -g 3 | 4 | # Directories 5 | ROOT = ../../ 6 | 7 | SRC_FILES=\ 8 | $(wildcard ./*.c) \ 9 | $(ROOT)utility/utility.c 10 | 11 | INC_DIRS=\ 12 | -I$(ROOT)utility/ 13 | 14 | LIBS=\ 15 | -lm 16 | 17 | OUTPUT_FILE=main 18 | 19 | .PHONY: clean 20 | .PHONY: test 21 | 22 | test: 23 | $(C_COMPILER) $(CFLAGS) $(INC_DIRS) $(LIBS) $(SRC_FILES) -o $(OUTPUT_FILE) 24 | 25 | clean: 26 | rm -rf $(OUTPUT_FILE) 27 | -------------------------------------------------------------------------------- /stack/generic/postfix.c: -------------------------------------------------------------------------------- 1 | #include "postfix.h" 2 | 3 | /* 4 | * Algorithm: when a number is seen, it is pushed 5 | * onto the stack; when an operator is seen, the 6 | * operator is applied to the two numbers (symbols) 7 | * that are popped from the stack, and the result 8 | * is pushed onto the stack. 9 | * 10 | * Limitation: can handle postfix expression 11 | * with integer only. 12 | */ 13 | ET 14 | evaluate_postfix(char* filename) 15 | { 16 | int maxElements = 20; 17 | FILE *fp; 18 | fp = fopen(filename, "r"); 19 | if (fp == NULL) 20 | { 21 | fprintf(stderr, "can't open %s\n", filename); 22 | exit(1); 23 | } 24 | int c; 25 | int res, a, b; 26 | Stack s = createStack(maxElements); 27 | while((c=getc(fp)) != EOF) 28 | { 29 | /* printf("character c read: "); */ 30 | /* putc(c, stdout); */ 31 | /* printf("\n"); */ 32 | if(isdigit(c)) 33 | { 34 | push(c-'0', s); 35 | } 36 | else 37 | { 38 | switch(c) 39 | { 40 | case '/': 41 | a = topAndPop(s); 42 | b = topAndPop(s); 43 | push(b/a, s); 44 | break; 45 | case '*': 46 | a = topAndPop(s); 47 | b = topAndPop(s); 48 | push(b*a, s); 49 | break; 50 | case '+': 51 | a = topAndPop(s); 52 | b = topAndPop(s); 53 | push(b+a, s); 54 | break; 55 | case '-': 56 | a = topAndPop(s); 57 | b = topAndPop(s); 58 | push(b-a, s); 59 | break; 60 | case ' ': 61 | break; 62 | default: 63 | fprintf(stderr, "Invalid operator in the file\n"); 64 | exit(1); 65 | } 66 | } 67 | } 68 | res = topAndPop(s); 69 | disposeStack(s); 70 | fclose(fp); 71 | return res; 72 | } 73 | -------------------------------------------------------------------------------- /stack/generic/postfix.h: -------------------------------------------------------------------------------- 1 | #include "stack.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | /* 8 | * MAW 3.19 Write a program to evaluate 9 | * a postfix expression. 10 | */ 11 | ET evaluate_postfix(char*); 12 | -------------------------------------------------------------------------------- /stack/generic/stack.c: -------------------------------------------------------------------------------- 1 | #include "stack.h" 2 | #include "utility.h" 3 | #include 4 | #include 5 | 6 | #define EmptyToS (-1) 7 | #define MinStackSize (5) 8 | 9 | static void resizeStack(Stack); 10 | 11 | struct StackRecord 12 | { 13 | int Capacity; 14 | int TopOfStack; 15 | ET *Array; 16 | }; 17 | 18 | /* Check if Stack is empty 19 | */ 20 | int isEmpty(Stack S) 21 | { 22 | return S->TopOfStack == EmptyToS; 23 | } 24 | 25 | /* Check if Stack is full 26 | */ 27 | int isFull(Stack S) 28 | { 29 | return S->TopOfStack == S->Capacity - 1; 30 | } 31 | 32 | /* Creat a Stack 33 | */ 34 | Stack createStack(int maxElements) 35 | { 36 | Stack s = malloc(sizeof(struct StackRecord)); 37 | s->Capacity = maxElements; 38 | s->TopOfStack = EmptyToS; 39 | s->Array = calloc(s->Capacity, sizeof(ET)); 40 | return s; 41 | } 42 | 43 | /* Delete the Stack 44 | */ 45 | void 46 | disposeStack(Stack S) 47 | { 48 | if (S != NULL) 49 | { 50 | free(S->Array); 51 | free(S); 52 | } 53 | } 54 | 55 | /* Make the Stack empty 56 | */ 57 | void 58 | makeEmpty(Stack S) 59 | { 60 | S->TopOfStack = EmptyToS; 61 | } 62 | 63 | /* Push an element on the Stack 64 | */ 65 | void 66 | push (ET elem, Stack S) 67 | { 68 | if (isFull(S)) 69 | { 70 | resizeStack(S); 71 | } 72 | S->Array[++S->TopOfStack] = elem; 73 | } 74 | 75 | /* Check the top element of the Stack 76 | */ 77 | ET 78 | top(Stack S) 79 | { 80 | return S->Array[S->TopOfStack]; 81 | } 82 | 83 | /* Pop the top element out of the Stack 84 | */ 85 | void 86 | pop(Stack S) 87 | { 88 | S->TopOfStack--; 89 | } 90 | 91 | /* Check the top element and pop it out of Stack 92 | */ 93 | ET 94 | topAndPop(Stack S) 95 | { 96 | return S->Array[S->TopOfStack--]; 97 | } 98 | 99 | /* initialize the Stack from the given array 100 | * with the array[0] being the bottom of the Stack 101 | */ 102 | Stack initializeStack(int array[], int length) 103 | { 104 | Stack s = malloc(sizeof(struct StackRecord)); 105 | s->Capacity = length; 106 | s->Array = calloc(length, sizeof(int)); 107 | int i; 108 | for ( i = 0; i < length; i++) 109 | { 110 | s->Array[i] = array[i]; 111 | } 112 | s->TopOfStack = s->Capacity - 1; 113 | return s; 114 | } 115 | 116 | void 117 | printStack(Stack S) 118 | { 119 | ET* arrayS = S->Array; 120 | int i; 121 | for (i = 0; i <= S->TopOfStack; i++) 122 | { 123 | printf("%s%d%s", 124 | "|", 125 | arrayS[i], 126 | (i == S->TopOfStack) ? ("| <-top") : ("")); 127 | } 128 | printf("\n"); 129 | } 130 | 131 | static void 132 | resizeStackArray(ET** array, int length) 133 | { 134 | *array = realloc(*array, sizeof(ET) * length); 135 | } 136 | 137 | static void 138 | resizeStack(Stack S) 139 | { 140 | S->Capacity *= 2; 141 | resizeStackArray(&(S->Array), S->Capacity); 142 | } 143 | -------------------------------------------------------------------------------- /stack/generic/stack.h: -------------------------------------------------------------------------------- 1 | /* We use array implementation of stacks 2 | */ 3 | #ifndef _STACK_H 4 | #define _STACK_H 5 | 6 | /* ET shorts for "ElementType" 7 | */ 8 | typedef int ET; 9 | 10 | struct StackRecord; 11 | typedef struct StackRecord* Stack; 12 | 13 | /* Check if stack is empty 14 | */ 15 | int isEmpty(Stack S); 16 | 17 | /* Check if stack is full 18 | */ 19 | int isFull(Stack S); 20 | 21 | /* Creat a stack 22 | */ 23 | Stack createStack(int maxElements); 24 | 25 | /* Delete the stack 26 | */ 27 | void disposeStack(Stack S); 28 | 29 | /* Make the stack empty 30 | */ 31 | void makeEmpty(Stack S); 32 | 33 | /* Push an element on the stack 34 | */ 35 | void push (ET elem, Stack S); 36 | 37 | /* Check the top element of the stack 38 | */ 39 | ET top(Stack S); 40 | 41 | /* Pop the top element out of the stack 42 | */ 43 | void pop(Stack S); 44 | 45 | /* Check the top element and pop it out of stack 46 | */ 47 | ET topAndPop(Stack S); 48 | 49 | #endif 50 | 51 | 52 | /* initialize the stack from the given array 53 | * with the array[0] being the bottom of the stack 54 | */ 55 | Stack initializeStack(int array[], int length); 56 | 57 | /* print out the stack with the following format: 58 | * |elem|elem|elem| <-top 59 | */ 60 | void printStack(Stack S); 61 | -------------------------------------------------------------------------------- /stack/generic/stackTestMain.c: -------------------------------------------------------------------------------- 1 | #include "postfix.h" 2 | #include "stack.h" 3 | #include "utility.h" 4 | #include 5 | #include 6 | #include 7 | #include // use 'getopt' 8 | 9 | void test_initalizeStack(); 10 | void test_createStack(); 11 | void test_push(); 12 | void test_top(); 13 | void test_pop(); 14 | void test_topAndPop(); 15 | 16 | int main(int argc, char** argv) 17 | { 18 | extern char *optarg; 19 | int c, err = 0; 20 | char *filename; 21 | static char usage[] = "usage: %s [-b filename] [-s]\n"; 22 | 23 | while ((c = getopt(argc, argv, "b:s")) != -1) 24 | { 25 | switch(c) 26 | { 27 | case 'b': 28 | filename = optarg; 29 | printf("Postfix expression: "); 30 | printFile(filename); 31 | int res = evaluate_postfix(filename); 32 | printf("res: %d\n", res); 33 | break; 34 | case 's': 35 | printf("///////////////////////\n"); 36 | printf("// STACK TEST\n"); 37 | printf("///////////////////////\n\n"); 38 | test_initalizeStack(); printf("\n"); 39 | test_createStack(); printf("\n"); 40 | test_push(); printf("\n"); 41 | test_top(); printf("\n"); 42 | test_pop(); printf("\n"); 43 | test_topAndPop(); printf("\n"); 44 | break; 45 | case '?': 46 | err = 1; 47 | break; 48 | } 49 | } 50 | if (err) 51 | { 52 | fprintf(stderr, usage, argv[0]); 53 | exit(1); 54 | } 55 | exit(0); 56 | } 57 | 58 | void 59 | test_initalizeStack() 60 | { 61 | printf("TEST: initializeStack\n"); 62 | 63 | ET test_Q1[3] = {1,2,3}; 64 | Stack Q1 = initializeStack(test_Q1, 3); 65 | printStack(Q1); 66 | disposeStack(Q1); 67 | } 68 | 69 | void 70 | test_createStack() 71 | { 72 | printf("TEST: createStack\n"); 73 | 74 | Stack s = createStack(3); 75 | printStack(s); 76 | disposeStack(s); 77 | } 78 | 79 | void 80 | test_push() 81 | { 82 | printf("TEST: push\n"); 83 | 84 | ET test_Q1[1] = {1}; 85 | Stack Q1 = initializeStack(test_Q1, 1); 86 | printStack(Q1); 87 | push(2, Q1); 88 | printf("After push 2:\n"); 89 | printStack(Q1); 90 | disposeStack(Q1); 91 | } 92 | 93 | void 94 | test_top() 95 | { 96 | printf("TEST: top\n"); 97 | ET test_Q1[1] = {1}; 98 | Stack Q1 = initializeStack(test_Q1, 1); 99 | printStack(Q1); 100 | printf("Top element of Stack: %d\n", top(Q1)); 101 | disposeStack(Q1); 102 | } 103 | 104 | void 105 | test_pop() 106 | { 107 | printf("TEST: pop\n"); 108 | ET test_Q1[3] = {1,2,3}; 109 | Stack Q1 = initializeStack(test_Q1, 3); 110 | printStack(Q1); 111 | printf("After pop the element:\n"); 112 | pop(Q1); 113 | printStack(Q1); 114 | push(2, Q1); 115 | printf("After push 2:\n"); 116 | printStack(Q1); 117 | disposeStack(Q1); 118 | } 119 | 120 | void 121 | test_topAndPop() 122 | { 123 | printf("TEST: topAndPop\n"); 124 | ET test_Q1[3] = {1,2,3}; 125 | Stack Q1 = initializeStack(test_Q1, 3); 126 | printStack(Q1); 127 | printf("Pop the element: %d\n", topAndPop(Q1)); 128 | printf("After pop the element:\n"); 129 | printStack(Q1); 130 | } 131 | -------------------------------------------------------------------------------- /stack/generic/test-posfix-expression/expr1: -------------------------------------------------------------------------------- 1 | 6 5 2 3 + 8 * + 3 + * -------------------------------------------------------------------------------- /stack/postfix-c/Makefile: -------------------------------------------------------------------------------- 1 | C_COMPILER=gcc 2 | CFLAGS = -Wall -g 3 | 4 | # Directories 5 | ROOT = ../../ 6 | 7 | SRC_FILES=\ 8 | $(wildcard ./*.c) \ 9 | $(ROOT)utility/utility.c 10 | 11 | INC_DIRS=\ 12 | -I$(ROOT)utility/ 13 | 14 | LIBS=\ 15 | -lm 16 | 17 | OUTPUT_FILE=main 18 | 19 | .PHONY: clean 20 | .PHONY: test 21 | 22 | test: 23 | $(C_COMPILER) $(CFLAGS) $(INC_DIRS) $(LIBS) $(SRC_FILES) -o $(OUTPUT_FILE) 24 | 25 | clean: 26 | rm -rf $(OUTPUT_FILE) 27 | -------------------------------------------------------------------------------- /stack/postfix-c/postfix2.c: -------------------------------------------------------------------------------- 1 | #include "postfix2.h" 2 | 3 | /* The algorithm used is called "Shunting-yard" algorithm 4 | * see more: https://en.wikipedia.org/wiki/Shunting-yard_algorithm 5 | * Operator precedence assumed (from highest to lowest): 6 | * () 7 | * ^ 8 | * *, / 9 | * +, - 10 | */ 11 | void 12 | infixTopostfix(char* filename) 13 | { 14 | int maxElements = 20; 15 | Stack s = createStack(maxElements); 16 | FILE *fp; 17 | fp = fopen(filename, "r"); 18 | if (fp == NULL) 19 | { 20 | fprintf(stderr, "can't open %s\n", filename); 21 | exit(1); 22 | } 23 | int c; 24 | char* tmp = malloc(sizeof(char)); 25 | while((c=getc(fp)) != EOF) 26 | { 27 | /* printf("character c read: "); */ 28 | /* putc(c, stdout); */ 29 | /* printf("\n"); */ 30 | if(isalpha(c) || isdigit(c)) 31 | { 32 | putchar(c); 33 | } 34 | else 35 | { 36 | switch(c) 37 | { 38 | case ' ': 39 | break; 40 | case '-': 41 | case '+': 42 | while(!isEmpty(s) && strcmp(top(s),"(")) 43 | { 44 | putchar(topAndPop(s)[0]); 45 | } 46 | tmp[0] = c; 47 | push(tmp, s); 48 | break; 49 | case '/': 50 | case '*': 51 | if (isEmpty(s) || 52 | !strcmp(top(s),"+") || 53 | !strcmp(top(s),"-") || 54 | !strcmp(top(s),"(") 55 | ) 56 | { 57 | tmp[0] = c; 58 | push(tmp, s); 59 | } 60 | else 61 | { 62 | while (strcmp(top(s),"(") && !isEmpty(s)) 63 | { 64 | putchar(topAndPop(s)[0]); 65 | } 66 | tmp[0] = c; 67 | push(tmp, s); 68 | } 69 | break; 70 | case '(': 71 | tmp[0] = c; 72 | push(tmp, s); 73 | break; 74 | case ')': 75 | while(strcmp(top(s),"(")) 76 | { 77 | putchar(topAndPop(s)[0]); 78 | } 79 | pop(s); //remove '(' 80 | break; 81 | case '^': 82 | tmp[0] = c; 83 | push(tmp, s); // by assumption, there is no operator has higher precedence than '^', so we push directly 84 | break; 85 | default: 86 | fprintf(stderr, "Invalid operator %c in expression\n", c); 87 | exit(1); 88 | } 89 | } 90 | //printStack(s); 91 | //printf("TopOfStack: %d\n", getTopOfStack(s)); 92 | } 93 | while(!isEmpty(s)) 94 | { 95 | putchar(topAndPop(s)[0]); 96 | } 97 | disposeStack(s); 98 | free(tmp); 99 | printf("\n"); 100 | } 101 | 102 | void 103 | postfixToinfix(char* filename) 104 | { 105 | int maxElements = 20; 106 | FILE *fp; 107 | fp = fopen(filename, "r"); 108 | if (fp == NULL) 109 | { 110 | fprintf(stderr, "can't open %s\n", filename); 111 | exit(1); 112 | } 113 | int c, lenA, lenB; 114 | char* tmp = malloc(sizeof(char)); 115 | char* tmp2; 116 | char* a; 117 | char* b; 118 | Stack s = createStack(maxElements); 119 | while((c=getc(fp)) != EOF) 120 | { 121 | /* printf("character c read: "); */ 122 | /* putc(c, stdout); */ 123 | /* printf("\n"); */ 124 | if(isdigit(c) || isalpha(c)) 125 | { 126 | tmp[0] = c; 127 | push(tmp, s); 128 | } 129 | else 130 | { 131 | switch(c) 132 | { 133 | case '^': 134 | case '/': 135 | case '*': 136 | case '+': 137 | case '-': 138 | a = topAndPop(s); 139 | lenA = strlen(a); 140 | //printf("a: %s with length: %d\n", a, lenA); 141 | b = topAndPop(s); 142 | lenB = strlen(b); 143 | //printf("b: %s with length: %d\n", b, lenB); 144 | tmp2 = malloc((lenA+lenB+3)*sizeof(char)); // 1 for c, 2 for '(' and ')', so total is 3 145 | strcpy(tmp2, "("); 146 | strcat(tmp2, b); 147 | //printf("tmp2: %s\n", tmp2); 148 | tmp[0] = c; 149 | strcat(tmp2,tmp); 150 | //printf("tmp2: %s\n", tmp2); 151 | strcat(tmp2,a); 152 | //printf("tmp2: %s\n", tmp2); 153 | strcat(tmp2, ")"); 154 | push(tmp2, s); 155 | free(tmp2); 156 | break; 157 | case ' ': 158 | break; 159 | default: 160 | fprintf(stderr, "Invalid operator in the file\n"); 161 | exit(1); 162 | } 163 | } 164 | //printStack(s); 165 | } 166 | printf(topAndPop(s)); 167 | disposeStack(s); 168 | fclose(fp); 169 | } 170 | -------------------------------------------------------------------------------- /stack/postfix-c/postfix2.h: -------------------------------------------------------------------------------- 1 | #include "stack3.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | /* MAW 3.20.a Write a program to convert 8 | * an infix expression which includes '(', 9 | * ')', '+', '-', '*', and '/' to postfix. 10 | * 11 | * MAW 3.20.b Add the exponentiation operator to your 12 | * repertoire. 13 | */ 14 | void infixTopostfix(char*); 15 | 16 | /* MAW 3.20.c Write a program to convert a postfix expression 17 | * to infix. 18 | */ 19 | void postfixToinfix(char*); 20 | -------------------------------------------------------------------------------- /stack/postfix-c/postfix2TestMain.c: -------------------------------------------------------------------------------- 1 | #include "postfix2.h" 2 | #include "stack3.h" 3 | #include "utility.h" 4 | #include 5 | #include 6 | #include 7 | #include // use 'getopt' 8 | 9 | int main(int argc, char** argv) 10 | { 11 | extern char *optarg; 12 | int c, err = 0; 13 | char *filename; 14 | static char usage[] = "usage: %s [-b filename]\n"; 15 | 16 | while ((c = getopt(argc, argv, "b:c:")) != -1) 17 | { 18 | switch(c) 19 | { 20 | case 'b': 21 | /* post2infix1: 22 | * infix expression: a+b*c+(d*e+f)*g 23 | * postfix expression: abc*+de*f+g*+ 24 | * post2infix2: 25 | * infix expression: (a+b)/c*d-e 26 | * postfix expression: ab+c/d*e- 27 | * post2infix3: 28 | * infix expression: 2^3^2 29 | * postfix expression: 232^^ 30 | */ 31 | filename = optarg; 32 | printf("postfix expression: "); 33 | printFile(filename); 34 | printf("infix expression: "); 35 | postfixToinfix(filename); 36 | break; 37 | case 'c': 38 | /* expr1: 39 | * infix expression: a+b*c+(d*e+f)*g 40 | * postfix expression: abc*+de*f+g*+ 41 | * expr2: 42 | * infix expression: (a+b)/c*d-e 43 | * postfix expression: ab+c/d*e- 44 | * expr3: 45 | * infix expression: 2^3^2 46 | * postfix expression: 232^^ 47 | */ 48 | filename = optarg; 49 | printf("infix expression: "); 50 | printFile(filename); 51 | printf("postfix expression: "); 52 | infixTopostfix(filename); 53 | break; 54 | case '?': 55 | err = 1; 56 | break; 57 | } 58 | } 59 | if (err) 60 | { 61 | fprintf(stderr, usage, argv[0]); 62 | exit(1); 63 | } 64 | exit(0); 65 | } 66 | -------------------------------------------------------------------------------- /stack/postfix-c/stack3.c: -------------------------------------------------------------------------------- 1 | #include "stack3.h" 2 | #include "utility.h" 3 | #include 4 | #include 5 | #include 6 | 7 | #define EmptyToS (-1) 8 | #define MinStackSize (5) 9 | 10 | static void resizeStack(Stack); 11 | 12 | struct StackRecord 13 | { 14 | int Capacity; 15 | int TopOfStack; 16 | ET *Array; 17 | }; 18 | 19 | /* Check if Stack is empty 20 | */ 21 | int isEmpty(Stack S) 22 | { 23 | return S->TopOfStack == EmptyToS; 24 | } 25 | 26 | /* Check if Stack is full 27 | */ 28 | int isFull(Stack S) 29 | { 30 | return S->TopOfStack == S->Capacity - 1; 31 | } 32 | 33 | /* Creat a Stack 34 | */ 35 | Stack createStack(int maxElements) 36 | { 37 | Stack s = malloc(sizeof(struct StackRecord)); 38 | s->Capacity = maxElements; 39 | s->TopOfStack = EmptyToS; 40 | s->Array = calloc(s->Capacity, sizeof(ET)); 41 | return s; 42 | } 43 | 44 | /* Delete the Stack 45 | */ 46 | void 47 | disposeStack(Stack S) 48 | { 49 | if (S != NULL) 50 | { 51 | free(S->Array); 52 | free(S); 53 | } 54 | } 55 | 56 | /* Make the Stack empty 57 | */ 58 | void 59 | makeEmpty(Stack S) 60 | { 61 | S->TopOfStack = EmptyToS; 62 | } 63 | 64 | /* Push an element on the Stack 65 | */ 66 | void 67 | push (ET elem, Stack S) 68 | { 69 | if (isFull(S)) 70 | { 71 | resizeStack(S); 72 | } 73 | char* dupSymbol = malloc(strlen(elem) * sizeof(char)); 74 | strcpy(dupSymbol, elem); 75 | S->Array[++S->TopOfStack] = dupSymbol; 76 | } 77 | 78 | /* Check the top element of the Stack 79 | */ 80 | ET 81 | top(Stack S) 82 | { 83 | if (!isEmpty(S)) 84 | { 85 | return S->Array[S->TopOfStack]; 86 | } 87 | return ""; 88 | } 89 | 90 | /* Pop the top element out of the Stack 91 | */ 92 | void 93 | pop(Stack S) 94 | { 95 | S->TopOfStack--; 96 | } 97 | 98 | /* Check the top element and pop it out of Stack 99 | */ 100 | ET 101 | topAndPop(Stack S) 102 | { 103 | return S->Array[S->TopOfStack--]; 104 | } 105 | 106 | static void 107 | resizeStackArray(ET** array, int length) 108 | { 109 | *array = realloc(*array, sizeof(ET) * length); 110 | } 111 | 112 | static void 113 | resizeStack(Stack S) 114 | { 115 | S->Capacity *= 2; 116 | resizeStackArray(&(S->Array), S->Capacity); 117 | } 118 | 119 | void 120 | printStack(Stack S) 121 | { 122 | ET* arrayS = S->Array; 123 | int i; 124 | for (i = 0; i <= S->TopOfStack; i++) 125 | { 126 | printf("%s%s%s", 127 | "|", 128 | arrayS[i], 129 | (i == S->TopOfStack) ? ("| <-top") : ("")); 130 | } 131 | printf("\n"); 132 | } 133 | 134 | int 135 | getTopOfStack(Stack S) 136 | { 137 | return S->TopOfStack; 138 | } 139 | -------------------------------------------------------------------------------- /stack/postfix-c/stack3.h: -------------------------------------------------------------------------------- 1 | /* We use array implementation of stacks 2 | */ 3 | #ifndef _STACK_H 4 | #define _STACK_H 5 | 6 | /* ET shorts for "ElementType" 7 | */ 8 | typedef char* ET; 9 | 10 | struct StackRecord; 11 | typedef struct StackRecord* Stack; 12 | 13 | /* Check if stack is empty 14 | */ 15 | int isEmpty(Stack S); 16 | 17 | /* Check if stack is full 18 | */ 19 | int isFull(Stack S); 20 | 21 | /* Creat a stack 22 | */ 23 | Stack createStack(int maxElements); 24 | 25 | /* Delete the stack 26 | */ 27 | void disposeStack(Stack S); 28 | 29 | /* Make the stack empty 30 | */ 31 | void makeEmpty(Stack S); 32 | 33 | /* Push an element on the stack 34 | */ 35 | void push (ET elem, Stack S); 36 | 37 | /* Check the top element of the stack 38 | */ 39 | ET top(Stack S); 40 | 41 | /* Pop the top element out of the stack 42 | */ 43 | void pop(Stack S); 44 | 45 | /* Check the top element and pop it out of stack 46 | */ 47 | ET topAndPop(Stack S); 48 | 49 | #endif 50 | 51 | /* print out the stack with the following format: 52 | * |elem|elem|elem| <-top 53 | */ 54 | void printStack(Stack S); 55 | 56 | int getTopOfStack(Stack S); 57 | -------------------------------------------------------------------------------- /stack/postfix-c/test-posfix-expression/expr1: -------------------------------------------------------------------------------- 1 | a+b*c+(d*e+f)*g -------------------------------------------------------------------------------- /stack/postfix-c/test-posfix-expression/expr2: -------------------------------------------------------------------------------- 1 | (a+b)/c*d-e -------------------------------------------------------------------------------- /stack/postfix-c/test-posfix-expression/expr3: -------------------------------------------------------------------------------- 1 | 2^3^2 -------------------------------------------------------------------------------- /stack/postfix-c/test-posfix-expression/post2infix1: -------------------------------------------------------------------------------- 1 | abc*+de*f+g*+ -------------------------------------------------------------------------------- /stack/postfix-c/test-posfix-expression/post2infix2: -------------------------------------------------------------------------------- 1 | ab+c/d*e- -------------------------------------------------------------------------------- /stack/postfix-c/test-posfix-expression/post2infix3: -------------------------------------------------------------------------------- 1 | 232^^ -------------------------------------------------------------------------------- /stack/postfix-c/test-posfix-expression/post2infix4: -------------------------------------------------------------------------------- 1 | ab+ -------------------------------------------------------------------------------- /stack/postfix/Makefile: -------------------------------------------------------------------------------- 1 | C_COMPILER=gcc 2 | CFLAGS = -Wall -g 3 | 4 | # Directories 5 | ROOT = ../../ 6 | 7 | SRC_FILES=\ 8 | $(wildcard ./*.c) \ 9 | $(ROOT)utility/utility.c 10 | 11 | INC_DIRS=\ 12 | -I$(ROOT)utility/ 13 | 14 | LIBS=\ 15 | -lm 16 | 17 | OUTPUT_FILE=main 18 | 19 | .PHONY: clean 20 | .PHONY: test 21 | 22 | test: 23 | $(C_COMPILER) $(CFLAGS) $(INC_DIRS) $(LIBS) $(SRC_FILES) -o $(OUTPUT_FILE) 24 | 25 | clean: 26 | rm -rf $(OUTPUT_FILE) 27 | -------------------------------------------------------------------------------- /stack/postfix/NOTICE: -------------------------------------------------------------------------------- 1 | This directory exists for legacy: 2 | 3 | The implementation for "void infixTopostfix(char*);" 4 | is same as that in "postfix-c" directory. The only difference 5 | is that, the version in this directory has "ET" as: 6 | 7 | typedef char ET; 8 | 9 | However, inside "postfix-c" directory, "ET" is defined as: 10 | 11 | typedef char* ET; 12 | 13 | The version in this directory is simpler than the version in "postfix-c". 14 | I implement "postfix-c" version is for engineering purpose: put both 15 | "void infixTopostfix(char*);" and "void postfixToinfix(char* filename);" 16 | under the same data structure framework to make the overall repo structure 17 | not very chaotic. 18 | -------------------------------------------------------------------------------- /stack/postfix/postfix2.c: -------------------------------------------------------------------------------- 1 | #include "postfix2.h" 2 | 3 | /* The algorithm used is called "Shunting-yard" algorithm 4 | * see more: https://en.wikipedia.org/wiki/Shunting-yard_algorithm 5 | * Operator precedence assumed (from highest to lowest): 6 | * () 7 | * ^ 8 | * *, / 9 | * +, - 10 | */ 11 | void 12 | infixTopostfix(char* filename) 13 | { 14 | int maxElements = 20; 15 | Stack s = createStack(maxElements); 16 | FILE *fp; 17 | fp = fopen(filename, "r"); 18 | if (fp == NULL) 19 | { 20 | fprintf(stderr, "can't open %s\n", filename); 21 | exit(1); 22 | } 23 | int c; 24 | while((c=getc(fp)) != EOF) 25 | { 26 | /* printf("character c read: "); */ 27 | /* putc(c, stdout); */ 28 | /* printf("\n"); */ 29 | if(isalpha(c) || isdigit(c)) 30 | { 31 | putchar(c); 32 | } 33 | else 34 | { 35 | switch(c) 36 | { 37 | case ' ': 38 | break; 39 | case '-': 40 | case '+': 41 | while(!isEmpty(s) && top(s) != '(') 42 | { 43 | putchar(topAndPop(s)); 44 | } 45 | push(c, s); 46 | break; 47 | case '/': 48 | case '*': 49 | if (top(s) == '+' || 50 | top(s) == '-' || 51 | top(s) == '(' || 52 | isEmpty(s)) 53 | { 54 | push(c, s); 55 | } 56 | else 57 | { 58 | while (top(s) != '(' && !isEmpty(s)) 59 | { 60 | putchar(topAndPop(s)); 61 | } 62 | push(c, s); 63 | } 64 | break; 65 | case '(': 66 | push('(', s); 67 | break; 68 | case ')': 69 | while(top(s) != '(') 70 | { 71 | putchar(topAndPop(s)); 72 | } 73 | pop(s); //remove '(' 74 | break; 75 | case '^': 76 | push('^', s); // by assumption, there is no operator has higher precedence than '^', so we push directly 77 | break; 78 | default: 79 | fprintf(stderr, "Invalid operator %c in expression\n", c); 80 | exit(1); 81 | } 82 | } 83 | } 84 | while(!isEmpty(s)) 85 | { 86 | putchar(topAndPop(s)); 87 | } 88 | disposeStack(s); 89 | printf("\n"); 90 | } 91 | -------------------------------------------------------------------------------- /stack/postfix/postfix2.h: -------------------------------------------------------------------------------- 1 | #include "stack3.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | /* MAW 3.20.a Write a program to convert 8 | * an infix expression which includes '(', 9 | * ')', '+', '-', '*', and '/' to postfix. 10 | * 11 | * MAW 3.20.b Add the exponentiation operator to your 12 | * repertoire. 13 | */ 14 | void infixTopostfix(char*); 15 | -------------------------------------------------------------------------------- /stack/postfix/postfix2TestMain.c: -------------------------------------------------------------------------------- 1 | #include "postfix2.h" 2 | #include "stack3.h" 3 | #include "utility.h" 4 | #include 5 | #include 6 | #include 7 | #include // use 'getopt' 8 | 9 | int main(int argc, char** argv) 10 | { 11 | extern char *optarg; 12 | int c, err = 0; 13 | char *filename; 14 | static char usage[] = "usage: %s [-b filename]\n"; 15 | 16 | while ((c = getopt(argc, argv, "b:")) != -1) 17 | { 18 | switch(c) 19 | { 20 | case 'b': 21 | /* expr1: 22 | * infix expression: a+b*c+(d*e+f)*g 23 | * postfix expression: abc*+de*f+g*+ 24 | * expr2: 25 | * infix expression: (a+b)/c*d-e 26 | * postfix expression: ab+c/d*e- 27 | * expr3: 28 | * infix expression: 2^3^2 29 | * postfix expression: 232^^ 30 | */ 31 | filename = optarg; 32 | printf("infix expression: "); 33 | printFile(filename); 34 | printf("postfix expression: "); 35 | infixTopostfix(filename); 36 | break; 37 | case '?': 38 | err = 1; 39 | break; 40 | } 41 | } 42 | if (err) 43 | { 44 | fprintf(stderr, usage, argv[0]); 45 | exit(1); 46 | } 47 | exit(0); 48 | } 49 | -------------------------------------------------------------------------------- /stack/postfix/stack3.c: -------------------------------------------------------------------------------- 1 | #include "stack3.h" 2 | #include "utility.h" 3 | #include 4 | #include 5 | 6 | #define EmptyToS (-1) 7 | #define MinStackSize (5) 8 | 9 | static void resizeStack(Stack); 10 | 11 | struct StackRecord 12 | { 13 | int Capacity; 14 | int TopOfStack; 15 | ET *Array; 16 | }; 17 | 18 | /* Check if Stack is empty 19 | */ 20 | int isEmpty(Stack S) 21 | { 22 | return S->TopOfStack == EmptyToS; 23 | } 24 | 25 | /* Check if Stack is full 26 | */ 27 | int isFull(Stack S) 28 | { 29 | return S->TopOfStack == S->Capacity - 1; 30 | } 31 | 32 | /* Creat a Stack 33 | */ 34 | Stack createStack(int maxElements) 35 | { 36 | Stack s = malloc(sizeof(struct StackRecord)); 37 | s->Capacity = maxElements; 38 | s->TopOfStack = EmptyToS; 39 | s->Array = calloc(s->Capacity, sizeof(ET)); 40 | return s; 41 | } 42 | 43 | /* Delete the Stack 44 | */ 45 | void 46 | disposeStack(Stack S) 47 | { 48 | if (S != NULL) 49 | { 50 | free(S->Array); 51 | free(S); 52 | } 53 | } 54 | 55 | /* Make the Stack empty 56 | */ 57 | void 58 | makeEmpty(Stack S) 59 | { 60 | S->TopOfStack = EmptyToS; 61 | } 62 | 63 | /* Push an element on the Stack 64 | */ 65 | void 66 | push (ET elem, Stack S) 67 | { 68 | if (isFull(S)) 69 | { 70 | resizeStack(S); 71 | } 72 | S->Array[++S->TopOfStack] = elem; 73 | } 74 | 75 | /* Check the top element of the Stack 76 | */ 77 | ET 78 | top(Stack S) 79 | { 80 | return S->Array[S->TopOfStack]; 81 | } 82 | 83 | /* Pop the top element out of the Stack 84 | */ 85 | void 86 | pop(Stack S) 87 | { 88 | S->TopOfStack--; 89 | } 90 | 91 | /* Check the top element and pop it out of Stack 92 | */ 93 | ET 94 | topAndPop(Stack S) 95 | { 96 | return S->Array[S->TopOfStack--]; 97 | } 98 | 99 | static void 100 | resizeStackArray(ET** array, int length) 101 | { 102 | *array = realloc(*array, sizeof(ET) * length); 103 | } 104 | 105 | static void 106 | resizeStack(Stack S) 107 | { 108 | S->Capacity *= 2; 109 | resizeStackArray(&(S->Array), S->Capacity); 110 | } 111 | -------------------------------------------------------------------------------- /stack/postfix/stack3.h: -------------------------------------------------------------------------------- 1 | /* We use array implementation of stacks 2 | */ 3 | #ifndef _STACK_H 4 | #define _STACK_H 5 | 6 | /* ET shorts for "ElementType" 7 | */ 8 | typedef char ET; 9 | 10 | struct StackRecord; 11 | typedef struct StackRecord* Stack; 12 | 13 | /* Check if stack is empty 14 | */ 15 | int isEmpty(Stack S); 16 | 17 | /* Check if stack is full 18 | */ 19 | int isFull(Stack S); 20 | 21 | /* Creat a stack 22 | */ 23 | Stack createStack(int maxElements); 24 | 25 | /* Delete the stack 26 | */ 27 | void disposeStack(Stack S); 28 | 29 | /* Make the stack empty 30 | */ 31 | void makeEmpty(Stack S); 32 | 33 | /* Push an element on the stack 34 | */ 35 | void push (ET elem, Stack S); 36 | 37 | /* Check the top element of the stack 38 | */ 39 | ET top(Stack S); 40 | 41 | /* Pop the top element out of the stack 42 | */ 43 | void pop(Stack S); 44 | 45 | /* Check the top element and pop it out of stack 46 | */ 47 | ET topAndPop(Stack S); 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /stack/postfix/test-posfix-expression/expr1: -------------------------------------------------------------------------------- 1 | a+b*c+(d*e+f)*g -------------------------------------------------------------------------------- /stack/postfix/test-posfix-expression/expr2: -------------------------------------------------------------------------------- 1 | (a+b)/c*d-e -------------------------------------------------------------------------------- /stack/postfix/test-posfix-expression/expr3: -------------------------------------------------------------------------------- 1 | 2^3^2 -------------------------------------------------------------------------------- /trees/2-d/2d.c: -------------------------------------------------------------------------------- 1 | #include "2d.h" 2 | 3 | // WARNING: DON'T CHANGE THE NUMKEYS VALUE 4 | #define NUMKEYS (2) // Number of keys in a 2-d tree node 5 | 6 | struct 7 | TdTreeNode 8 | { 9 | char* Keys[NUMKEYS]; 10 | Position Child[NUMKEYS]; 11 | int Level; // which level the node is on: even or odd? 12 | }; 13 | 14 | void 15 | makeEmpty(TdTree T) 16 | { 17 | int i; 18 | if(T != NULL) 19 | { 20 | for(i=0; i < NUMKEYS; i++) 21 | makeEmpty(T->Child[i]); 22 | free(T); 23 | } 24 | } 25 | 26 | static TdTree 27 | insertionInternal(char elem[], TdTree T, int level) 28 | { 29 | char elemDup[30]; 30 | strcpy(elemDup, elem); //strtok directly alter elem but we want to keep them intact when we do recursive call 31 | char* pch1; char* pch2; 32 | pch1 = strtok(elemDup, " "); 33 | pch2 = strtok(NULL, " "); 34 | if (T == NULL) 35 | { 36 | T = malloc(sizeof(*T)); 37 | T->Keys[0] = strtok(elem, " "); 38 | T->Keys[1] = strtok(NULL, " "); 39 | T->Child[0] = T->Child[1] = NULL; 40 | T->Level = ++level; 41 | } 42 | else if(T->Level % 2 != 0) // odd levels 43 | { 44 | if (strcmp(pch2, T->Keys[1]) < 0) // we insert into the left subtree 45 | T->Child[0] = insertionInternal(elem, T->Child[0], T->Level); 46 | else if (strcmp(pch2, T->Keys[1]) > 0) // we insert into the right subtree 47 | T->Child[1] = insertionInternal(elem, T->Child[1], T->Level); 48 | } 49 | else // even levels 50 | { 51 | if (strcmp(pch1, T->Keys[0]) < 0) // we insert into the left subtree 52 | T->Child[0] = insertionInternal(elem, T->Child[0], T->Level); 53 | else if (strcmp(pch1, T->Keys[0]) > 0) // we insert into the right subtree 54 | T->Child[1] = insertionInternal(elem, T->Child[1], T->Level); 55 | } 56 | return T; 57 | } 58 | 59 | TdTree 60 | insertion(char elem[], TdTree T) 61 | { 62 | T = insertionInternal(elem, T, -1); 63 | return T; 64 | } 65 | 66 | void 67 | tdprintRange(char* low1, char* high1, char* low2, char* high2, TdTree T) 68 | { 69 | if(T != NULL) 70 | { 71 | if(T->Level % 2 == 0) // even levels 72 | { 73 | if(strcmp(low1, T->Keys[0]) <= 0) 74 | tdprintRange(low1, high1, low2, high2, T->Child[0]); 75 | if(strcmp(low1, T->Keys[0]) <= 0 && strcmp(high1, T->Keys[0]) >= 0) 76 | if (strcmp(low2, T->Keys[1]) <= 0 && strcmp(high2, T->Keys[1]) >= 0) 77 | printf("%s %s\n", T->Keys[0], T->Keys[1]); 78 | if(strcmp(high1, T->Keys[0]) >= 0) 79 | tdprintRange(low1, high1, low2, high2, T->Child[1]); 80 | } 81 | else // odd levels 82 | { 83 | if(strcmp(low2, T->Keys[1]) <= 0) 84 | tdprintRange(low1, high1, low2, high2, T->Child[0]); 85 | if(strcmp(low2, T->Keys[1]) <= 0 && strcmp(high2, T->Keys[1]) >= 0) 86 | if (strcmp(low1, T->Keys[0]) <= 0 && strcmp(high1, T->Keys[0]) >= 0) 87 | printf("%s %s\n", T->Keys[0], T->Keys[1]); 88 | if(strcmp(high2, T->Keys[1]) >= 0) 89 | tdprintRange(low1, high1, low2, high2, T->Child[1]); 90 | } 91 | } 92 | } 93 | 94 | static void 95 | td_print_dot_aux(TdTree T, FILE* stream) 96 | { 97 | if(T != NULL) 98 | { 99 | int i; 100 | for(i=0;i < NUMKEYS; i++) 101 | { 102 | if (T->Child[i] != NULL) 103 | { 104 | fprintf(stream, "\"%s %s\"->\"%s %s\";\n", T->Keys[0], T->Keys[1], 105 | T->Child[i]->Keys[0], T->Child[i]->Keys[1]); 106 | td_print_dot_aux(T->Child[i], stream); 107 | } 108 | } 109 | } 110 | } 111 | 112 | void 113 | td_print_dot(TdTree T, FILE* stream) 114 | { 115 | fprintf(stream, "digraph TdTree{\n"); 116 | td_print_dot_aux(T, stream); 117 | fprintf(stream, "}\n"); 118 | } 119 | 120 | TdTree 121 | initializeTdTree(char array[][30], int arrayLength) 122 | { 123 | TdTree T = NULL; 124 | int i; 125 | for(i = 0; i < arrayLength; i++) 126 | T = insertion(array[i], T); 127 | return T; 128 | } 129 | -------------------------------------------------------------------------------- /trees/2-d/2d.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "utility.h" 4 | #include 5 | #include 6 | 7 | /* 8 | * MAW 4.46 A binary search tree presupposes that searching is based on only one 9 | * key per record. Suppose we would like to be able to perform searching based on 10 | * either of two keys, Key1 or Key2. 11 | * 12 | * An alternative method is a 2-d tree. A 2-d tree is similar to a binary search tree, 13 | * except that branching at even levels is done with respsect to Key1, and branching at 14 | * odd levels is done with Key2. 15 | */ 16 | #ifndef _TD_H_ 17 | #define _TD_H_ 18 | 19 | struct TdTreeNode; 20 | typedef struct TdTreeNode *Position; 21 | typedef Position TdTree; 22 | 23 | void makeEmpty(TdTree T); 24 | /* 25 | * MAW 4.16.b Write a routine to perform insertion into a 2-d tree. 26 | */ 27 | TdTree insertion(char elem[], TdTree T); 28 | /* 29 | * MAW 4.16.c Write an efficient procedure that prints all records in the tree that simultaneously satisfy 30 | * the constraints Low1 <= Key1 <= High1 and Low2 <= Key2 <= High2 31 | */ 32 | void tdprintRange(char* low1, char* high1, char* low2, char* high2, TdTree T); 33 | TdTree initializeTdTree(char elem[][30], int); 34 | void td_print_dot(TdTree T, FILE* stream); 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /trees/2-d/2dTestMain.c: -------------------------------------------------------------------------------- 1 | #include "2d.h" 2 | 3 | void generate_dot(TdTree); 4 | void delete_tree(TdTree); 5 | void test_initializeTdTree(); 6 | void test_tdprintRange(); 7 | 8 | int main() 9 | { 10 | printf("////////////////////\n"); 11 | printf("/// 2D TREE TEST\n"); 12 | printf("////////////////////\n"); 13 | 14 | test_initializeTdTree(); printf("\n"); 15 | test_tdprintRange(); printf("\n"); 16 | 17 | return 0; 18 | } 19 | 20 | void 21 | generate_dot(TdTree T) 22 | { 23 | char* dotFilename = "2d.dot"; 24 | FILE *fp = fopen(dotFilename, "w"); 25 | td_print_dot(T, fp); 26 | fclose(fp); 27 | printFile(dotFilename); 28 | } 29 | 30 | void 31 | delete_tree(TdTree T) 32 | { 33 | makeEmpty(T); 34 | } 35 | 36 | void 37 | test_initializeTdTree() 38 | { 39 | printf("TEST: initializeTdTree\n"); 40 | char test_array[][30] = { // array of char array: K&R p.114 41 | "Harry Truman", 42 | "Dwight Eisenhower", 43 | "John Kennedy", 44 | "Lyndon Johnson", 45 | "Richard Nixon", 46 | "Gerald Ford", 47 | "Jimmy Carter", 48 | "Ronald Reagan", 49 | "George Bush", 50 | "Bill Clinton" 51 | }; 52 | TdTree T = initializeTdTree(test_array, 10); 53 | generate_dot(T); 54 | delete_tree(T); 55 | } 56 | 57 | void 58 | test_tdprintRange() 59 | { 60 | printf("TEST: tdprintRange\n"); 61 | char test_array[][30] = { // array of char array: K&R p.114. strtok cannot work on constant string 62 | "Harry Truman", 63 | "Dwight Eisenhower", 64 | "John Kennedy", 65 | "Lyndon Johnson", 66 | "Richard Nixon", 67 | "Gerald Ford", 68 | "Jimmy Carter", 69 | "Ronald Reagan", 70 | "George Bush", 71 | "Bill Clinton" 72 | }; 73 | TdTree T = initializeTdTree(test_array, 10); 74 | tdprintRange("A", "Z", "A", "Z", T); 75 | delete_tree(T); 76 | } 77 | -------------------------------------------------------------------------------- /trees/2-d/Makefile: -------------------------------------------------------------------------------- 1 | C_COMPILER=gcc 2 | CFLAGS = -Wall -g 3 | 4 | # Directories 5 | ROOT = ../../ 6 | 7 | SRC_FILES=\ 8 | $(wildcard ./*.c) \ 9 | $(ROOT)utility/utility.c 10 | 11 | INC_DIRS=\ 12 | -I$(ROOT)utility/ 13 | 14 | LIBS=\ 15 | -lm 16 | 17 | OUTPUT_FILE=main 18 | 19 | .PHONY: clean 20 | .PHONY: test 21 | 22 | test: 23 | $(C_COMPILER) $(CFLAGS) $(INC_DIRS) $(LIBS) $(SRC_FILES) -o $(OUTPUT_FILE) 24 | ./$(OUTPUT_FILE) -v 25 | 26 | clean: 27 | rm -rf $(OUTPUT_FILE) 28 | -------------------------------------------------------------------------------- /trees/AVL/Makefile: -------------------------------------------------------------------------------- 1 | C_COMPILER=gcc 2 | CFLAGS = -Wall -g 3 | 4 | # Directories 5 | ROOT = ../../ 6 | 7 | SRC_FILES=\ 8 | $(wildcard ./*.c) \ 9 | $(ROOT)utility/utility.c 10 | 11 | INC_DIRS=\ 12 | -I$(ROOT)utility/ 13 | 14 | LIBS=\ 15 | -lm 16 | 17 | OUTPUT_FILE=main 18 | 19 | .PHONY: clean 20 | .PHONY: test 21 | 22 | test: 23 | $(C_COMPILER) $(CFLAGS) $(INC_DIRS) $(LIBS) $(SRC_FILES) -o $(OUTPUT_FILE) 24 | ./$(OUTPUT_FILE) -v 25 | 26 | clean: 27 | rm -rf $(OUTPUT_FILE) 28 | rm -rf *.dot 29 | -------------------------------------------------------------------------------- /trees/AVL/avl.h: -------------------------------------------------------------------------------- 1 | #include "utility.h" 2 | #include 3 | #include 4 | 5 | #ifndef _AVL_H 6 | #define _AVL_H 7 | 8 | typedef int ET; 9 | 10 | struct AVLTreeNode; 11 | typedef struct AVLTreeNode *Position; 12 | typedef Position AVL; 13 | 14 | AVL makeEmpty(AVL); 15 | Position find(ET, AVL); 16 | Position findMin(AVL); 17 | Position findMax(AVL); 18 | 19 | /* 20 | * MAW 4.18 Write the remaining procedures to implement AVL single and double rotations. 21 | */ 22 | AVL insert(ET, AVL); 23 | 24 | /* 25 | * MAW 4.19 Write a nonrecursive function to insert into an AVL tree. 26 | */ 27 | AVL insert2(ET, AVL); 28 | 29 | /* 30 | * MAW 4.20 How can you implement (nonlazy) deletion in AVL trees? 31 | */ 32 | AVL delete(ET, AVL); 33 | ET retrieve(Position); 34 | 35 | /* 36 | * Create a AVL tree based upon the given array 37 | */ 38 | AVL initializeAVL(ET*, int); 39 | 40 | /* 41 | * Generate a dot file to be fed into Graphviz to display tree 42 | */ 43 | void bst_print_dot(AVL, FILE*); 44 | 45 | /* 46 | * MAW 4.30 Write a function to generate the AVL tree of height H with fewest nodes. 47 | */ 48 | AVL minAVL(int H); 49 | 50 | #endif 51 | -------------------------------------------------------------------------------- /trees/AVL/avlTestMain.c: -------------------------------------------------------------------------------- 1 | #include "avl.h" 2 | #include 3 | #include 4 | 5 | void generate_dot(AVL); 6 | void delete_tree(AVL); 7 | void test_initializeAVL(); 8 | /* void test_find(); */ 9 | /* void test_findMin(); */ 10 | /* void test_findMax(); */ 11 | void test_insert2(); 12 | void test_delete(); 13 | void test_minAVL(); 14 | 15 | int 16 | main() 17 | { 18 | printf("///////////////////////\n"); 19 | printf("// AVL SEARCH TREE TEST\n"); 20 | printf("///////////////////////\n\n"); 21 | 22 | test_initializeAVL(); 23 | /* test_find(); printf("\n"); */ 24 | /* test_findMin(); printf("\n"); */ 25 | /* test_findMax(); printf("\n"); */ 26 | test_insert2(); 27 | test_delete(); 28 | test_minAVL(); 29 | return 0; 30 | } 31 | 32 | void 33 | generate_dot(AVL T) 34 | { 35 | char* dotFilename = "avl.dot"; 36 | FILE *fp = fopen(dotFilename,"w"); 37 | bst_print_dot(T,fp); 38 | fclose(fp); 39 | printFile(dotFilename); 40 | } 41 | 42 | void 43 | delete_tree(AVL T) 44 | { 45 | T = makeEmpty(T); 46 | free(T); 47 | } 48 | 49 | void 50 | test_initializeAVL() 51 | { 52 | printf("TEST: initializeAVL\n"); 53 | ET test_array[] = {2,1,4,5,9,3,6,7}; 54 | AVL T = initializeAVL(test_array, 8); 55 | generate_dot(T); 56 | delete_tree(T); 57 | } 58 | 59 | /* void */ 60 | /* test_find() */ 61 | /* { */ 62 | /* printf("TEST: find\n"); */ 63 | /* ET test_array[] = {2,1,3}; */ 64 | /* BST T = initializeBST(test_array, 3); */ 65 | /* int target = 1; */ 66 | /* printf("want to find the element: %d\n", target); */ 67 | /* Position pos = find(target, T); */ 68 | /* printf("Found the element: %d\n", retrieve(pos)); */ 69 | /* delete_tree(T); */ 70 | /* } */ 71 | 72 | /* void */ 73 | /* test_findMin() */ 74 | /* { */ 75 | /* printf("TEST: findMin\n"); */ 76 | /* ET test_array[] = {2,1,3}; */ 77 | /* BST T = initializeBST(test_array, 3); */ 78 | /* Position pos = findMin(T); */ 79 | /* printf("The min element in the tree: %d\n", retrieve(pos)); */ 80 | /* delete_tree(T); */ 81 | /* } */ 82 | 83 | /* void */ 84 | /* test_findMax() */ 85 | /* { */ 86 | /* printf("TEST: findMax\n"); */ 87 | /* ET test_array[] = {2,1,3}; */ 88 | /* BST T = initializeBST(test_array, 3); */ 89 | /* Position pos = findMax(T); */ 90 | /* printf("The max element in the tree: %d\n", retrieve(pos)); */ 91 | /* delete_tree(T); */ 92 | /* } */ 93 | 94 | void 95 | test_insert2() 96 | { 97 | printf("TEST: insert2\n"); 98 | ET test_array[] = {2,1,4,5,9,3,6,7}; 99 | AVL T = NULL; 100 | int i; 101 | for(i = 0; i < 8; i++) 102 | T = insert2(test_array[i], T); 103 | generate_dot(T); 104 | delete_tree(T); 105 | } 106 | 107 | void 108 | test_delete() 109 | { 110 | printf("TEST: delete\n"); 111 | /* 112 | * 6 3 113 | * / \ delete 7 / \ 114 | * 3 7 --------> 1 6 115 | * / 116 | * 1 117 | */ 118 | ET test_array[] = {6,3,7,1}; 119 | AVL T = initializeAVL(test_array, 4); 120 | printf("deleting the root: %d\n", 7); 121 | T = delete(7, T); 122 | generate_dot(T); 123 | delete_tree(T); 124 | } 125 | 126 | void 127 | test_minAVL() 128 | { 129 | printf("TEST: minimum AVL tree with H\n"); 130 | AVL T = minAVL(2); 131 | generate_dot(T); 132 | delete_tree(T); 133 | } 134 | -------------------------------------------------------------------------------- /trees/AVL/cse100hw1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxks-kkk/algo/05c5f727bbe82185ec969bd4c6caa713ca7c34e5/trees/AVL/cse100hw1.pdf -------------------------------------------------------------------------------- /trees/AVL/lecture12.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxks-kkk/algo/05c5f727bbe82185ec969bd4c6caa713ca7c34e5/trees/AVL/lecture12.pdf -------------------------------------------------------------------------------- /trees/BinarySearchTree/Makefile: -------------------------------------------------------------------------------- 1 | C_COMPILER=gcc 2 | CFLAGS = -Wall -g 3 | 4 | # Directories 5 | ROOT = ../../ 6 | 7 | SRC_FILES=\ 8 | $(wildcard ./*.c) \ 9 | $(ROOT)utility/utility.c 10 | 11 | INC_DIRS=\ 12 | -I$(ROOT)utility/ 13 | 14 | LIBS=\ 15 | -lm 16 | 17 | OUTPUT_FILE=main 18 | 19 | .PHONY: clean 20 | .PHONY: test 21 | 22 | test: 23 | $(C_COMPILER) $(CFLAGS) $(INC_DIRS) $(LIBS) $(SRC_FILES) -o $(OUTPUT_FILE) 24 | ./$(OUTPUT_FILE) -v 25 | 26 | clean: 27 | rm -rf $(OUTPUT_FILE) 28 | -------------------------------------------------------------------------------- /trees/BinarySearchTree/bst.h: -------------------------------------------------------------------------------- 1 | #include "utility.h" 2 | #include 3 | #include 4 | 5 | /* 6 | * MAW 4.10 Write routines to implement the basic binary search tree operations. 7 | */ 8 | 9 | #ifndef _BST_H 10 | #define _BST_H 11 | 12 | typedef int ET; 13 | 14 | struct TreeNode; 15 | typedef struct TreeNode *Position; 16 | typedef Position BST; 17 | 18 | BST makeEmpty(BST); 19 | Position find(ET, BST); 20 | Position findMinBST(BST); 21 | Position findMaxBST(BST); 22 | BST insert(ET, BST); 23 | BST delete(ET, BST); 24 | ET retrieve(Position); 25 | 26 | /* 27 | * Create a BST based upon the given array 28 | */ 29 | BST initializeBST(ET*, int); 30 | 31 | /* 32 | * Generate a dot file to be fed into Graphviz to display tree 33 | */ 34 | void bst_print_dot(BST, FILE*); 35 | 36 | /* 37 | * MAW 4.28 Write efficient functions that take only a pointer to the root of a binary tree T, 38 | * and compute: 39 | * a. The number of nodes in T. 40 | * b. The number of leaves in T. 41 | * c. The number of full nodes in T. 42 | */ 43 | int numNodes(BST); 44 | int numLeaves(BST); 45 | int numFullNodes(BST); 46 | 47 | /* 48 | * MAW 4.29 Write a function to generate an N-node random binary search tree with distinct keys 1 through N. 49 | */ 50 | BST randBST(int); 51 | 52 | /* 53 | * MAW 4.31 Write a function to generate a perfectly balanced binary search tree of height H with keys 1 through 2^{H+1}-1. 54 | */ 55 | BST perfectBST(int H); 56 | 57 | /* 58 | * MAW 4.32 Write a function that takes as input a binary search tree, T, and two keys k_1 and k_2, which are ordered 59 | * so that k_1 <= k_2, and prints all elements X in the tree such that k_1 <= Key(X) <= k_2. Do not assume any 60 | * information about the type of keys except that they can be ordered (consistently). 61 | */ 62 | void printRangeKeys(BST T, int k1, int k2); 63 | 64 | /* 65 | * MAW 4.35 Write a routine to list our the nodes of a binary tree in level-order. List the root, then nodes at depth 1, 66 | * followed by nodes at depth 2, and so on. You must do this in linear time. 67 | */ 68 | void levelOrder(BST); 69 | 70 | /* 71 | * MAW 4.41 Two binary trees are similar if they are both empty or both nonempty and have similar left and right subtrees. 72 | * Write a function to decide whether two binary trees are similar. 73 | * Return 1 if not similar; 0 if similar 74 | */ 75 | int similar(BST, BST); 76 | 77 | /* 78 | * Check if two binary search tree are the same in terms of structure and elements 79 | */ 80 | int same(BST T1, BST T2); 81 | 82 | /* 83 | * MAW 4.43 Show that via AVL single rotations, any binary search tree T_1 can be transformed into 84 | * another search tree T_2 (with the same keys) 85 | * Return newly transformed T1 86 | */ 87 | BST transform(BST T1, BST T2); 88 | 89 | /* 90 | * Given a binary search tree, return the inorder traversal of its nodes' values 91 | * as an array. 92 | */ 93 | int* inorderTraversal(BST root, int* returnSize); 94 | 95 | /* 96 | * Given a binary tree, you need to compute the length of the diameter of the tree. 97 | * The diameter of a binary tree is the length of the longest path between 98 | * any two nodes in a tree. This path may or may not pass through the root. 99 | * 100 | * NOTE: we use BST instead of binary tree. 101 | */ 102 | int diameterOfBST(BST root); 103 | 104 | #endif 105 | 106 | 107 | /* 108 | * A simple queue for BST functions 109 | */ 110 | #ifndef QUEUE_NODE_H 111 | #define QUEUE_NODE_H 112 | 113 | struct QueueRecord; 114 | typedef struct QueueRecord* PtrToNode; 115 | typedef struct QueueCDT* QueueADT; // naming convention: https://www.cs.bu.edu/teaching/c/queue/linked-list/types.html 116 | 117 | int isEmpty(QueueADT Q); 118 | QueueADT createQueue(); 119 | void makeEmptyQueue(QueueADT Q); 120 | void disposeQueue(QueueADT Q); 121 | void enqueue(Position elem, QueueADT Q); 122 | void dequeue(QueueADT Q); 123 | Position frontAndDequeue(QueueADT Q); 124 | 125 | #endif 126 | -------------------------------------------------------------------------------- /trees/b-tree/Makefile: -------------------------------------------------------------------------------- 1 | C_COMPILER=gcc 2 | override CFLAGS += -Wall -g 3 | 4 | # Directories 5 | ROOT = ../../ 6 | 7 | SRC_FILES=\ 8 | $(wildcard ./*.c) \ 9 | $(ROOT)utility/utility.c 10 | 11 | INC_DIRS=\ 12 | -I$(ROOT)utility/ 13 | 14 | LIBS=\ 15 | -lm 16 | 17 | OUTPUT_FILE=main 18 | 19 | .PHONY: clean 20 | .PHONY: test 21 | 22 | test: 23 | $(C_COMPILER) $(CFLAGS) $(INC_DIRS) $(LIBS) $(SRC_FILES) -o $(OUTPUT_FILE) 24 | ./$(OUTPUT_FILE) -v 25 | 26 | clean: 27 | rm -rf $(OUTPUT_FILE) 28 | rm -rf *.dot 29 | -------------------------------------------------------------------------------- /trees/b-tree/btree.h: -------------------------------------------------------------------------------- 1 | #include "utility.h" 2 | #include 3 | #include 4 | #include 5 | 6 | /* 7 | * MAW 4.37.a Write a routine to perform insertion into a B-tree. 8 | * b Write a routine to perform deletion from a B-tree. 9 | * c Modify your insertion routine so that if an attempt is made 10 | * to add into a node that already has M entries, a search is performed 11 | * for a sibling with less than M children before the node is split. 12 | */ 13 | // Here we implement B+-tree. We follow the notation from MAW to call B-tree. 14 | #ifndef _BTREE_H 15 | #define _BTREE_H 16 | 17 | typedef int ET; 18 | 19 | struct TreeNode; 20 | typedef struct TreeNode *Position; 21 | typedef Position BT; 22 | 23 | /* We destroy the BT 24 | */ 25 | void makeEmpty(BT); 26 | 27 | /* We find the leaf that contains the target element. 28 | */ 29 | Position find(ET, BT); 30 | 31 | /* Insert the element into the b-tree and return the newly formed b-tree. 32 | */ 33 | void insert(ET, BT); 34 | void delete(ET, BT); 35 | BT initializeBT(ET*, int); 36 | void bt_print_dot(BT, FILE*); 37 | 38 | #endif 39 | 40 | -------------------------------------------------------------------------------- /trees/child-sibling-pointer/Makefile: -------------------------------------------------------------------------------- 1 | C_COMPILER=gcc 2 | CFLAGS = -Wall -g 3 | 4 | # Directories 5 | ROOT = ../../ 6 | 7 | SRC_FILES=\ 8 | $(wildcard ./*.c) \ 9 | $(ROOT)utility/utility.c 10 | 11 | INC_DIRS=\ 12 | -I$(ROOT)utility/ 13 | 14 | LIBS=\ 15 | -lm 16 | 17 | OUTPUT_FILE=main 18 | 19 | .PHONY: clean 20 | .PHONY: test 21 | 22 | test: 23 | $(C_COMPILER) $(CFLAGS) $(INC_DIRS) $(LIBS) $(SRC_FILES) -o $(OUTPUT_FILE) 24 | ./$(OUTPUT_FILE) -v 25 | dot -T png -O cspt.dot 26 | 27 | clean: 28 | rm -rf $(OUTPUT_FILE) 29 | -------------------------------------------------------------------------------- /trees/child-sibling-pointer/csp.h: -------------------------------------------------------------------------------- 1 | #include "utility.h" 2 | #include 3 | #include 4 | 5 | /* 6 | * MAW 4.40 Write a procedure to traverse a tree stored with child/sibling links. 7 | */ 8 | 9 | #ifndef _CSP_H 10 | #define _CSP_H 11 | 12 | typedef char ET; 13 | 14 | struct CSPTreeNode; 15 | typedef struct CSPTreeNode *Position; 16 | typedef Position CSPT; 17 | 18 | CSPT makeEmpty(CSPT); //TODO: not implemented 19 | Position find(ET, CSPT); 20 | CSPT insert(ET, CSPT, ET, int); 21 | CSPT delete(ET, CSPT); //TODO: not implemented 22 | ET retrieve(Position); 23 | void cspt_print_dot(CSPT, FILE*); 24 | 25 | /* 26 | * MAW 4.42 Give a polynomial time algorithm to decide if two trees are isomorphic. 27 | * Return 1 if not isomorphic; 0 if isomorphic 28 | */ 29 | int isomorphic(CSPT, CSPT); 30 | 31 | #endif 32 | 33 | #ifndef QUEUE_NODE_H 34 | #define QUEUE_NODE_H 35 | 36 | struct QueueRecord; 37 | typedef struct QueueRecord* PtrToNode; 38 | typedef struct QueueCDT* QueueADT; 39 | 40 | int isEmpty(QueueADT Q); 41 | QueueADT createQueue(); 42 | void makeEmptyQueue(QueueADT Q); 43 | void disposeQueue(QueueADT Q); 44 | void enqueue(Position elem, QueueADT Q); 45 | void dequeue(QueueADT Q); 46 | Position frontAndDequeue(QueueADT Q); 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /trees/child-sibling-pointer/cspTestMain.c: -------------------------------------------------------------------------------- 1 | #include "csp.h" 2 | #include 3 | #include 4 | #include 5 | 6 | void generate_dot(CSPT); 7 | //void delete_tree(CSPT); 8 | void test_insert(); 9 | //void test_delete(); 10 | void test_isomorphic(); 11 | 12 | int 13 | main() 14 | { 15 | printf("////////////////////////////////////////////\n"); 16 | printf("// CHILD/SIBLING IMPLEMENTATION TREE TEST\n"); 17 | printf("////////////////////////////////////////////\n\n"); 18 | 19 | test_insert(); printf("\n"); 20 | test_isomorphic(); printf("\n"); 21 | //test_delete(); 22 | 23 | return 0; 24 | } 25 | 26 | void 27 | generate_dot(CSPT T) 28 | { 29 | char* dotFilename = "cspt.dot"; 30 | FILE *fp = fopen(dotFilename,"w"); 31 | cspt_print_dot(T,fp); 32 | fclose(fp); 33 | printFile(dotFilename); 34 | } 35 | 36 | /* void */ 37 | /* delete_tree(BST T) */ 38 | /* { */ 39 | /* T = makeEmpty(T); */ 40 | /* free(T); */ 41 | /* } */ 42 | 43 | void 44 | test_insert() 45 | { 46 | printf("TEST: insert\n"); 47 | CSPT T = NULL; 48 | T = insert('A', T, 'A', 0); 49 | T = insert('B', T, 'A', 1); 50 | T = insert('C', T, 'A', 1); 51 | T = insert('G', T, 'A', 1); 52 | T = insert('D', T, 'B', 1); 53 | T = insert('H', T, 'D', 1); 54 | T = insert('I', T, 'H', 0); 55 | T = insert('E', T, 'B', 1); 56 | T = insert('J', T, 'E', 1); 57 | T = insert('F', T, 'C', 1); 58 | T = insert('K', T, 'F', 1); 59 | T = insert('L', T, 'F', 1); 60 | T = insert('O', T, 'L', 1); 61 | T = insert('M', T, 'F', 1); 62 | T = insert('P', T, 'M', 1); 63 | T = insert('Q', T, 'P', 0); 64 | T = insert('R', T, 'P', 0); 65 | T = insert('N', T, 'G', 1); 66 | generate_dot(T); 67 | //delete_tree(T); 68 | } 69 | 70 | /* void */ 71 | /* test_delete() */ 72 | /* { */ 73 | /* printf("TEST: delete\n"); */ 74 | /* ET test_array[] = {3,1,4,6,9,2,5,7}; */ 75 | /* BST T = initializeBST(test_array, 8); */ 76 | /* printf("deleting the root: %d\n", 3); */ 77 | /* T = delete(3, T); */ 78 | /* generate_dot(T); */ 79 | /* delete_tree(T); */ 80 | /* } */ 81 | 82 | void 83 | test_isomorphic() 84 | { 85 | printf("TEST: isomorphic\n"); 86 | CSPT T1 = NULL; 87 | CSPT T2 = NULL; 88 | printf("Graph T1:\n"); 89 | T1 = insert('A', T1, 'A', 0); 90 | T1 = insert('B', T1, 'A', 1); 91 | T1 = insert('C', T1, 'A', 1); 92 | T1 = insert('D', T1, 'B', 1); 93 | T1 = insert('E', T1, 'B', 1); 94 | T1 = insert('F', T1, 'E', 1); 95 | T1 = insert('G', T1, 'C', 1); 96 | T1 = insert('H', T1, 'G', 1); 97 | generate_dot(T1); 98 | printf("Graph T2:\n"); 99 | T2 = insert('A', T2, 'A', 0); 100 | T2 = insert('C', T2, 'A', 1); 101 | T2 = insert('B', T2, 'C', 0); 102 | T2 = insert('G', T2, 'C', 1); 103 | T2 = insert('H', T2, 'G', 1); 104 | T2 = insert('E', T2, 'B', 1); 105 | T2 = insert('D', T2, 'E', 0); 106 | T2 = insert('F', T2, 'E', 1); 107 | generate_dot(T2); 108 | assert(isomorphic(T1,T2) == 0); 109 | printf("All pass!\n"); 110 | } 111 | -------------------------------------------------------------------------------- /trees/orderStatisticTree/Makefile: -------------------------------------------------------------------------------- 1 | C_COMPILER=gcc 2 | CFLAGS = -Wall -g 3 | 4 | # Directories 5 | ROOT = ../../ 6 | 7 | SRC_FILES=\ 8 | $(wildcard ./*.c) \ 9 | $(ROOT)utility/utility.c 10 | 11 | INC_DIRS=\ 12 | -I$(ROOT)utility/ 13 | 14 | LIBS=\ 15 | -lm 16 | 17 | OUTPUT_FILE=main 18 | 19 | .PHONY: clean 20 | .PHONY: test 21 | 22 | test: 23 | $(C_COMPILER) $(CFLAGS) $(INC_DIRS) $(LIBS) $(SRC_FILES) -o $(OUTPUT_FILE) 24 | ./$(OUTPUT_FILE) -v 25 | 26 | clean: 27 | rm -rf $(OUTPUT_FILE) 28 | -------------------------------------------------------------------------------- /trees/orderStatisticTree/ost.c: -------------------------------------------------------------------------------- 1 | #include "ost.h" 2 | 3 | struct TreeNode 4 | { 5 | ET Element; 6 | BST Left; 7 | BST Right; 8 | int NumElementsOfLeftSubtree; // number of elements in the left subtree of the current node (including the node itself) 9 | int NumElementsOfRightSubtree; // number of elements in the right subtree of the current node (not including the node itself) 10 | }; 11 | 12 | BST 13 | makeEmpty(BST T) 14 | { 15 | if (T != NULL) 16 | { 17 | makeEmpty(T->Left); 18 | makeEmpty(T->Right); 19 | free(T); 20 | } 21 | return NULL; 22 | } 23 | 24 | Position 25 | findKthSmallest(BST T, int i) 26 | { 27 | if (T == NULL) 28 | return T; 29 | if (T->NumElementsOfLeftSubtree == i) 30 | return T; 31 | else if (T->NumElementsOfLeftSubtree > i) 32 | return findKthSmallest(T->Left, i); 33 | else 34 | return findKthSmallest(T->Right, i - T->NumElementsOfLeftSubtree); 35 | } 36 | 37 | Position 38 | findKthLargest(BST T, int i) 39 | { 40 | int totalElements = T->NumElementsOfLeftSubtree + T->NumElementsOfRightSubtree; 41 | return findKthSmallest(T, 1 + totalElements-i); 42 | } 43 | 44 | Position 45 | findMin(BST T) 46 | { 47 | if (T == NULL) 48 | return NULL; 49 | else if (T->Left == NULL) 50 | return T; 51 | else 52 | return findMin(T->Left); 53 | } 54 | 55 | Position 56 | findMax(BST T) 57 | { 58 | if (T != NULL) 59 | while (T->Right != NULL) 60 | T = T->Right; 61 | return T; 62 | } 63 | 64 | BST 65 | insert(ET elem, BST T) 66 | { 67 | if (T == NULL) 68 | { 69 | T = malloc(sizeof(struct TreeNode)); 70 | T->Element = elem; 71 | T->Left = T->Right = NULL; 72 | T->NumElementsOfLeftSubtree = 1; 73 | T->NumElementsOfRightSubtree = 0; 74 | } 75 | else if (elem < T->Element) 76 | { 77 | T->NumElementsOfLeftSubtree++; 78 | T->Left = insert(elem, T->Left); 79 | } 80 | else if (elem > T->Element) 81 | { 82 | T->NumElementsOfRightSubtree++; 83 | T->Right = insert(elem, T->Right); 84 | } 85 | // else elem is in the tree already; we'll do nothing 86 | return T; 87 | } 88 | 89 | BST 90 | delete(ET elem, BST T) 91 | { 92 | Position tmpCell; 93 | 94 | if (T == NULL) 95 | fatal("Element not found"); 96 | else if (elem < T->Element) 97 | T->Left = delete(elem, T->Left); 98 | else if (elem > T->Element) 99 | T->Right = delete(elem, T->Right); 100 | else // we found the element to be deleted 101 | if (T->Left != NULL && T->Right != NULL) // two children 102 | { 103 | tmpCell = findMin(T->Right); 104 | T->Element = tmpCell->Element; 105 | T->Right = delete(T->Element, T->Right); 106 | } 107 | else // one or two children 108 | { 109 | tmpCell = T; 110 | if (T->Right == NULL) 111 | T = T->Left; 112 | else if (T->Left == NULL) 113 | T = T->Right; 114 | free(tmpCell); 115 | } 116 | return T; 117 | } 118 | 119 | ET 120 | retrieve(Position T) 121 | { 122 | if (T != NULL) 123 | return T->Element; 124 | return 0; 125 | } 126 | 127 | BST 128 | initializeBST(ET* array, int arrayLength) 129 | { 130 | BST T = NULL; 131 | int i; 132 | for(i = 0; i < arrayLength; i++) 133 | T = insert(array[i], T); 134 | return T; 135 | } 136 | 137 | static void 138 | bst_print_dot_aux(BST T, FILE* stream) 139 | { 140 | if (T != NULL) 141 | { 142 | if (T->Left != NULL) 143 | { 144 | fprintf(stream, "%d->%d;\n", T->Element, T->Left->Element); 145 | bst_print_dot_aux(T->Left, stream); 146 | } 147 | if (T->Right != NULL) 148 | { 149 | fprintf(stream, "%d->%d;\n", T->Element, T->Right->Element); 150 | bst_print_dot_aux(T->Right, stream); 151 | } 152 | } 153 | } 154 | 155 | void 156 | bst_print_dot(BST T, FILE* stream) 157 | { 158 | fprintf(stream, "digraph BinarySearchTree \{\n"); 159 | bst_print_dot_aux(T, stream); 160 | fprintf(stream,"}\n"); 161 | } 162 | -------------------------------------------------------------------------------- /trees/orderStatisticTree/ost.h: -------------------------------------------------------------------------------- 1 | #include "utility.h" 2 | #include 3 | #include 4 | 5 | // Order Statistic Tree: https://en.wikipedia.org/wiki/Order_statistic_tree 6 | #ifndef _OST_H 7 | #define _OST_H 8 | 9 | typedef int ET; 10 | 11 | struct TreeNode; 12 | typedef struct TreeNode *Position; 13 | typedef Position BST; 14 | 15 | BST makeEmpty(BST); 16 | 17 | /* 18 | * MAW 4.44 Suppose we want to add the operation FindKth to our repertoire. 19 | * The operation FindKth(T,i) returns the element in tree T with ith smallest key. 20 | * Assume all elements have distinct keys. 21 | */ 22 | // Implementation hints: 23 | // http://stackoverflow.com/questions/2329171/find-kth-smallest-element-in-a-binary-search-tree-in-optimum-way?page=1 24 | Position findKthSmallest(BST, int); 25 | 26 | /* 27 | * Returns the element in tree T with ith largest key. 28 | */ 29 | Position findKthLargest(BST, int); 30 | Position findMin(BST); 31 | Position findMax(BST); 32 | BST insert(ET, BST); 33 | BST delete(ET, BST); 34 | ET retrieve(Position); 35 | BST initializeBST(ET*, int); 36 | void bst_print_dot(BST, FILE*); 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /trees/orderStatisticTree/ostTestMain.c: -------------------------------------------------------------------------------- 1 | #include "ost.h" 2 | #include 3 | #include 4 | #include 5 | 6 | void generate_dot(BST); 7 | void delete_tree(BST); 8 | void test_findKthSmallest(); 9 | void test_findKthLargest(); 10 | 11 | int 12 | main() 13 | { 14 | printf("///////////////////////\n"); 15 | printf("// ORDER STATISTIC TREE TEST\n"); 16 | printf("///////////////////////\n\n"); 17 | 18 | test_findKthSmallest(); printf("\n"); 19 | test_findKthLargest(); printf("\n"); 20 | 21 | return 0; 22 | } 23 | 24 | void 25 | generate_dot(BST T) 26 | { 27 | char* dotFilename = "bst.dot"; 28 | FILE *fp = fopen(dotFilename,"w"); 29 | bst_print_dot(T,fp); 30 | fclose(fp); 31 | printFile(dotFilename); 32 | } 33 | 34 | void 35 | delete_tree(BST T) 36 | { 37 | T = makeEmpty(T); 38 | free(T); 39 | } 40 | 41 | void 42 | test_findKthSmallest() 43 | { 44 | printf("TEST: findKthSmallest"); 45 | ET test_array[] = {5,1,2,3,4,8,7}; 46 | BST T = initializeBST(test_array, 7); 47 | generate_dot(T); 48 | assert(retrieve(findKthSmallest(T,3)) == 3); 49 | assert(retrieve(findKthSmallest(T,5)) == 5); 50 | assert(retrieve(findKthSmallest(T,7)) == 8); 51 | printf("Pass all\n"); 52 | } 53 | 54 | void 55 | test_findKthLargest() 56 | { 57 | printf("TEST: findKthLargest"); 58 | ET test_array[] = {5,1,2,3,4,8,7}; 59 | BST T = initializeBST(test_array, 7); 60 | generate_dot(T); 61 | assert(retrieve(findKthLargest(T,5)) == 3); 62 | assert(retrieve(findKthLargest(T,3)) == 5); 63 | assert(retrieve(findKthLargest(T,1)) == 8); 64 | printf("Pass all\n"); 65 | } 66 | -------------------------------------------------------------------------------- /trees/splay/Makefile: -------------------------------------------------------------------------------- 1 | C_COMPILER=gcc 2 | CFLAGS = -Wall -g 3 | 4 | # Directories 5 | ROOT = ../../ 6 | 7 | SRC_FILES=\ 8 | $(wildcard ./*.c) \ 9 | $(ROOT)utility/utility.c 10 | 11 | INC_DIRS=\ 12 | -I$(ROOT)utility/ 13 | 14 | LIBS=\ 15 | -lm 16 | 17 | OUTPUT_FILE=main 18 | 19 | .PHONY: clean 20 | .PHONY: test 21 | 22 | test: 23 | $(C_COMPILER) $(CFLAGS) $(INC_DIRS) $(LIBS) $(SRC_FILES) -o $(OUTPUT_FILE) 24 | ./$(OUTPUT_FILE) -v 25 | 26 | clean: 27 | rm -rf $(OUTPUT_FILE) 28 | rm -rf *.dot 29 | -------------------------------------------------------------------------------- /trees/splay/splay.h: -------------------------------------------------------------------------------- 1 | #include "utility.h" 2 | #include 3 | #include 4 | 5 | #ifndef _SPLAY_H 6 | #define _SPLAY_H 7 | 8 | typedef int ET; 9 | 10 | /* 11 | * MAW 4.27 Write a program to perform random operations on splay trees. 12 | * Count the total number of rotations performed over the sequence. How 13 | * does the running time compare to AVL trees and unbalanced binary 14 | * search trees? 15 | * 16 | * NOTE: Implement Splay operations and numRotations counter and 17 | * don't bother to run the actual experimentation 18 | */ 19 | 20 | int numRotations; //count the number of rotations happened to a specific tree. 21 | 22 | struct SplayTreeNode; 23 | typedef struct SplayTreeNode *Position; 24 | typedef Position Splay; 25 | 26 | Splay makeEmpty(Splay); 27 | Position find(ET, Splay); 28 | Position findMin(Splay); 29 | Position findMax(Splay); 30 | Splay insert(ET, Splay); 31 | Splay insert2(ET, Splay); 32 | Splay delete(ET, Splay); 33 | Splay delete2(ET, Splay); 34 | ET retrieve(Position); 35 | int getNumRotations(); 36 | Splay initializeBST(ET*, int); 37 | void bst_print_dot(Splay, FILE*); 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /trees/threadedTree/Makefile: -------------------------------------------------------------------------------- 1 | C_COMPILER=gcc 2 | CFLAGS = -Wall -g 3 | 4 | # Directories 5 | ROOT = ../../ 6 | 7 | SRC_FILES=\ 8 | $(wildcard ./*.c) \ 9 | $(ROOT)utility/utility.c 10 | 11 | INC_DIRS=\ 12 | -I$(ROOT)utility/ 13 | 14 | LIBS=\ 15 | -lm 16 | 17 | OUTPUT_FILE=main 18 | 19 | .PHONY: clean 20 | .PHONY: test 21 | 22 | test: 23 | $(C_COMPILER) $(CFLAGS) $(INC_DIRS) $(LIBS) $(SRC_FILES) -o $(OUTPUT_FILE) 24 | ./$(OUTPUT_FILE) -v 25 | 26 | clean: 27 | rm -rf $(OUTPUT_FILE) 28 | -------------------------------------------------------------------------------- /trees/threadedTree/tt.h: -------------------------------------------------------------------------------- 1 | #include "utility.h" 2 | #include 3 | #include 4 | #include 5 | 6 | // threaded binary tree: https://en.wikipedia.org/wiki/Threaded_binary_tree 7 | // Technically speaking, this is a double threaded BST implementation. 8 | 9 | /* 10 | * MAW 4.45 Since a binary search tree with N nodes has N+1 NULL pointers, 11 | * half the space allocated in a binary search tree for pointer information is wasted. 12 | * Suppose that if a node has a NULL left child, we make its left child point to 13 | * its inorder predecessor, and if a node has a NULL right child, we make its right child 14 | * point to its inorder successor. This is known as a threaded tree and the extra pointers 15 | * are called threads. 16 | * 17 | * The advantage of threaded tree is you can do tree traversals somewhat easier and without recursion. 18 | * The disadvantage is that it reeks of old-style hacking. 19 | */ 20 | 21 | #ifndef _TT_H 22 | #define _TT_H 23 | 24 | typedef int ET; 25 | struct TreeNode; 26 | typedef struct TreeNode *Position; 27 | typedef Position TT; 28 | 29 | TT createEmptyTT(); 30 | TT makeEmpty(TT); 31 | Position findMin(TT); 32 | Position findMax(TT); 33 | TT insert(ET, TT); 34 | TT delete(ET, TT); 35 | ET retrieve(Position); 36 | TT initializeTT(ET*, int); 37 | void tt_print_dot(TT, FILE*); 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /trees/threadedTree/ttTestMain.c: -------------------------------------------------------------------------------- 1 | #include "tt.h" 2 | #include 3 | #include 4 | #include 5 | 6 | void generate_dot(TT); 7 | void delete_tree(TT); 8 | void test_initializeTT(); 9 | void test_delete(); 10 | 11 | int 12 | main() 13 | { 14 | printf("///////////////////////\n"); 15 | printf("// THREADED TREE TEST\n"); 16 | printf("///////////////////////\n\n"); 17 | 18 | test_initializeTT(); printf("\n"); 19 | test_delete(); printf("\n"); 20 | 21 | return 0; 22 | } 23 | 24 | void 25 | generate_dot(TT T) 26 | { 27 | char* dotFilename = "tt.dot"; 28 | FILE *fp = fopen(dotFilename,"w"); 29 | tt_print_dot(T,fp); 30 | fclose(fp); 31 | printFile(dotFilename); 32 | } 33 | 34 | void 35 | delete_tree(TT T) 36 | { 37 | T = makeEmpty(T); 38 | free(T); 39 | } 40 | 41 | void 42 | test_initializeTT() 43 | { 44 | printf("TEST: initializeTT\n"); 45 | ET test_array[] = {20,1,9,8,7,5,6}; 46 | TT T = initializeTT(test_array, 7); 47 | generate_dot(T); 48 | delete_tree(T); 49 | } 50 | 51 | void 52 | test_delete() 53 | { 54 | printf("TEST: delete\n"); 55 | ET test_array[] = {20,1,9,8,7,5,6}; 56 | TT T = initializeTT(test_array, 7); 57 | T = delete(20, T); 58 | generate_dot(T); 59 | delete_tree(T); 60 | } 61 | -------------------------------------------------------------------------------- /union-find/disjSet.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "utility.h" 4 | 5 | /* 6 | * Disjoint set data structure interface 7 | */ 8 | #define NumSets 10 9 | 10 | #ifndef _DisjSet_H 11 | 12 | typedef int DisjSet[NumSets + 1]; 13 | typedef int SetType; 14 | typedef int ElementType; 15 | 16 | /* 17 | * Initialize the disjoint set 18 | */ 19 | void initialize(DisjSet); 20 | 21 | /* 22 | * Replace equivalence classes containing two elements with their union 23 | * 24 | * NOTE: there are some minor changes compared to MAW: 25 | * 1. Unlike MAW implementation, we pass in two elements instead of the 26 | * actual class name (i.e., root if we use quick-union implementation) 27 | * 2. Unlike MAW, we merge the equvalience class containing 1st element into 28 | * equivalence class containing 2nd element. This statement holds for 29 | * quick-find, quick-union and not true for smart-union (union-by-size) 30 | * and path compression. 31 | */ 32 | void setUnion(DisjSet, ElementType, ElementType); 33 | 34 | /* 35 | * Returns the name of the set (that is, the equivalence class) containing 36 | * a given element 37 | */ 38 | SetType find(ElementType, DisjSet); 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /union-find/quick-find/Makefile: -------------------------------------------------------------------------------- 1 | C_COMPILER=gcc 2 | CFLAGS = -Wall -g 3 | 4 | # Directories 5 | ROOT = ../../ 6 | 7 | SRC_FILES=\ 8 | $(wildcard ./*.c) \ 9 | $(ROOT)utility/utility.c 10 | 11 | INC_DIRS=\ 12 | -I$(ROOT)utility/ \ 13 | -I../ 14 | 15 | LIBS=\ 16 | -lm 17 | 18 | OUTPUT_FILE=main 19 | 20 | .PHONY: clean 21 | .PHONY: test 22 | 23 | test: 24 | $(C_COMPILER) $(CFLAGS) $(INC_DIRS) $(LIBS) $(SRC_FILES) -o $(OUTPUT_FILE) 25 | ./$(OUTPUT_FILE) -v 26 | 27 | clean: 28 | rm -rf $(OUTPUT_FILE) 29 | -------------------------------------------------------------------------------- /union-find/quick-find/quickFind.c: -------------------------------------------------------------------------------- 1 | #include "disjSet.h" 2 | 3 | 4 | /* 5 | * Initialize the disjoint set in quick-find algorithm 6 | * 7 | * NOTE: The implementation is different from MAW's. In MAW, the equivalence 8 | * class name is indicated by 0 and thus, during the initialization, all the 9 | * S[i] are initialized to 0. However, in this implementation, the equivalence 10 | * class name is indicated by the element position. That's why we initialize 11 | * S[i] = i. 12 | */ 13 | void 14 | initialize(DisjSet S) 15 | { 16 | int i; 17 | for(i = 0; i < NumSets; i++) 18 | { 19 | S[i] = i; 20 | } 21 | } 22 | 23 | /* 24 | * Implements find operation in quick-find algorithm 25 | */ 26 | SetType 27 | find(ElementType X, DisjSet S) 28 | { 29 | return S[X]; 30 | } 31 | 32 | /* 33 | * Implements union operation in quick-find algorithm 34 | * 35 | * NOTE: we merge the equivalence class containing p into q 36 | */ 37 | void 38 | setUnion(DisjSet S, ElementType p, ElementType q) 39 | { 40 | int i; 41 | SetType pType = find(p, S); // get the class name for p 42 | SetType qType = find(q, S); // get the class name for q 43 | for(i = 0; i < NumSets; i++) 44 | { 45 | if(S[i] == pType) S[i] = qType; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /union-find/quick-find/testquickFind.c: -------------------------------------------------------------------------------- 1 | #include "disjSet.h" 2 | 3 | int 4 | main(void) 5 | { 6 | DisjSet S; 7 | 8 | printf("Initialize a disjoint set with 10 items\n"); 9 | initialize( S ); 10 | printf("Union 1-2\n"); setUnion(S, 1, 2); 11 | printf("Union 3-4\n"); setUnion(S, 3, 4); 12 | printf("Union 5-6\n"); setUnion(S, 5, 6); 13 | printf("Union 7-8\n"); setUnion(S, 7, 8); 14 | printf("Union 7-9\n"); setUnion(S, 7, 9); 15 | printf("Union 2-8\n"); setUnion(S, 2, 8); 16 | printf("Union 0-5\n"); setUnion(S, 0, 5); 17 | printf("Union 1-9\n"); setUnion(S, 1, 9); 18 | printf("the connected components are: \n"); 19 | printArray(S, NumSets); // 6, 9, 9, 4, 4, 6, 6, 9, 9, 9, 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /union-find/quick-union/Makefile: -------------------------------------------------------------------------------- 1 | C_COMPILER=gcc 2 | CFLAGS = -Wall -g 3 | 4 | # Directories 5 | ROOT = ../../ 6 | 7 | SRC_FILES=\ 8 | $(wildcard ./*.c) \ 9 | $(ROOT)utility/utility.c 10 | 11 | INC_DIRS=\ 12 | -I$(ROOT)utility/ \ 13 | -I../ 14 | 15 | LIBS=\ 16 | -lm 17 | 18 | OUTPUT_FILE=main 19 | 20 | .PHONY: clean 21 | .PHONY: test 22 | 23 | test: 24 | $(C_COMPILER) $(CFLAGS) $(INC_DIRS) $(LIBS) $(SRC_FILES) -o $(OUTPUT_FILE) 25 | ./$(OUTPUT_FILE) -v 26 | 27 | clean: 28 | rm -rf $(OUTPUT_FILE) 29 | -------------------------------------------------------------------------------- /union-find/quick-union/quickUnion.c: -------------------------------------------------------------------------------- 1 | #include "disjSet.h" 2 | 3 | 4 | /* 5 | * Initialize the disjoint set in quick-union algorithm 6 | * 7 | * NOTE: The implementation is different from MAW's. In MAW, the equivalence 8 | * class name is indicated by 0 and thus, during the initialization, all the 9 | * S[i] are initialized to 0. However, in this implementation, the equivalence 10 | * class name is indicated by the element position. That's why we initialize 11 | * S[i] = i. 12 | */ 13 | void 14 | initialize(DisjSet S) 15 | { 16 | int i; 17 | for(i = 0; i < NumSets; i++) 18 | { 19 | S[i] = i; 20 | } 21 | } 22 | 23 | /* 24 | * Implements find operation in quick-union algorithm 25 | */ 26 | SetType 27 | find(ElementType X, DisjSet S) 28 | { 29 | if (S[X] == X) 30 | return X; 31 | else 32 | return find(S[X], S); 33 | } 34 | 35 | /* 36 | * Implements union operation in quick-union algorithm 37 | * 38 | * NOTE: we merge the equivalence class containing p into q 39 | */ 40 | void 41 | setUnion(DisjSet S, ElementType p, ElementType q) 42 | { 43 | SetType pType = find(p, S); // get the class name for p 44 | SetType qType = find(q, S); // get the class name for q 45 | S[pType] = qType; 46 | } 47 | -------------------------------------------------------------------------------- /union-find/quick-union/testquickUnion.c: -------------------------------------------------------------------------------- 1 | #include "disjSet.h" 2 | 3 | int 4 | main(void) 5 | { 6 | DisjSet S; 7 | 8 | printf("Initialize a disjoint set with 10 items\n"); 9 | initialize( S ); 10 | printf("Union 1-2\n"); setUnion(S, 1, 2); 11 | printf("Union 3-4\n"); setUnion(S, 3, 4); 12 | printf("Union 5-6\n"); setUnion(S, 5, 6); 13 | printf("Union 7-8\n"); setUnion(S, 7, 8); 14 | printf("Union 7-9\n"); setUnion(S, 7, 9); 15 | printf("Union 2-8\n"); setUnion(S, 2, 8); 16 | printf("Union 0-5\n"); setUnion(S, 0, 5); 17 | printf("Union 1-9\n"); setUnion(S, 1, 9); 18 | printf("the connected components are: \n"); 19 | printArray(S, NumSets); // 6, 2, 9, 4, 4, 6, 6, 8, 9, 9 20 | /* 21 | * The visualization of the result of operations above: 22 | * 4 6 9 23 | * / / \ / \ 24 | * 3 5 0 8 2 25 | * / / 26 | * 7 1 27 | */ 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /union-find/smart-union-with-path-compression/Makefile: -------------------------------------------------------------------------------- 1 | C_COMPILER=gcc 2 | CFLAGS = -Wall -g 3 | 4 | # Directories 5 | ROOT = ../../ 6 | 7 | SRC_FILES=\ 8 | $(wildcard ./*.c) \ 9 | $(ROOT)utility/utility.c 10 | 11 | INC_DIRS=\ 12 | -I$(ROOT)utility/ \ 13 | -I../ 14 | 15 | LIBS=\ 16 | -lm 17 | 18 | OUTPUT_FILE=main 19 | 20 | .PHONY: clean 21 | .PHONY: test 22 | 23 | test: 24 | $(C_COMPILER) $(CFLAGS) $(INC_DIRS) $(LIBS) $(SRC_FILES) -o $(OUTPUT_FILE) 25 | ./$(OUTPUT_FILE) -v 26 | 27 | clean: 28 | rm -rf $(OUTPUT_FILE) 29 | -------------------------------------------------------------------------------- /union-find/smart-union-with-path-compression/smartUnion.c: -------------------------------------------------------------------------------- 1 | #include "disjSet.h" 2 | 3 | /* 4 | * smart-union is also called weighted quick-union. The goal is to modify the 5 | * quick-union to avoid tall trees. There are two variations 6 | * in this category: 1. union-by-size 2. union-by-height. 7 | * 8 | * In union-by-size, we keep track of size of each tree (i.e. number of objects) 9 | * and balance the tree by linking root of smaller tree to root of larger tree. 10 | * In union-by-height, we keep track of the height of each tree and perform unions 11 | * by making the shallow tree a subtree of the deeper tree. Since the height of a 12 | * tree increases only when two equally deep trees are joined (and then the height 13 | * goes up by one). Thus, union-by height is a trivial modification of union-by-size. 14 | * 15 | * We implement union-by-size in this source file. Union-by-height implementation 16 | * see MAW p.271. 17 | * 18 | * Like union-by-size as a way to imrpove union operation, path compression is 19 | * a way to improve find operation. The effect of path compression is that 20 | * every node on the path from X to the root has its parent changed to the root. 21 | * Path compression is independent of the strategy used to perform Unions. In other 22 | * words, we can use path compression in combination with union-by-size or union-by-height. 23 | */ 24 | 25 | /* 26 | * Initialize the disjoint set in smart-union algorithm 27 | * 28 | * We need to keep track of the size of each tee. Since we are really just using 29 | * an array, we can have the array entry of each root contain the negative of the size 30 | * of its tree. Thus, initially the array representation of the tree is all -1s. 31 | */ 32 | void 33 | initialize(DisjSet S) 34 | { 35 | int i; 36 | for(i = 0; i < NumSets; i++) 37 | { 38 | S[i] = -1; 39 | } 40 | } 41 | 42 | /* 43 | * Implements find operation in path compression 44 | * 45 | * NOTE: The only change to the Find routine is that S[X] is made equal to 46 | * the value returned by Find; thus after the root of the set is found 47 | * recursively, X is made to point directly to it. This occurs recursively 48 | * to every node on the path to the root, so this implements path compression. 49 | */ 50 | SetType 51 | find(ElementType X, DisjSet S) 52 | { 53 | if (S[X] <= 0) 54 | return X; 55 | else 56 | return S[X] = find(S[X], S); 57 | } 58 | 59 | /* 60 | * Implements union operation in smart-union algorithm 61 | * 62 | * NOTE: another way of impelementation is to use a separate array to keep track 63 | * of the size of each corresponding array entry. Sedgewick uses this implementation. 64 | */ 65 | void 66 | setUnion(DisjSet S, ElementType p, ElementType q) 67 | { 68 | SetType pType = find(p, S); // get the class name for p 69 | SetType qType = find(q, S); // get the class name for q 70 | if (S[pType] < S[qType]) // class containing p is deeper 71 | { 72 | S[pType] += S[qType]; // "+=" because array entry of each root contain the negative of the size of its tree 73 | S[qType] = pType; // merge class containing q into class containing q 74 | } 75 | else if (S[qType] < S[pType] || // class containing q is deeper 76 | pType != qType) // when their height are the same (i.e. S[qType] = S[pType]), we only do merge if two given elements are in different class 77 | { 78 | S[qType] += S[pType]; 79 | S[pType] = qType; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /union-find/smart-union-with-path-compression/testsmartUnion.c: -------------------------------------------------------------------------------- 1 | #include "disjSet.h" 2 | 3 | int 4 | main(void) 5 | { 6 | DisjSet S; 7 | 8 | printf("Initialize a disjoint set with 10 items\n"); 9 | initialize( S ); 10 | printf("Union 1-2\n"); setUnion(S, 1, 2); 11 | printf("Union 3-4\n"); setUnion(S, 3, 4); 12 | printf("Union 5-6\n"); setUnion(S, 5, 6); 13 | printf("Union 7-8\n"); setUnion(S, 7, 8); 14 | printf("Union 7-9\n"); setUnion(S, 7, 9); 15 | printf("Union 2-8\n"); setUnion(S, 2, 8); 16 | printf("Union 0-5\n"); setUnion(S, 0, 5); 17 | printf("Union 1-9\n"); setUnion(S, 1, 9); 18 | printf("the connected components are: \n"); 19 | printArray(S, NumSets); // with union-by-size only: 6, 2, 8, 4, -2, 6, -3, 8, -5, 8, 20 | // union-by-size with path compression: 6, 8, 8, 4, -2, 6, -3, 8, -5, 8, 21 | /* 22 | * Visualization of the result of union operations above 23 | * with union-by-size only: 24 | * 25 | * 4 6 8 26 | * / / / |\ 27 | * 3 5 7 9 2 28 | * / \ 29 | * 0 1 30 | * with union-by-size and path compression: 31 | * 32 | * 4 6 8 33 | * / / /|\ \ 34 | * 3 5 7 9 2 1 35 | * / 36 | * 0 37 | */ 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /utility/Makefile: -------------------------------------------------------------------------------- 1 | C_COMPILER=gcc 2 | CFLAGS = -Wall -g 3 | 4 | SRC_FILES=\ 5 | $(wildcard ./*.c) 6 | OUTPUT_FILE=main 7 | LIBS = -lm 8 | 9 | .PHONY: clean 10 | .PHONY: test 11 | 12 | test: 13 | $(C_COMPILER) $(CFLAGS) $(SRC_FILES) $(LIBS) -o $(OUTPUT_FILE) 14 | ./$(OUTPUT_FILE) -v 15 | 16 | clean: 17 | rm -rf $(OUTPUT_FILE) 18 | -------------------------------------------------------------------------------- /utility/utility.h: -------------------------------------------------------------------------------- 1 | #include "math.h" 2 | #include "stdio.h" 3 | #include "stdlib.h" 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | 10 | #ifndef BOOLEAN 11 | #define BOOLEAN 12 | typedef enum { false, true } bool; 13 | #endif 14 | 15 | ///////////////////////////////// 16 | // MATHEMATICS RELATED 17 | //////////////////////////////// 18 | 19 | /* Assumes 0 <= max <= RAND_MAX 20 | * Returns in the closed interval [0, max] 21 | */ 22 | //from: http://stackoverflow.com/questions/2509679/how-to-generate-a-random-number-from-within-a-range 23 | long random_at_most(long max); 24 | 25 | /* count number of digits for a number 26 | */ 27 | int countDigits(int number); 28 | 29 | /* chunk a number based upon the "start" position and "end" position and return the number in between (inclusive) 30 | * Start position begins from "0" from the most significant bit. 31 | * For example: number = 123456789, 32 | * start = 0, end = 2, will give 123 in return. 33 | * start = 3, end = 5, will give 456 in return. 34 | * start = 6, end = 8, will give 789 in return. 35 | */ 36 | int chunk_number(int number, int start, int end); 37 | 38 | /* 39 | * return the bigger value of two input 40 | */ 41 | int max(int a, int b); 42 | 43 | /* 44 | * return the smaller value of two input 45 | */ 46 | int min(int a, int b); 47 | 48 | 49 | /* 50 | * swap values hold by a and b 51 | */ 52 | void swap(int* a, int* b); 53 | 54 | /* 55 | * generate a permutation of the given array 56 | */ 57 | // The algorithm is from MAW 2.7, which references 58 | // J. Bentley, "Programming Pearls," Communications of the ACM 30 (1987), 754-757. 59 | void permutation(int* array, int length); 60 | 61 | /* 62 | * generate a list of prime numbers that is below given integer n 63 | */ 64 | // Algorithm: https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes 65 | // Illustration: http://www.geeksforgeeks.org/sieve-of-eratosthenes/ 66 | // Another algorithm: http://www.geeksforgeeks.org/sieve-sundaram-print-primes-smaller-n/ (not used) 67 | int* primeList(int n); 68 | 69 | /* 70 | * Find the nearest Prime greater than the given number n. 71 | */ 72 | // http://www.geeksforgeeks.org/nearest-prime-less-given-number-n/ 73 | int nearestPrime(int n); 74 | 75 | ///////////////////////////////// 76 | // MISC RELATED 77 | //////////////////////////////// 78 | 79 | /* We perform the binary search and 80 | * return the smallest index i in the sorted array such that elem <= a[i] 81 | * (or n if there is no such index) 82 | */ 83 | int searchElement(int elem, int *a, int n); 84 | 85 | /* print array 86 | */ 87 | void printArray(int array[], int length); 88 | 89 | /* 90 | * Print out the content reading from file 91 | */ 92 | void printFile(char*); 93 | 94 | /* A function for fatal errors 95 | */ 96 | void fatal(char *); 97 | 98 | /* 99 | * Calculate the array Length; check INT_MAX as the end of array marker. 100 | */ 101 | int arrayLength(int *); 102 | 103 | /* 104 | * return the index of the array which contains 105 | * the minimum element of the array 106 | */ 107 | int findMin(int* array, int arrayLength); 108 | 109 | /* 110 | * return the infex of the array which contains 111 | * the maximum element of the array 112 | */ 113 | int findMax(int* array, int arrayLength); 114 | 115 | //////////////////////////////// 116 | // I/O RELATED 117 | //////////////////////////////// 118 | 119 | /* get the file extension for the given filename 120 | */ 121 | char *get_filename_ext(char *filename); 122 | -------------------------------------------------------------------------------- /utility/utilityTestMain.c: -------------------------------------------------------------------------------- 1 | #include "utility.h" 2 | #include 3 | 4 | void test_chunk_number(); 5 | void test_permutations(); 6 | void test_searchElement(); 7 | void test_primeList(); 8 | void test_nearestPrime(); 9 | void test_findMin(); 10 | 11 | int main() 12 | { 13 | printf("///////////////////////\n"); 14 | printf("// UTILITY FUNCTIONS TEST\n"); 15 | printf("///////////////////////\n\n"); 16 | 17 | test_chunk_number(); printf("=============\n"); 18 | test_permutations(); printf("=============\n"); 19 | test_primeList(); printf("=============\n"); 20 | test_searchElement(); printf("=============\n"); 21 | test_nearestPrime(); printf("=============\n"); 22 | test_findMin(); printf("=============\n"); 23 | 24 | return 0; 25 | } 26 | 27 | void 28 | test_chunk_number() 29 | { 30 | int a = 123456789; 31 | printf("TEST: chunk_number\n"); 32 | 33 | /* printf("original number: %d\n", a); */ 34 | /* int first_three_digit = a / (int)pow(10,6); */ 35 | /* printf("first three digit: %d\n", first_three_digit); */ 36 | /* int first_six_digit = a / (int)pow(10,3); */ 37 | /* printf("middle three digit: %d\n", first_six_digit - first_six_digit / (int)pow(10,3) * (int)pow(10,3) ); */ 38 | /* int last_six_digit = (a - a / (int)pow(10,6) * (int)pow(10,6)); */ 39 | /* printf("last three digit: %d\n", last_six_digit - last_six_digit / (int)pow(10,3) * (int)pow(10,3)); */ 40 | 41 | printf("Original number: %d\n", a); 42 | int res; 43 | res = chunk_number(a, 0, 2); 44 | assert(res == 123); 45 | printf("[0:2] digits: %d\n", res); 46 | res = chunk_number(a, 3, 5); 47 | assert(res == 456); 48 | printf("[3:5] digits: %d\n", res); 49 | res = chunk_number(a, 6, 8); 50 | assert(res == 789); 51 | printf("[6:8] digits: %d\n", res); 52 | res = chunk_number(a, 2, 5); 53 | assert(res == 3456); 54 | printf("[2:5] digits: %d\n", res); 55 | res = chunk_number(a, 0, 5); 56 | assert(res == 123456); 57 | printf("[0:5] digits: %d\n", res); 58 | a = 17502605; 59 | printf("original number: %d\n", a); 60 | res = chunk_number(a, 0, 2); 61 | assert(res == 175); 62 | printf("[0:2] digits: %d\n", res); 63 | res = chunk_number(a, 3, 5); 64 | assert(res == 26); 65 | printf("[3:5] digits: %d\n", res); 66 | res = chunk_number(a, 6, 7); 67 | assert(res == 5); 68 | printf("[6:7] digits: %d\n", res); 69 | } 70 | 71 | void 72 | test_permutations() 73 | { 74 | printf("TEST: permutations\n"); 75 | int *array = malloc(5 * sizeof(int)); 76 | permutation(array, 5); 77 | printArray(array, 5); 78 | } 79 | 80 | void 81 | test_primeList() 82 | { 83 | printf("TEST: primeList\n"); 84 | int* array = primeList(30); 85 | printf("The list of primes below %d are: \n", 30); 86 | printArray(array,arrayLength(array)); 87 | free(array); 88 | } 89 | 90 | void 91 | test_nearestPrime() 92 | { 93 | printf("TEST: nearestPrime\n"); 94 | printf("Nearest Prime around 20 is: %d\n", nearestPrime(20)); 95 | } 96 | 97 | void 98 | test_searchElement() 99 | { 100 | printf("TEST: searchElement\n"); 101 | int array[10] = {0, 4, 5, 6, 20, 21, 50, 79, 81, 100}; 102 | printf("array: "); 103 | printArray(array, 10); 104 | printf("Index for 2 is: %d\n", searchElement(2, array, 10)); 105 | printf("Index for 4 is: %d\n", searchElement(4, array, 10)); 106 | printf("Index for 6 is: %d\n", searchElement(6, array, 10)); 107 | printf("Index for 20 is: %d\n", searchElement(20, array, 10)); 108 | printf("Index for 30 is: %d\n", searchElement(30, array, 10)); 109 | printf("Index for 90 is: %d\n", searchElement(90, array, 10)); 110 | } 111 | 112 | void 113 | test_findMin() 114 | { 115 | printf("TEST: findMin\n"); 116 | int array[10] = {0, 4, 5, 6, 20, 21, 50, 79, 81, 100}; 117 | printf("array: "); 118 | printArray(array, 10); 119 | printf("Min: %d\n", array[findMin(array, 10)]); 120 | } 121 | --------------------------------------------------------------------------------