├── adt ├── BIT.cpp ├── circular_queue.h ├── stack.h ├── linked_list.h ├── priority_queue.h ├── binary_search_tree.h ├── hash.h ├── stack.c ├── tree.cpp ├── circular_queue.c ├── hash.c ├── linked_list.c ├── priority_queue.c └── binary_search_tree.c ├── README.md ├── .gitattributes ├── algorithm ├── insert_sort.c ├── selection_sort.c ├── bubble_sort.c ├── qsort.c ├── AstarLayer.h └── AstarLayer.cpp ├── test ├── stack_test.c ├── circular_queue_test.c ├── linked_list_test.c ├── binary_search_tree_test.c ├── hash_test.c └── priority_queue_test.c └── .gitignore /adt/BIT.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/booirror/data-structures-and-algorithm-in-c/HEAD/adt/BIT.cpp -------------------------------------------------------------------------------- /adt/circular_queue.h: -------------------------------------------------------------------------------- 1 | #ifndef _CIRCULAR_QUEUE_H 2 | #define _CIRCULAR_QUEUE_H 3 | 4 | 5 | struct queue_tag; 6 | typedef struct queue_tag *queue; 7 | typedef int element_type; 8 | queue queue_create(); 9 | 10 | void queue_destroy(queue * qtr); 11 | 12 | void queue_enqueue(queue q, element_type e); 13 | 14 | element_type queue_dequeue(queue q); 15 | 16 | int queue_is_empty(queue q); 17 | 18 | int queue_is_full(queue q); 19 | 20 | #endif -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | DATA STRUCTURES IN A GO!! 2 | 3 | 4 | 5 | ADT 6 | ---------------------------- 7 | 8 | - Linked List 9 | - Stack 10 | - Queue 11 | - binary search tree 12 | - binary index tree 13 | - hash(closed hash table using linear probing) 14 | - priority queue(binary heap) 15 | 16 | Algorithm 17 | -------- 18 | - bubble sort 19 | - selection sort 20 | - insertion sort 21 | - quick sort 22 | - merge sort 23 | - heap sort 24 | - A*(C++) 25 | 26 | 27 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /adt/stack.h: -------------------------------------------------------------------------------- 1 | #ifndef ADT_STACK_H_ 2 | #define ADT_STACK_H_ 3 | 4 | #define SIZE 100 5 | struct stack_tag; 6 | typedef int element_type; 7 | typedef struct stack_tag *stack; 8 | 9 | stack stack_create(); 10 | 11 | void stack_destroy(stack* s); 12 | 13 | element_type stack_top(stack s); 14 | 15 | void stack_pop(stack s); 16 | 17 | void stack_push(stack s, element_type e); 18 | 19 | int stack_size(stack s); 20 | 21 | int stack_is_empty(stack s); 22 | 23 | #endif -------------------------------------------------------------------------------- /algorithm/insert_sort.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | 4 | void insertion_sort(int a[], int n) 5 | { 6 | int i,j,tmp; 7 | for (i = 1; i < n; i++) { 8 | tmp = a[i]; 9 | for (j = i - 1; j >= 0 && a[j] > tmp; j--) { 10 | a[j+1] = a[j]; 11 | } 12 | a[j+1] = tmp; 13 | } 14 | } 15 | 16 | int main() 17 | { 18 | int i = 0; 19 | int ar[6] = {4, 22, 11, 77, 33, 41}; 20 | insertion_sort(ar, 6); 21 | for (; i < 6; i++) { 22 | printf("%d ", ar[i]); 23 | } 24 | puts("\n"); 25 | return 0; 26 | } -------------------------------------------------------------------------------- /algorithm/selection_sort.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void selection_sort(int a[], int n) 4 | { 5 | int i, j, k; 6 | for (i = 0; i< n-1; i++) { 7 | k = i; 8 | for (j = i+1; j < n; j++) { 9 | if (a[k] > a[j]) 10 | k = j; 11 | } 12 | if (k != i) { 13 | int tmp = a[i]; 14 | a[i] = a[k]; 15 | a[k] = tmp; 16 | } 17 | } 18 | } 19 | 20 | int main() 21 | { 22 | int i = 0; 23 | int ar[6] = {4, 22, 11, 77, 33, 41}; 24 | selection_sort(ar, 6); 25 | for (; i < 6; i++) { 26 | printf("%d ", ar[i]); 27 | } 28 | puts("\n"); 29 | return 0; 30 | } -------------------------------------------------------------------------------- /algorithm/bubble_sort.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void bubble_sort(int array[], int n) 4 | { 5 | int i,j,tmp; 6 | for (i = 0; i < n - 1; i++) { 7 | for (j = 0; j < n -1 -i; j++) { 8 | if (array[j] > array[j+1]) { 9 | tmp = array[j+1]; 10 | array[j+1] = array[j]; 11 | array[j] = tmp; 12 | } 13 | } 14 | } 15 | } 16 | 17 | int main(int argc, char const *argv[]) 18 | { 19 | int i = 0; 20 | int ar[6] = {4, 22, 11, 77, 33, 41}; 21 | bubble_sort(ar, 6); 22 | for (; i < 6; i++) { 23 | printf("%d ", ar[i]); 24 | } 25 | puts("\n"); 26 | return 0; 27 | } -------------------------------------------------------------------------------- /test/stack_test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "../adt/stack.h" 4 | 5 | int main() 6 | { 7 | stack s = stack_create(); 8 | stack as = stack_create(); 9 | assert(stack_is_empty(s)); 10 | stack_push(s, 3); 11 | assert(1 == stack_size(s)); 12 | stack_push(s, 5); 13 | assert(5 == stack_top(s)); 14 | stack_push(as, 10); 15 | stack_pop(s); 16 | assert(stack_size(s) == stack_size(as)); 17 | printf("3 = [%d], 10 = [%d]\n", stack_top(s), stack_top(as)); 18 | stack_destroy(&s); 19 | stack_destroy(&as); 20 | assert(s == NULL); 21 | return 0; 22 | } -------------------------------------------------------------------------------- /test/circular_queue_test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "../adt/circular_queue.h" 4 | 5 | int main() 6 | { 7 | int i; 8 | queue q = queue_create(); 9 | assert(queue_is_empty(q)); 10 | queue_enqueue(q, 3); 11 | assert(queue_dequeue(q) == 3); 12 | assert(queue_is_empty(q)); 13 | for (i= 0; i < 99; i++) { 14 | queue_enqueue(q, i); 15 | } 16 | assert(queue_is_full(q)); 17 | assert(queue_dequeue(q) == 0); 18 | queue_enqueue(q, 1); 19 | queue_enqueue(q, 1); 20 | assert(queue_is_full(q)); 21 | queue_destroy(&q); 22 | assert(q == NULL); 23 | return 0; 24 | } -------------------------------------------------------------------------------- /test/linked_list_test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "../adt/linked_list.h" 4 | 5 | void print_list(LIST L) 6 | { 7 | while (L->next != NULL) { 8 | printf("%d ", L->next->element); 9 | L = L->next; 10 | } 11 | printf("\n"); 12 | } 13 | 14 | int main() 15 | { 16 | LIST list = list_create(); 17 | assert(list_is_empty(list)); 18 | list_insert_header(3, list); 19 | assert(!list_is_empty(list)); 20 | position p = list_find(3, list); 21 | assert(list_is_last(p, list)); 22 | list_insert_header(4, list); 23 | list_insert_header(5, list); 24 | print_list(list); 25 | list_reverse(list); 26 | print_list(list); 27 | list_delete(5, list); 28 | assert(list_find(5, list) == NULL); 29 | return 0; 30 | } -------------------------------------------------------------------------------- /test/binary_search_tree_test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "../adt/binary_search_tree.h" 4 | 5 | static void print_node(node_ptr p) 6 | { 7 | printf("%d ", p->data); 8 | } 9 | 10 | static void print_bst(bstree bst) 11 | { 12 | bst_inorder_traversal(bst, print_node); 13 | printf("\n"); 14 | } 15 | 16 | int main(int argc, char const *argv[]) 17 | { 18 | int a[6] = {9, 4, 11, 16, 14, 7}; 19 | bstree bst = bst_create(a, 6); 20 | print_bst(bst); 21 | bst_insert(bst, 8); 22 | print_bst(bst); 23 | node_ptr f = bst_find(bst, 4); 24 | node_ptr m = bst_min_element(bst); 25 | assert(f == m); 26 | bst = bst_delete(bst, 11); 27 | print_bst(bst); 28 | f = bst_find(bst, 11); 29 | assert(f == NULL); 30 | bst_destroy(&bst); 31 | assert(bst == NULL); 32 | return 0; 33 | } -------------------------------------------------------------------------------- /adt/linked_list.h: -------------------------------------------------------------------------------- 1 | #ifndef _linked_list_h_ 2 | #define _linked_list_h_ 3 | 4 | typedef int element_type; 5 | typedef struct node *node_ptr; 6 | 7 | struct node { 8 | element_type element; 9 | node_ptr next; 10 | }; 11 | 12 | typedef node_ptr LIST; 13 | typedef node_ptr position; 14 | 15 | LIST list_create(); 16 | 17 | void list_destroy(LIST *L); 18 | 19 | void fatal_error(const char* errmsg); 20 | 21 | int list_is_empty(LIST L); 22 | 23 | int list_is_last(position p, LIST L); 24 | 25 | position list_find(element_type x, LIST L); 26 | 27 | void list_reverse(LIST L); 28 | 29 | void list_insert(element_type x, LIST L, position p); 30 | 31 | void list_insert_header(element_type x, LIST L); 32 | 33 | void list_delete(element_type x, LIST L); 34 | 35 | position list_find_previous(element_type x, LIST L); 36 | 37 | #endif -------------------------------------------------------------------------------- /adt/priority_queue.h: -------------------------------------------------------------------------------- 1 | #ifndef _priority_queue_h_ 2 | #define _priority_queue_h_ 3 | #include 4 | typedef int element_type; 5 | 6 | #define min_data INT_MIN 7 | 8 | typedef struct heap_tag{ 9 | unsigned int max_size; 10 | unsigned int size; 11 | element_type *elements; 12 | }*priority_queue; 13 | 14 | priority_queue pq_create(unsigned int max_size); 15 | 16 | void pq_destroy(priority_queue* pheap); 17 | 18 | void pq_insert(priority_queue pq, element_type e); 19 | 20 | int pq_is_full(priority_queue pq); 21 | 22 | element_type pq_delete_min(priority_queue heap); 23 | 24 | void pq_decrease_key(priority_queue heap, unsigned int position, element_type delta); 25 | 26 | void pq_increase_key(priority_queue heap, unsigned int position, element_type delta); 27 | 28 | void pq_delete(priority_queue heap, unsigned int p); 29 | 30 | #endif -------------------------------------------------------------------------------- /algorithm/qsort.c: -------------------------------------------------------------------------------- 1 | /* 2 | *author: booirror@163.com 3 | *date: 2015/4/28 4 | */ 5 | #include 6 | void swap(int a[], int n, int m) 7 | { 8 | if (n == m) return; 9 | int tmp = a[n]; 10 | a[n] = a[m]; 11 | a[m] = tmp; 12 | } 13 | 14 | void qsort(int a[], int n) 15 | { 16 | int i, j; 17 | int last = 0; 18 | if (n < 2) return; 19 | swap(a, 0, n/2); 20 | for (i = 1; i < n; i++) { 21 | if (a[i] < a[0]) { 22 | swap(a, ++last, i); 23 | } 24 | } 25 | swap(a, 0, last); 26 | qsort(a, last); 27 | qsort(a+last+1, n-last-1); 28 | } 29 | 30 | int main() 31 | { 32 | int i = 0; 33 | int ra[10] = {12, 23, 55, 33, 1, 25, 32, 99, 77, 11}; 34 | qsort(ra, 10); 35 | 36 | while (i < 10) 37 | printf(" %d", ra[i++]); 38 | puts("\n"); 39 | int ar[6] = {4, 22, 11, 77, 33, 41}; 40 | qsort(ar, 6); 41 | for (i=0; i < 6; i++) { 42 | printf("%d ", ar[i]); 43 | } 44 | puts("\n"); 45 | return 0; 46 | } -------------------------------------------------------------------------------- /adt/binary_search_tree.h: -------------------------------------------------------------------------------- 1 | #ifndef _BST_H_ 2 | #define _BST_H_ 3 | 4 | typedef int element_type; 5 | typedef struct bstree_tag *bstree; 6 | typedef struct bstree_tag *node_ptr; 7 | 8 | struct bstree_tag 9 | { 10 | element_type data; 11 | node_ptr left; 12 | node_ptr right; 13 | }; 14 | 15 | typedef void (*bst_func)(node_ptr nptr); 16 | 17 | bstree bst_create_root(element_type e); 18 | 19 | /* create bst with array */ 20 | bstree bst_create(element_type a[], int size); 21 | 22 | void bst_destroy(bstree* bst); 23 | 24 | /* bst should not null */ 25 | void bst_insert(bstree bst, element_type e); 26 | 27 | node_ptr bst_find(bstree bst, element_type e); 28 | 29 | node_ptr bst_min_element(bstree bst); 30 | 31 | node_ptr bst_max_element(bstree bst); 32 | 33 | bstree bst_delete(bstree bst, element_type e); 34 | 35 | void bst_inorder_traversal(bstree bst, bst_func func); 36 | 37 | void bst_postorder_traversal(bstree bst, bst_func func); 38 | #endif -------------------------------------------------------------------------------- /test/hash_test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "../adt/hash.h" 4 | 5 | #define SIZE 10 6 | 7 | position hashfunc(int e) 8 | { 9 | return e % 10; 10 | } 11 | 12 | int cmp_int(int a, int b) 13 | { 14 | return a == b; 15 | } 16 | 17 | int main() 18 | { 19 | int k = 0; 20 | int array[] = {4371, 1323, 6173, 4199, 4344, 9679, 1989}; 21 | hash_table_ptr tbl = hash_init_table(SIZE, hashfunc, cmp_int); 22 | for (; k < 7; k++) { 23 | hash_insert(tbl, array[k]); 24 | } 25 | position p = hash_find(tbl, 6173); 26 | position q = hash_find(tbl, 1323); 27 | assert(p != -1); 28 | assert(p != q); 29 | assert(tbl->cells[p].element == 6173); 30 | hash_delete(tbl, 6173); 31 | p = hash_find(tbl, 6173); 32 | assert(p == -1); 33 | for (k = 0; k < SIZE; k++) { 34 | if (tbl->cells[k].info == legitimate) { 35 | printf("%d ", tbl->cells[k].element); 36 | } 37 | } 38 | puts("\n"); 39 | hash_destroy_table(&tbl); 40 | assert(tbl == NULL); 41 | return 0; 42 | } -------------------------------------------------------------------------------- /adt/hash.h: -------------------------------------------------------------------------------- 1 | #ifndef _linear_hash_h 2 | #define _linear_hash_h 3 | 4 | typedef int element_type; 5 | 6 | typedef unsigned int position; 7 | 8 | typedef position (*hash)(element_type e); 9 | 10 | /* if equals, return 1, othewise, return 0 */ 11 | typedef int (*cmp_func)(element_type e, element_type b); 12 | 13 | typedef enum kind_of_entry 14 | { 15 | legitimate, 16 | empty, 17 | deleted 18 | }kind_of_entry; 19 | 20 | typedef struct hash_entry{ 21 | element_type element; 22 | kind_of_entry info; 23 | }cell; 24 | 25 | typedef struct hash_table { 26 | hash hfunc; 27 | cmp_func equals; 28 | unsigned int table_size; 29 | cell *cells; 30 | }*hash_table_ptr; 31 | 32 | hash_table_ptr hash_init_table(unsigned int size, hash f, cmp_func c); 33 | 34 | void hash_insert(hash_table_ptr hash_tbl, element_type e); 35 | 36 | position hash_find(hash_table_ptr hash_tbl, element_type e); 37 | 38 | void hash_delete(hash_table_ptr hash_tbl, element_type e); 39 | 40 | void hash_destroy_table(hash_table_ptr* ptr); 41 | 42 | #endif -------------------------------------------------------------------------------- /adt/stack.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "stack.h" 4 | 5 | struct stack_tag 6 | { 7 | element_type data[SIZE]; 8 | int tos; 9 | }; 10 | 11 | static void fatal_error(const char* errmsg) 12 | { 13 | fprintf(stderr, "%s\n", errmsg); 14 | exit(1); 15 | } 16 | 17 | stack stack_create() 18 | { 19 | stack s = (stack)malloc(sizeof(struct stack_tag)); 20 | if (s == NULL) 21 | fatal_error("out of space"); 22 | s->tos = -1; 23 | } 24 | 25 | void stack_destroy(stack* sptr) 26 | { 27 | if (*sptr != NULL) 28 | free(*sptr); 29 | *sptr = NULL; 30 | } 31 | 32 | element_type stack_top(stack s) 33 | { 34 | return s->data[s->tos]; 35 | } 36 | 37 | void stack_pop(stack s) 38 | { 39 | if (s->tos > -1) { 40 | s->tos -= 1; 41 | } 42 | } 43 | 44 | void stack_push(stack s, element_type e) 45 | { 46 | if (s->tos < SIZE - 1) { 47 | s->tos++; 48 | s->data[s->tos] = e; 49 | } else { 50 | fatal_error("stack overflow"); 51 | } 52 | } 53 | 54 | int stack_size(stack s) 55 | { 56 | return s->tos + 1; 57 | } 58 | 59 | int stack_is_empty(stack s) 60 | { 61 | return s->tos == -1; 62 | } 63 | -------------------------------------------------------------------------------- /test/priority_queue_test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "../adt/priority_queue.h" 4 | 5 | int main(int argc, char const *argv[]) 6 | { 7 | int i = 1; 8 | priority_queue heap = pq_create(10); 9 | for (; i < 10; i++) { 10 | pq_insert(heap, i); 11 | } 12 | for (i = 1; i <=heap->size; i++) { 13 | printf(" %d", heap->elements[i]); 14 | } 15 | puts("\n1--------------\n"); 16 | assert(pq_is_full(heap)); 17 | assert(pq_delete_min(heap) == 1); 18 | assert(!pq_is_full(heap)); 19 | for (i = 1; i <=heap->size; i++) { 20 | printf(" %d", heap->elements[i]); 21 | } 22 | puts("\n2--------------\n"); 23 | pq_decrease_key(heap, 8, 8); 24 | for (i = 1; i <=heap->size; i++) { 25 | printf(" %d", heap->elements[i]); 26 | } 27 | puts("\n3--------------\n"); 28 | assert(pq_delete_min(heap) == 1); 29 | pq_increase_key(heap, 1, 7); 30 | for (i = 1; i <=heap->size; i++) { 31 | printf(" %d", heap->elements[i]); 32 | } 33 | puts("\n4--------------\n"); 34 | pq_delete(heap, 7); 35 | for (i = 1; i <=heap->size; i++) { 36 | printf(" %d", heap->elements[i]); 37 | } 38 | puts("\n5--------------\n"); 39 | pq_destroy(&heap); 40 | return 0; 41 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Object files 2 | *.o 3 | *.ko 4 | *.obj 5 | *.elf 6 | 7 | # Precompiled Headers 8 | *.gch 9 | *.pch 10 | 11 | # Libraries 12 | *.lib 13 | *.a 14 | *.la 15 | *.lo 16 | 17 | # Shared objects (inc. Windows DLLs) 18 | *.dll 19 | *.so 20 | *.so.* 21 | *.dylib 22 | 23 | # Executables 24 | *.exe 25 | *.out 26 | *.app 27 | *.i*86 28 | *.x86_64 29 | *.hex 30 | 31 | # ========================= 32 | # Operating System Files 33 | # ========================= 34 | 35 | # OSX 36 | # ========================= 37 | 38 | .DS_Store 39 | .AppleDouble 40 | .LSOverride 41 | 42 | # Thumbnails 43 | ._* 44 | 45 | # Files that might appear on external disk 46 | .Spotlight-V100 47 | .Trashes 48 | 49 | # Directories potentially created on remote AFP share 50 | .AppleDB 51 | .AppleDesktop 52 | Network Trash Folder 53 | Temporary Items 54 | .apdisk 55 | 56 | # Windows 57 | # ========================= 58 | 59 | # Windows image file caches 60 | Thumbs.db 61 | ehthumbs.db 62 | 63 | # Folder config file 64 | Desktop.ini 65 | 66 | # Recycle Bin used on file shares 67 | $RECYCLE.BIN/ 68 | 69 | # Windows Installer files 70 | *.cab 71 | *.msi 72 | *.msm 73 | *.msp 74 | 75 | # Windows shortcuts 76 | *.lnk 77 | -------------------------------------------------------------------------------- /adt/tree.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | class C { 6 | public: 7 | int v; 8 | C():v(0){} 9 | C(int val) { v = val; } 10 | ~C() { 11 | std::cout << "C::~C(), v=" << v << std::endl; 12 | } 13 | 14 | }; 15 | 16 | struct PathNode 17 | { 18 | C c; 19 | PathNode* child; 20 | PathNode* sibling; 21 | 22 | PathNode(const C& v) : c(v), child(nullptr), sibling(nullptr) 23 | { 24 | 25 | } 26 | }; 27 | 28 | typedef PathNode *Tree; 29 | 30 | void deleteTree(Tree t) 31 | { 32 | if (t == nullptr) 33 | return; 34 | PathNode* child = t->child; 35 | PathNode* sib = t->sibling; 36 | delete t; 37 | if (child) { 38 | deleteTree(child); 39 | } 40 | while (sib) { 41 | PathNode* tmp = sib; 42 | sib = sib->sibling; 43 | deleteTree(tmp); 44 | } 45 | } 46 | 47 | void mainTree() 48 | { 49 | Tree t = new PathNode(C(2)); 50 | 51 | PathNode* t2 = new PathNode(C(3)); 52 | t->child = t2; 53 | 54 | PathNode* t3 = new PathNode(C(4)); 55 | 56 | t2->sibling = t3; 57 | 58 | PathNode* t4 = new PathNode(C(5)); 59 | t3->sibling = t4; 60 | 61 | PathNode* t5 = new PathNode(C(6)); 62 | t2->child = t5; 63 | 64 | PathNode* t6 = new PathNode(C(7)); 65 | t5->child = t6; 66 | 67 | PathNode* t7 = new PathNode(C(8)); 68 | t4->child = t7; 69 | 70 | deleteTree(t); 71 | } -------------------------------------------------------------------------------- /adt/circular_queue.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "circular_queue.h" 4 | 5 | #define SIZE 100 6 | 7 | struct queue_tag 8 | { 9 | element_type qdata[SIZE]; 10 | int qfront; 11 | int qrear; 12 | }; 13 | 14 | void fatal_error(const char* errmsg) 15 | { 16 | fprintf(stderr, "%s\n", errmsg); 17 | exit(1); 18 | } 19 | 20 | void donothing_warnning(const char* warn) 21 | { 22 | fprintf(stdout, "warnning: %s\n", warn); 23 | } 24 | 25 | queue queue_create() 26 | { 27 | queue q = (queue)malloc(sizeof(struct queue_tag)); 28 | if (q == NULL) { 29 | fatal_error("out of space"); 30 | } 31 | q->qfront = q->qrear = 0; 32 | return q; 33 | } 34 | 35 | void queue_destroy(queue * qptr) 36 | { 37 | if (*qptr != NULL) { 38 | free(*qptr); 39 | *qptr = NULL; 40 | } 41 | } 42 | 43 | void queue_enqueue(queue q, element_type e) 44 | { 45 | if ((q->qrear + 1)%SIZE == q->qfront) { 46 | donothing_warnning("queue overflow"); 47 | return; 48 | } 49 | q->qdata[q->qrear] = e; 50 | q->qrear = (q->qrear + 1) % SIZE; 51 | } 52 | 53 | element_type queue_dequeue(queue q) 54 | { 55 | element_type tmp; 56 | if (q->qfront == q->qrear) { 57 | donothing_warnning("queue underflow"); 58 | return -1; 59 | } 60 | tmp = q->qdata[q->qfront]; 61 | q->qfront = (q->qfront + 1) % SIZE; 62 | return tmp; 63 | } 64 | 65 | int queue_is_empty(queue q) 66 | { 67 | return q->qfront == q->qrear; 68 | } 69 | 70 | int queue_is_full(queue q) 71 | { 72 | return (q->qrear + 1)%SIZE == q->qfront; 73 | } -------------------------------------------------------------------------------- /adt/hash.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "hash.h" 4 | 5 | static void fatal_error(const char* errmsg) 6 | { 7 | fprintf(stderr, "%s\n", errmsg); 8 | exit(1); 9 | } 10 | 11 | 12 | hash_table_ptr hash_init_table(unsigned int size, hash f, cmp_func c) 13 | { 14 | int i = 0; 15 | if (f == NULL) { 16 | fatal_error("hash function must be provided"); 17 | } 18 | if (c == NULL) { 19 | fatal_error("compare function must be provided"); 20 | } 21 | hash_table_ptr tbl = (hash_table_ptr)malloc(sizeof(struct hash_table)); 22 | if (tbl == NULL) { 23 | fatal_error("out of space"); 24 | } 25 | tbl->cells = (cell*)malloc(sizeof(cell)*size); 26 | if (tbl->cells == NULL){ 27 | free(tbl); 28 | fatal_error("out of space"); 29 | } 30 | tbl->table_size = size; 31 | tbl->hfunc = f; 32 | tbl->equals = c; 33 | for (; i < size; ++i) { 34 | tbl->cells[i].info = empty; 35 | } 36 | return tbl; 37 | } 38 | 39 | void hash_insert(hash_table_ptr tbl, element_type e) 40 | { 41 | position pos = tbl->hfunc(e); 42 | while (tbl->cells[pos].info != empty) { 43 | pos = (pos+1) % tbl->table_size; 44 | } 45 | tbl->cells[pos].element = e; 46 | tbl->cells[pos].info = legitimate; 47 | } 48 | 49 | position hash_find(hash_table_ptr tbl, element_type e) 50 | { 51 | int i = 0; 52 | position idx = tbl->hfunc(e); 53 | while (i < tbl->table_size) { 54 | if (tbl->cells[idx].info == legitimate && tbl->equals(tbl->cells[idx].element, e)) 55 | return idx; 56 | idx = (idx+1) % tbl->table_size; 57 | i++; 58 | } 59 | return -1; 60 | } 61 | 62 | void hash_delete(hash_table_ptr ptr, element_type e) 63 | { 64 | position pos = hash_find(ptr, e); 65 | if (pos != -1) { 66 | ptr->cells[pos].info = deleted; 67 | } 68 | } 69 | 70 | void hash_destroy_table(hash_table_ptr* phash_ptr) 71 | { 72 | hash_table_ptr tbl = *phash_ptr; 73 | if (*phash_ptr == NULL) return; 74 | if (tbl->cells != NULL) { 75 | free(tbl->cells); 76 | } 77 | free(tbl); 78 | *phash_ptr = NULL; 79 | } -------------------------------------------------------------------------------- /algorithm/AstarLayer.h: -------------------------------------------------------------------------------- 1 | #ifndef _ASTAR_LAYER_H_ 2 | #define _ASTAR_LAYER_H_ 3 | #include "cocos2d.h" 4 | 5 | class ANode : public cocos2d::Node { 6 | public: 7 | enum class Type { 8 | kNormal, 9 | kWall, 10 | kSrc, 11 | kDst, 12 | kAddOpen, 13 | kAddClose, 14 | kPath, 15 | }; 16 | static ANode* create(); 17 | virtual bool init() override; 18 | bool setType(Type type); 19 | Type getType() { return aType; } 20 | private: 21 | cocos2d::DrawNode *drawNode; 22 | Type aType; 23 | int aWidth = 40; 24 | }; 25 | 26 | struct AstarNode { 27 | AstarNode* parent; 28 | int hValue; 29 | int gValue; 30 | int row; 31 | int col; 32 | 33 | int getFValue() { return hValue + gValue; } 34 | void calcValue(AstarNode* dst); 35 | 36 | AstarNode() :AstarNode(0, 0) { 37 | 38 | } 39 | AstarNode(int r, int c) : 40 | row(r), col(c), parent(nullptr), hValue(0), gValue(0) 41 | { 42 | 43 | } 44 | }; 45 | 46 | struct Vec2Ex { 47 | int x; 48 | int y; 49 | Vec2Ex() { 50 | x = 0; 51 | y = 0; 52 | } 53 | Vec2Ex(int _x, int _y) { 54 | x = _x; 55 | y = _y; 56 | } 57 | }; 58 | 59 | const int maxrow = 15; 60 | const int maxcol = 23; 61 | 62 | class AstarLayer : public cocos2d::Layer { 63 | public: 64 | 65 | static AstarLayer* create(); 66 | static cocos2d::Scene* createScene(); 67 | virtual bool init() override; 68 | 69 | ANode* getNode(int row, int col) { return mNodes[row][col]; } 70 | private: 71 | ANode* mNodes[maxrow][maxcol]; 72 | AstarNode src; 73 | AstarNode dst; 74 | std::vector list; 75 | }; 76 | 77 | class AStar { 78 | public: 79 | static AStar* getInstance(); 80 | 81 | bool find(AstarNode src, AstarNode dst, std::vector &list); 82 | 83 | void init(AstarNode(&astarNodes)[maxrow][maxcol], AstarLayer* astarLayer); 84 | 85 | private: 86 | //void addOpenList(std::vector& q, ) 87 | bool isValid(int row, int col); 88 | bool isUnwalkable(int row, int col); 89 | AstarLayer* layer = nullptr; 90 | AstarNode nodes[maxrow][maxcol]; 91 | bool openlist[maxrow*maxcol]; 92 | bool closelist[maxrow*maxcol]; 93 | }; 94 | 95 | #endif -------------------------------------------------------------------------------- /adt/linked_list.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "linked_list.h" 4 | 5 | void fatal_error(const char* errmsg) 6 | { 7 | fprintf(stderr, "%s\n", errmsg); 8 | exit(1); 9 | } 10 | 11 | LIST list_create() 12 | { 13 | node_ptr ptr = malloc(sizeof(struct node)); 14 | if (ptr == NULL) { 15 | fatal_error("out of space"); 16 | return NULL; 17 | } 18 | ptr->next = NULL; 19 | return ptr; 20 | } 21 | 22 | void list_destroy(LIST *Lptr) 23 | { 24 | position tmp; 25 | position p = *Lptr; 26 | while (p != NULL) { 27 | tmp = p; 28 | p = p->next; 29 | free(tmp); 30 | } 31 | *Lptr = NULL; 32 | } 33 | 34 | int list_is_empty(LIST L) 35 | { 36 | return (L->next == NULL); 37 | } 38 | 39 | int list_is_last(position p, LIST L) 40 | { 41 | return (p->next == NULL); 42 | } 43 | 44 | position list_find(element_type x, LIST L) 45 | { 46 | L = L->next; 47 | while (L != NULL && L->element != x) { 48 | L = L->next; 49 | } 50 | return L; 51 | } 52 | 53 | void list_reverse(LIST L) 54 | { 55 | if (L->next == NULL) return; 56 | node_ptr p = L->next, first = L->next; 57 | while (p != NULL && p->next != NULL) { 58 | node_ptr next_node = p->next; 59 | p->next = next_node->next; 60 | next_node->next = first; 61 | first = next_node; 62 | } 63 | L->next = first; 64 | } 65 | 66 | void list_delete(element_type x, LIST L) 67 | { 68 | position p, tmp_node; 69 | p = list_find_previous(x, L); 70 | if (p->next != NULL) { 71 | tmp_node = p->next; 72 | p->next = tmp_node->next; 73 | free(tmp_node); 74 | } 75 | } 76 | 77 | position list_find_previous(element_type x, LIST L) 78 | { 79 | while (L->next != NULL && L->next->element != x) { 80 | L = L->next; 81 | } 82 | return L; 83 | } 84 | 85 | void list_insert(element_type x, LIST L, position p) 86 | { 87 | node_ptr node = (node_ptr)malloc(sizeof(struct node)); 88 | if (node == NULL) { 89 | fatal_error("out of space"); 90 | } else { 91 | node->element = x; 92 | node->next = p->next; 93 | p->next = node; 94 | } 95 | } 96 | 97 | void list_insert_header(element_type x, LIST L) 98 | { 99 | list_insert(x, L, L); 100 | } -------------------------------------------------------------------------------- /adt/priority_queue.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "priority_queue.h" 4 | 5 | static void fatal_error(const char* errmsg) 6 | { 7 | fprintf(stderr, "%s\n", errmsg); 8 | exit(1); 9 | } 10 | 11 | static void donothing_warnning(const char* warn) 12 | { 13 | fprintf(stdout, "warnning: %s\n", warn); 14 | } 15 | 16 | priority_queue pq_create(unsigned int max_size) 17 | { 18 | priority_queue heap = (priority_queue)malloc(sizeof(struct heap_tag)); 19 | if (heap == NULL) { 20 | fatal_error("out of space"); 21 | } 22 | heap->elements = (element_type*)malloc(sizeof(element_type)*max_size); 23 | if (heap->elements == NULL) { 24 | fatal_error("out of space"); 25 | } 26 | heap->max_size = max_size; 27 | heap->size = 0; 28 | heap->elements[0] = min_data; 29 | return heap; 30 | } 31 | 32 | void pq_destroy(priority_queue *pheap) 33 | { 34 | priority_queue pq = *pheap; 35 | if (pq == NULL) { 36 | return; 37 | } 38 | if (pq->elements != NULL) { 39 | free(pq->elements); 40 | } 41 | free(pq); 42 | *pheap = NULL; 43 | } 44 | 45 | int pq_is_full(priority_queue pq) 46 | { 47 | return pq->max_size == pq->size+1; 48 | } 49 | 50 | void pq_insert(priority_queue heap, element_type x) 51 | { 52 | unsigned int i; 53 | if (pq_is_full(heap)) { 54 | donothing_warnning("binary heap is full"); 55 | return; 56 | } 57 | i = ++heap->size; 58 | while (heap->elements[i/2] > x) { 59 | heap->elements[i] = heap->elements[i/2]; 60 | i /= 2; 61 | } 62 | heap->elements[i] = x; 63 | } 64 | 65 | element_type pq_delete_min(priority_queue pq) 66 | { 67 | element_type min = pq->elements[1]; 68 | element_type x = pq->elements[pq->size--]; 69 | int i = 1; 70 | element_type tmp; 71 | int flag = 0; 72 | while (2 * i <= pq->size) 73 | { 74 | flag = 0; 75 | if (pq->elements[2*i] < x) { 76 | tmp = x; 77 | pq->elements[i] = x = pq->elements[2*i]; 78 | pq->elements[2*i] = tmp; 79 | flag = 0; 80 | } 81 | if (2*i+1 <= pq->size && pq->elements[2*i+1] < x) { 82 | tmp = x; 83 | pq->elements[i] = x = pq->elements[2*i+1]; 84 | pq->elements[2*i+1] = tmp; 85 | flag = 1; 86 | } 87 | i = 2 * i + flag; 88 | x = pq->elements[i]; 89 | } 90 | return min; 91 | } 92 | 93 | void pq_decrease_key(priority_queue heap, unsigned int pos, element_type delta) 94 | { 95 | if (pos > heap->size) { 96 | return; 97 | } 98 | element_type x = heap->elements[pos] - delta; 99 | unsigned int i = pos; 100 | while (heap->elements[i/2] > x) { 101 | heap->elements[i] = heap->elements[i/2]; 102 | i /= 2; 103 | } 104 | heap->elements[i] = x; 105 | } 106 | 107 | void pq_increase_key(priority_queue heap, unsigned int pos, element_type delta) 108 | { 109 | if (pos > heap->size) { 110 | return; 111 | } 112 | element_type x = heap->elements[pos] + delta; 113 | unsigned int i = pos; 114 | unsigned int child; 115 | for (; i*2 < heap->size; i = child) { 116 | child = i * 2; 117 | if ((child != heap->size) && heap->elements[child+1] < heap->elements[child]) { 118 | child++; 119 | } 120 | if (x > heap->elements[child]) { 121 | heap->elements[i] = heap->elements[child]; 122 | } else { 123 | break; 124 | } 125 | } 126 | heap->elements[i] = x; 127 | } 128 | 129 | void pq_delete(priority_queue q, unsigned int p) 130 | { 131 | pq_decrease_key(q, p, q->elements[p] - q->elements[1] -1); 132 | pq_delete_min(q); 133 | } -------------------------------------------------------------------------------- /adt/binary_search_tree.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "binary_search_tree.h" 4 | 5 | void fatal_error(const char* errmsg) 6 | { 7 | fprintf(stderr, "%s\n", errmsg); 8 | exit(1); 9 | } 10 | 11 | void donothing_warnning(const char* warn) 12 | { 13 | fprintf(stdout, "warnning: %s\n", warn); 14 | } 15 | 16 | bstree bst_create_root(element_type e) 17 | { 18 | node_ptr ptr = (node_ptr)malloc(sizeof(struct bstree_tag)); 19 | if (ptr == NULL) { 20 | fatal_error("out of space"); 21 | } 22 | ptr->data = e; 23 | ptr->left = ptr->right = NULL; 24 | return ptr; 25 | } 26 | 27 | 28 | void bst_insert(bstree bst, element_type e) 29 | { 30 | if (bst->data == e) { 31 | return; 32 | } else if (bst->data < e) { 33 | if (bst->right != NULL) { 34 | bst_insert(bst->right, e); 35 | } else { 36 | bstree node = bst_create_root(e); 37 | bst->right = node; 38 | } 39 | } else { 40 | if (bst->left != NULL) { 41 | bst_insert(bst->left, e); 42 | } else { 43 | bstree node = bst_create_root(e); 44 | bst->left = node; 45 | } 46 | } 47 | } 48 | 49 | bstree bst_create(element_type a[], int size) 50 | { 51 | int i = 1; 52 | if (size <= 0) return NULL; 53 | bstree bst = bst_create_root(a[0]); 54 | for (; i < size; i++) { 55 | bst_insert(bst, a[i]); 56 | } 57 | return bst; 58 | } 59 | 60 | node_ptr bst_find(bstree bst, element_type e) 61 | { 62 | if (bst == NULL) 63 | return NULL; 64 | else if (bst->data < e) { 65 | return bst_find(bst->right, e); 66 | } else if (bst->data > e) { 67 | return bst_find(bst->left, e); 68 | } 69 | return bst; 70 | } 71 | 72 | node_ptr bst_min_element(bstree bst) 73 | { 74 | if (bst->left != NULL) 75 | return bst_min_element(bst->left); 76 | return bst; 77 | } 78 | 79 | node_ptr bst_max_element(bstree bst) 80 | { 81 | while (bst->right != NULL) { 82 | bst = bst->right; 83 | } 84 | return bst; 85 | } 86 | 87 | static bstree bst_delete_min(bstree bst, element_type* pdata) 88 | { 89 | while (bst->left != NULL) { 90 | bst = bst->left; 91 | } 92 | node_ptr right = bst->right; 93 | *pdata = bst->data; 94 | free(bst); 95 | return right; 96 | } 97 | 98 | bstree bst_delete(bstree bst, element_type e) 99 | { 100 | if (bst == NULL) { 101 | donothing_warnning("element not found"); 102 | return bst; 103 | } else if (bst->data > e) { 104 | bst->left = bst_delete(bst->left, e); 105 | } else if (bst->data < e) { 106 | bst->right = bst_delete(bst->right, e); 107 | } else { 108 | // bst->data == e 109 | if (bst->left == NULL && bst->right == NULL) { 110 | free(bst); 111 | return NULL; 112 | } else if (bst->left == NULL || bst->right == NULL) { 113 | node_ptr node = bst->left == NULL ? bst->right : bst->left; 114 | free(bst); 115 | return node; 116 | } 117 | bst->right = bst_delete_min(bst->right, &bst->data); 118 | } 119 | return bst; 120 | } 121 | 122 | void bst_inorder_traversal(bstree bst, bst_func func) 123 | { 124 | if (bst == NULL) return; 125 | bst_inorder_traversal(bst->left, func); 126 | func(bst); 127 | bst_inorder_traversal(bst->right, func); 128 | } 129 | 130 | static void free_node(node_ptr p) 131 | { 132 | free(p); 133 | } 134 | void bst_postorder_traversal(bstree bst, bst_func func) 135 | { 136 | if (bst == NULL) return; 137 | bst_postorder_traversal(bst->left, func); 138 | bst_postorder_traversal(bst->right, func); 139 | func(bst); 140 | } 141 | 142 | void bst_destroy(bstree *bst) 143 | { 144 | bst_postorder_traversal(*bst, free_node); 145 | *bst = NULL; 146 | } -------------------------------------------------------------------------------- /algorithm/AstarLayer.cpp: -------------------------------------------------------------------------------- 1 | #include "AstarLayer.h" 2 | #include 3 | #include 4 | using namespace cocos2d; 5 | 6 | static AStar* _instance = nullptr; 7 | 8 | ANode* ANode::create() 9 | { 10 | ANode* node = new ANode(); 11 | if (node && node->init()) { 12 | node->autorelease(); 13 | return node; 14 | } 15 | else { 16 | CC_SAFE_DELETE(node); 17 | return nullptr; 18 | } 19 | } 20 | 21 | bool ANode::init() 22 | { 23 | if (!Node::init()) { 24 | return false; 25 | } 26 | drawNode = DrawNode::create(); 27 | setType(Type::kNormal); 28 | this->addChild(drawNode); 29 | this->setContentSize(Size(aWidth, aWidth)); 30 | this->setAnchorPoint(Vec2(0.5, 0.5)); 31 | return true; 32 | } 33 | 34 | bool ANode::setType(Type type) 35 | { 36 | Color4F color; 37 | switch (type) 38 | { 39 | case ANode::Type::kNormal: 40 | color = Color4F::MAGENTA; 41 | break; 42 | case ANode::Type::kWall: 43 | color = Color4F(0x8b / 255.0f, 0x57 / 255.0f, 0x42 / 255.0f, 1); 44 | break; 45 | case ANode::Type::kSrc: 46 | color = Color4F(0x41 / 255.0f, 0x69 / 255.0f, 0xE1 / 255.0f, 0.8); 47 | break; 48 | case ANode::Type::kDst: 49 | color = color = Color4F(0x22 / 255.0f, 0x8B / 255.0f, 0x22 / 255.0f, 0.8); 50 | break; 51 | case ANode::Type::kAddOpen: 52 | color = Color4F::BLUE; 53 | break; 54 | case ANode::Type::kAddClose: 55 | color = Color4F(0x89 / 255.0f, 0x68 / 255.0f, 0xCD / 255.0f, 1); 56 | break; 57 | case ANode::Type::kPath: 58 | color = Color4F::GREEN; 59 | break; 60 | default: 61 | color = Color4F::MAGENTA; 62 | break; 63 | } 64 | aType = type; 65 | drawNode->clear(); 66 | drawNode->drawSolidRect(Vec2(0, 0), Vec2(aWidth, aWidth), color); 67 | drawNode->drawRect(Vec2(0, 0), Vec2(aWidth, aWidth), Color4F::ORANGE); 68 | return true; 69 | } 70 | 71 | ///////////////////////////////////////////////// 72 | 73 | void AstarNode::calcValue(AstarNode* dst) 74 | { 75 | int v = abs(parent->row - row) + abs(parent->col - col); 76 | if (v == 1) { 77 | gValue = parent->gValue + 10; 78 | } 79 | else { 80 | gValue = parent->gValue + 14; 81 | } 82 | hValue = abs(dst->col - col) + abs(dst->row - row); 83 | } 84 | 85 | //////////////////////////////////////////////// 86 | 87 | Scene* AstarLayer::createScene() 88 | { 89 | Scene* scene = Scene::create(); 90 | AstarLayer* layer = AstarLayer::create(); 91 | scene->addChild(layer); 92 | return scene; 93 | } 94 | 95 | AstarLayer* AstarLayer::create() 96 | { 97 | AstarLayer* layer = new (std::nothrow) AstarLayer(); 98 | if (layer && layer->init()) { 99 | layer->autorelease(); 100 | return layer; 101 | } 102 | else { 103 | delete layer; 104 | layer = nullptr; 105 | return nullptr; 106 | } 107 | } 108 | 109 | bool AstarLayer::init() 110 | { 111 | if (!Layer::init()) { 112 | return false; 113 | } 114 | auto winSize = Director::getInstance()->getVisibleSize(); 115 | 116 | auto bgLayer = LayerColor::create(Color4B(0x12, 0x12, 0x12, 0xff)); 117 | bgLayer->setPosition(Vec2(0, 0)); 118 | this->addChild(bgLayer); 119 | ANode* temp = ANode::create(); 120 | float startx = (winSize.width - maxcol * temp->getContentSize().width) / 2; 121 | float starty = (winSize.height - maxrow * temp->getContentSize().height) / 2; 122 | auto nsize = temp->getContentSize(); 123 | 124 | AstarNode nodes[maxrow][maxcol]; 125 | 126 | for (int i = 0; i < maxcol; i++) { 127 | for (int j = 0; j < maxrow; j++) { 128 | auto node = ANode::create(); 129 | node->setPosition(startx + (i + 0.5)*nsize.width, starty + (j + 0.5)*nsize.height); 130 | this->addChild(node); 131 | mNodes[j][i] = node; 132 | 133 | nodes[j][i].row = j; 134 | nodes[j][i].col = i; 135 | } 136 | } 137 | 138 | src = AstarNode(10, 3); 139 | dst = AstarNode(3, 21); 140 | 141 | mNodes[src.row][src.col]->setType(ANode::Type::kSrc); 142 | mNodes[dst.row][dst.col]->setType(ANode::Type::kDst); 143 | 144 | for (int row = 4; row < maxrow; row++) { 145 | mNodes[row][5]->setType(ANode::Type::kWall); 146 | } 147 | 148 | for (int row = 3; row < maxrow - 3; row++) { 149 | mNodes[row][10]->setType(ANode::Type::kWall); 150 | } 151 | 152 | for (int row = 0; row < maxrow - 4; row++) { 153 | mNodes[row][18]->setType(ANode::Type::kWall); 154 | } 155 | 156 | auto astar = AStar::getInstance(); 157 | astar->init(nodes, this); 158 | 159 | auto eventDispatcher = Director::getInstance()->getEventDispatcher(); 160 | auto listener = EventListenerTouchOneByOne::create(); 161 | 162 | listener->onTouchBegan = [this, astar](Touch* touch, Event* e)->bool { 163 | 164 | std::thread t(std::bind(&AStar::find, astar, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3), src, dst, std::ref(list)); 165 | t.detach(); 166 | //AStar::getInstance()->find(src, dst, list); 167 | return true; 168 | }; 169 | eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this); 170 | 171 | return true; 172 | } 173 | //////////////////////////// 174 | 175 | AStar* AStar::getInstance() 176 | { 177 | if (_instance == nullptr) { 178 | _instance = new AStar(); 179 | } 180 | return _instance; 181 | } 182 | 183 | void AStar::init(AstarNode(&astarNodes)[maxrow][maxcol], AstarLayer* astar) 184 | { 185 | std::swap(nodes, astarNodes); 186 | layer = astar; 187 | } 188 | 189 | bool AStar::find(AstarNode src, AstarNode dst, std::vector &list) 190 | { 191 | using namespace std::literals; 192 | std::vector queue; 193 | 194 | memset(openlist, 0, sizeof(openlist)); 195 | memset(closelist, 0, sizeof(closelist)); 196 | 197 | queue.push_back(&nodes[src.row][src.col]); 198 | 199 | while (!queue.empty()) { 200 | auto it = queue.begin(); 201 | for (auto iter = queue.begin(); iter != queue.end(); iter++) { 202 | if ((*it)->getFValue() > (*iter)->getFValue()) { 203 | it = iter; 204 | } 205 | } 206 | auto node = *it; 207 | queue.erase(it); 208 | closelist[node->row*maxcol + node->col] = true; 209 | 210 | if (!(src.row == node->row && src.col == node->col)) { 211 | this->layer->getNode(node->row, node->col)->setType(ANode::Type::kAddClose); 212 | } 213 | std::this_thread::sleep_for(std::chrono::milliseconds(50)); 214 | 215 | int r = node->row; 216 | int c = node->col; 217 | 218 | Vec2Ex twds[8]{ 219 | { r + 1, c }, 220 | { r - 1, c }, 221 | { r, c + 1}, 222 | { r, c - 1 }, 223 | { r + 1, c + 1 }, 224 | { r + 1, c - 1}, 225 | { r - 1, c + 1}, 226 | { r - 1, c - 1}, 227 | }; 228 | 229 | for (int i = 0; i < 8; i++) { 230 | int row = twds[i].x; 231 | int col = twds[i].y; 232 | 233 | //std::this_thread::sleep_for(1s); 234 | 235 | if (row == dst.row && col == dst.col) { 236 | list.push_back(&nodes[row][col]); 237 | auto p = node; 238 | while (p != nullptr) { 239 | list.push_back(p); 240 | 241 | if (p->row != src.row || p->col != src.col) { 242 | this->layer->getNode(p->row, p->col)->setType(ANode::Type::kPath); 243 | } 244 | std::this_thread::sleep_for(std::chrono::milliseconds(100)); 245 | p = p->parent; 246 | } 247 | return true; 248 | } 249 | 250 | if (isValid(row, col) && !isUnwalkable(row, col)) { 251 | if (openlist[row*maxcol + col]) { 252 | if (nodes[row][col].gValue > node->gValue + 10) 253 | { 254 | nodes[row][col].parent = node; 255 | nodes[row][col].calcValue(&dst); 256 | } 257 | } 258 | else { 259 | nodes[row][col].parent = node; 260 | nodes[row][col].calcValue(&dst); 261 | queue.push_back(&nodes[row][col]); 262 | openlist[row*maxcol + col] = true; 263 | 264 | this->layer->getNode(row, col)->setType(ANode::Type::kAddOpen); 265 | } 266 | } 267 | } 268 | } 269 | 270 | return false; 271 | } 272 | 273 | bool AStar::isUnwalkable(int row, int col) 274 | { 275 | return layer->getNode(row, col)->getType() == ANode::Type::kWall; 276 | } 277 | 278 | bool AStar::isValid(int row, int col) 279 | { 280 | if (row >= 0 && row < maxrow && col >= 0 && col < maxcol) { 281 | return !closelist[row * maxcol + col]; 282 | } 283 | return false; 284 | } --------------------------------------------------------------------------------