├── README.md ├── chapter3 ├── util.c ├── util.h ├── testLinkedList.c ├── linkedstack.h ├── arraystack.h ├── arrayqueue.h ├── polynomial.h ├── cursor.h ├── linkedlist.h ├── polynomial.c ├── exercise.c ├── linkedstack.c ├── arraystack.c ├── joesphus.c ├── arrayqueue.c ├── main.c ├── cursor.c └── linkedlist.c ├── chapter2 ├── fib.c ├── fib.h ├── gcd.h ├── horner.h ├── horner.c ├── prime.h ├── pow.h ├── gcd.c ├── binary_search.h ├── permutation.h ├── prime.c ├── MaxSubsequenceSum.h ├── util.h ├── pow.c ├── binary_search.c ├── permutation.c ├── util.c ├── MaxSubsequenceSum.c └── main.c ├── chapter5 ├── prime.h ├── prime.c ├── test_hash_quad.c ├── testhashmap.c ├── hashtable.h ├── hashtable_quad.h ├── hashtable_quad.c └── hashtable.c ├── .gitignore ├── chapter6 ├── test_binary_heap.c ├── left_heap.h ├── binary_heap.h ├── left_heap.c └── binary_heap.c ├── chapter4 ├── testSearchTree.c ├── testAVLTree.c ├── avltree.h ├── searchtree.h ├── searchtree.c └── avltree.c ├── chapter7 ├── sort.h ├── test_sort.c └── sort.c ├── LICENSE └── CMakeLists.txt /README.md: -------------------------------------------------------------------------------- 1 | # data-structure-and-algorithm 2 | 《数据结构与算法分析——C语言描述》随书练习 3 | 4 | 这本书在网上的评价不错,拿来作为数据结构的入门练习,在这个repo中主要实现各个章节中的数据结构。 5 | 6 | - 第四章:树 7 | - 第五章:哈希表 -------------------------------------------------------------------------------- /chapter3/util.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by aaron on 10/19/16. 3 | // 4 | 5 | #include "util.h" 6 | 7 | int max(int a, int b) { 8 | return a > b ? a : b; 9 | } -------------------------------------------------------------------------------- /chapter2/fib.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 董启宏 on 2016/10/12. 3 | // 4 | 5 | #include "fib.h" 6 | 7 | long fib(int N) { 8 | if (N <= 1) { 9 | return 1; 10 | } 11 | return fib(N-1) + fib(N-2); 12 | } 13 | -------------------------------------------------------------------------------- /chapter2/fib.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 董启宏 on 2016/10/12. 3 | // 4 | 5 | #ifndef DATA_STRUCTURE_AND_ALGORITHM_FIB_H 6 | #define DATA_STRUCTURE_AND_ALGORITHM_FIB_H 7 | long fib(int N); 8 | #endif //DATA_STRUCTURE_AND_ALGORITHM_FIB_H 9 | -------------------------------------------------------------------------------- /chapter3/util.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by aaron on 10/19/16. 3 | // 4 | 5 | #ifndef DATA_STRUCTURE_AND_ALGORITHM_UTIL_H 6 | #define DATA_STRUCTURE_AND_ALGORITHM_UTIL_H 7 | 8 | int max(int a, int b); 9 | #endif //DATA_STRUCTURE_AND_ALGORITHM_UTIL_H 10 | -------------------------------------------------------------------------------- /chapter2/gcd.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by aaron on 10/13/16. 3 | // 4 | 5 | #ifndef DATA_STRUCTURE_AND_ALGORITHM_GCD_H 6 | #define DATA_STRUCTURE_AND_ALGORITHM_GCD_H 7 | unsigned int gcd(unsigned int M, unsigned int N); 8 | #endif //DATA_STRUCTURE_AND_ALGORITHM_GCD_H 9 | -------------------------------------------------------------------------------- /chapter2/horner.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by aaron on 10/14/16. 3 | // 4 | 5 | #ifndef DATA_STRUCTURE_AND_ALGORITHM_HORNER_H 6 | #define DATA_STRUCTURE_AND_ALGORITHM_HORNER_H 7 | double polynomial(double* A, int N, double X); 8 | #endif //DATA_STRUCTURE_AND_ALGORITHM_HORNER_H 9 | -------------------------------------------------------------------------------- /chapter2/horner.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by aaron on 10/14/16. 3 | // 4 | 5 | #include "horner.h" 6 | 7 | double polynomial(double* A, int N, double X) { 8 | double poly = 0; 9 | for (int i = N-1; i >= 0; i--) { 10 | poly = poly * X + A[i]; 11 | } 12 | return poly; 13 | } -------------------------------------------------------------------------------- /chapter2/prime.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by aaron on 10/14/16. 3 | // 4 | 5 | #include 6 | 7 | #ifndef DATA_STRUCTURE_AND_ALGORITHM_PRIME_H 8 | #define DATA_STRUCTURE_AND_ALGORITHM_PRIME_H 9 | 10 | bool isPrime(long N); 11 | 12 | #endif //DATA_STRUCTURE_AND_ALGORITHM_PRIME_H 13 | -------------------------------------------------------------------------------- /chapter2/pow.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by aaron on 10/13/16. 3 | // 4 | 5 | #ifndef DATA_STRUCTURE_AND_ALGORITHM_POW_H 6 | #define DATA_STRUCTURE_AND_ALGORITHM_POW_H 7 | long Pow(long X, unsigned long N); 8 | long PowRecursion(long X, unsigned long N); 9 | #endif //DATA_STRUCTURE_AND_ALGORITHM_POW_H 10 | -------------------------------------------------------------------------------- /chapter2/gcd.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by aaron on 10/13/16. 3 | // 4 | 5 | #include "gcd.h" 6 | 7 | unsigned int gcd(unsigned int M, unsigned int N) { 8 | unsigned int rem = 0; 9 | while (N > 0) { 10 | rem = M % N; 11 | M = N; 12 | N = rem; 13 | } 14 | 15 | return M; 16 | } -------------------------------------------------------------------------------- /chapter5/prime.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by aaron on 16-11-5. 3 | // 4 | 5 | #include 6 | #include 7 | 8 | #ifndef DATA_STRUCTURE_AND_ALGORITHM_PRIME_H 9 | #define DATA_STRUCTURE_AND_ALGORITHM_PRIME_H 10 | bool isPrime(size_t x); 11 | size_t nextPrime(size_t x); 12 | #endif //DATA_STRUCTURE_AND_ALGORITHM_PRIME_H 13 | -------------------------------------------------------------------------------- /chapter2/binary_search.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 董启宏 on 2016/10/12. 3 | // 4 | 5 | #ifndef DATA_STRUCTURE_AND_ALGORITHM_BINARY_SEARCH_H 6 | #define DATA_STRUCTURE_AND_ALGORITHM_BINARY_SEARCH_H 7 | 8 | int BinarySearch(const int A[], int N, int X); 9 | int BinarySearchAi(const int A[], int N); 10 | #endif //DATA_STRUCTURE_AND_ALGORITHM_BINARY_SEARCH_H 11 | -------------------------------------------------------------------------------- /chapter2/permutation.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by aaron on 10/13/16. 3 | // 4 | 5 | #ifndef DATA_STRUCTURE_AND_ALGORITHM_PERMUTATION_H 6 | #define DATA_STRUCTURE_AND_ALGORITHM_PERMUTATION_H 7 | int* getPermutation_ON2LogN(int N); 8 | int* getPermutation_ONLogN(int N); 9 | int* getPermutation_ON(int N); 10 | #endif //DATA_STRUCTURE_AND_ALGORITHM_PERMUTATION_H 11 | -------------------------------------------------------------------------------- /chapter2/prime.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by aaron on 10/14/16. 3 | // 4 | 5 | #include "prime.h" 6 | #include "util.h" 7 | 8 | 9 | bool isPrime(long N) { 10 | if (N == 2) return true; 11 | if (isEven(N)) return false; 12 | 13 | for (int i = 3; i < N; i += 2) { 14 | if (N % i == 0) { 15 | return false; 16 | } 17 | } 18 | 19 | return true; 20 | } -------------------------------------------------------------------------------- /chapter3/testLinkedList.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by aaron on 10/30/16. 3 | // 4 | 5 | #include "linkedlist.h" 6 | #include 7 | 8 | int main(void) { 9 | int arr[] = {1, 2, 3, 4, 5}; 10 | List list = fromArray(arr, 5); 11 | printList(list); 12 | 13 | List reverse = reverseList(list->next); 14 | printList(reverse); 15 | 16 | deleteList(list); 17 | return 0; 18 | } -------------------------------------------------------------------------------- /.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 | # Debug files 32 | *.dSYM/ 33 | *.su 34 | 35 | .idea/ 36 | 37 | -------------------------------------------------------------------------------- /chapter6/test_binary_heap.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by aaron on 16-11-9. 3 | // 4 | #include "binary_heap.h" 5 | #include 6 | 7 | int main(void) { 8 | const int maxSize = 20; 9 | PriorityQueue H = initialize(maxSize); 10 | 11 | for (int i = 10; i > 0; i--) { 12 | insert(i, H); 13 | } 14 | 15 | for (int j = 0; j < 10; ++j) { 16 | printf("%d, ", deleteMin(H)); 17 | } 18 | 19 | destroy(H); 20 | } 21 | -------------------------------------------------------------------------------- /chapter5/prime.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by aaron on 16-11-5. 3 | // 4 | 5 | #include "prime.h" 6 | 7 | bool isPrime(size_t x) { 8 | for (size_t i = 3; true; i += 2) { 9 | size_t q = x / i; 10 | if (q < i) return true; 11 | if (x == q * i) return false; 12 | } 13 | return true; 14 | } 15 | 16 | size_t nextPrime(size_t x) { 17 | if (x <= 2) return 2; 18 | if (!(x & 1)) x++; 19 | while (!isPrime(x)) { 20 | x += 2; 21 | } 22 | return x; 23 | } -------------------------------------------------------------------------------- /chapter4/testSearchTree.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by aaron on 16-11-3. 3 | // 4 | 5 | #include 6 | #include "searchtree.h" 7 | 8 | void main(void) { 9 | int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; 10 | SearchTree T = makeEmpty(NULL); 11 | for (int i = 0; i < 10; ++i) { 12 | T = insert(a[i], T); 13 | } 14 | delete(10, T); 15 | preorderTraversal(T); 16 | printf("\n"); 17 | inorderTraversal(T); 18 | printf("\n"); 19 | postorderTraversal(T); 20 | } 21 | -------------------------------------------------------------------------------- /chapter5/test_hash_quad.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by aaron on 16-11-8. 3 | // 4 | 5 | #include 6 | #include "hashtable_quad.h" 7 | 8 | int main(void) { 9 | const unsigned int tableSize = 10; 10 | HashTable H = initializeTable(tableSize); 11 | for (int i = 0; i < 6; ++i) { 12 | insert(i*i, H); 13 | } 14 | 15 | H = rehash(H); 16 | 17 | for (int j = 0; j < 6; ++j) { 18 | printf("%d, ", retrive(find(j*j, H), H)); 19 | } 20 | destroyTable(H); 21 | } 22 | -------------------------------------------------------------------------------- /chapter2/MaxSubsequenceSum.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 董启宏 on 2016/10/12. 3 | // 4 | 5 | #ifndef DATA_STRUCTURE_AND_ALGORITHM_MAXSUBSEQUENCESUM_H 6 | #define DATA_STRUCTURE_AND_ALGORITHM_MAXSUBSEQUENCESUM_H 7 | 8 | int MaxSubsequenceSum_ON3(const int A[], int N); 9 | int MaxSubsequenceSum_ON2(const int A[], int N); 10 | int MaxSubsequenceSum_ONLogN(const int A[], int N); 11 | int MaxSubsequenceSum_ON(const int A[], int N); 12 | static int MaxSubSum(const int A[], int left, int right); 13 | 14 | #endif //DATA_STRUCTURE_AND_ALGORITHM_MAXSUBSEQUENCESUM_H 15 | -------------------------------------------------------------------------------- /chapter5/testhashmap.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by aaron on 16-11-5. 3 | // 4 | 5 | #include 6 | #include "hashtable.h" 7 | 8 | int main(void) { 9 | const int N = 100; 10 | HashTable hashTable = initializeTable(N); 11 | for (int i = 0; i < N; ++i) { 12 | insert(i*i, hashTable); 13 | } 14 | 15 | for (int j = 0; j < N; ++j) { 16 | int x = retrive(find(j*j, hashTable)); 17 | printf("%4d,", x); 18 | } 19 | printf("\ntableSize = %d\n", tableSize(hashTable)); 20 | destroyTable(hashTable); 21 | return 0; 22 | } -------------------------------------------------------------------------------- /chapter4/testAVLTree.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by aaron on 16-11-3. 3 | // 4 | 5 | #include 6 | #include 7 | #include "avltree.h" 8 | 9 | void main(void) { 10 | const int N = 16; 11 | AvlTree T = makeEmpty(NULL); 12 | int a[] = {1, 2, 3, 4, 5, 6, 7, 16, 15, 14, 13, 12, 11, 10, 8, 9}; 13 | for (int i = 0; i < N; ++i) { 14 | T = insert(a[i], T); 15 | } 16 | postorderTraversal(T); 17 | printf("\n"); 18 | printf("min: %d, max: %d\n", retrive(findMin(T)), retrive(findMax(T))); 19 | printf("find(3) == %d\n", retrive(find(19, T))); 20 | } -------------------------------------------------------------------------------- /chapter3/linkedstack.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by aaron on 10/25/16. 3 | // 4 | 5 | #ifndef DATA_STRUCTURE_AND_ALGORITHM_LISTSTACK_H 6 | #define DATA_STRUCTURE_AND_ALGORITHM_LISTSTACK_H 7 | 8 | #include 9 | 10 | struct Node; 11 | typedef struct Node *PtrToNode; 12 | typedef PtrToNode Stack; 13 | typedef int ElementType; 14 | 15 | bool isEmpty(Stack S); 16 | Stack createStack(void); 17 | void disposeStack(Stack S); 18 | void makeEmpty(Stack S); 19 | void push(ElementType X, Stack S); 20 | ElementType peek(Stack S); 21 | void pop(Stack S); 22 | 23 | #endif //DATA_STRUCTURE_AND_ALGORITHM_LISTSTACK_H 24 | -------------------------------------------------------------------------------- /chapter2/util.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 董启宏 on 2016/10/12. 3 | // 4 | 5 | #include 6 | 7 | #ifndef DATA_STRUCTURE_AND_ALGORITHM_UTIL_H 8 | #define DATA_STRUCTURE_AND_ALGORITHM_UTIL_H 9 | 10 | int* getSequence(int N); 11 | int max3(int a, int b, int c); 12 | int* getLinearSequence(int N); 13 | void printArray(int A[], int N); 14 | void printTestHeader(char* s); 15 | bool isEven(long n); 16 | bool isOdd(long n); 17 | int randInt(int i, int j); 18 | bool isContain(int* A, int X, int N); 19 | void swap(int* a, int* b); 20 | unsigned int msb(unsigned long N); 21 | #endif //DATA_STRUCTURE_AND_ALGORITHM_UTIL_H 22 | -------------------------------------------------------------------------------- /chapter3/arraystack.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by aaron on 10/25/16. 3 | // 4 | 5 | #include 6 | 7 | #ifndef DATA_STRUCTURE_AND_ALGORITHM_ARRAYSTACK_H 8 | #define DATA_STRUCTURE_AND_ALGORITHM_ARRAYSTACK_H 9 | struct StackRecord; 10 | typedef struct StackRecord *Stack; 11 | typedef int ElementType; 12 | 13 | bool isEmpty(Stack S); 14 | bool isFull(Stack S); 15 | Stack createStack(int maxElements); 16 | void disposeStack(Stack S); 17 | void makeEmpty(Stack S); 18 | void push(ElementType X, Stack S); 19 | ElementType peek(Stack S); 20 | void pop(Stack S); 21 | ElementType peekAndPop(Stack S); 22 | #endif //DATA_STRUCTURE_AND_ALGORITHM_ARRAYSTACK_H 23 | -------------------------------------------------------------------------------- /chapter7/sort.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by aaron on 16-11-14. 3 | // 4 | 5 | #ifndef DATA_STRUCTURE_AND_ALGORITHM_SORT_H 6 | #define DATA_STRUCTURE_AND_ALGORITHM_SORT_H 7 | 8 | #include 9 | 10 | typedef int ElementType; 11 | void swap(ElementType* a, ElementType *b); 12 | void InsertionSort(ElementType A[], size_t N); 13 | void ShellSort(ElementType A[], size_t N); 14 | void BubbleSort(ElementType A[], size_t N); 15 | void SelectionSort(ElementType A[], size_t N); 16 | void HeapSort(ElementType A[], size_t N); 17 | void MergeSort(ElementType A[], size_t N); 18 | void QuickSort(ElementType A[], size_t N); 19 | #endif //DATA_STRUCTURE_AND_ALGORITHM_SORT_H 20 | -------------------------------------------------------------------------------- /chapter3/arrayqueue.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by aaron on 10/25/16. 3 | // 4 | 5 | #include 6 | 7 | #ifndef DATA_STRUCTURE_AND_ALGORITHM_ARRAYQUEUE_H 8 | #define DATA_STRUCTURE_AND_ALGORITHM_ARRAYQUEUE_H 9 | struct QueueRecord; 10 | typedef struct QueueRecord *Queue; 11 | typedef int ElementType; 12 | 13 | bool isEmpty(Queue Q); 14 | bool isFull(Queue Q); 15 | Queue createQueue(int maxElements); 16 | void disposeQueue(Queue Q); 17 | void makeEmpty(Queue Q); 18 | void enqueue(ElementType X, Queue Q); 19 | ElementType front(Queue Q); 20 | void dequeue(Queue Q); 21 | ElementType frontAndDequeue(Queue Q); 22 | #endif //DATA_STRUCTURE_AND_ALGORITHM_ARRAYQUEUE_H 23 | -------------------------------------------------------------------------------- /chapter6/left_heap.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by aaron on 16-11-10. 3 | // 4 | 5 | #ifndef DATA_STRUCTURE_AND_ALGORITHM_LEFT_HEAP_H 6 | #define DATA_STRUCTURE_AND_ALGORITHM_LEFT_HEAP_H 7 | 8 | #include 9 | 10 | struct TreeNode; 11 | typedef struct TreeNode *PriorityQueue; 12 | typedef int ElementType; 13 | PriorityQueue Initialize(void); 14 | ElementType FindMin(PriorityQueue H); 15 | bool isEmpty(PriorityQueue H); 16 | PriorityQueue Merge(PriorityQueue H1, PriorityQueue H2); 17 | 18 | #define Insert(X, H) (H = Insert1((X), H)) 19 | 20 | PriorityQueue Insert1(ElementType X, PriorityQueue H); 21 | PriorityQueue DeleteMin1(PriorityQueue H); 22 | #endif //DATA_STRUCTURE_AND_ALGORITHM_LEFT_HEAP_H 23 | -------------------------------------------------------------------------------- /chapter4/avltree.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by aaron on 16-11-3. 3 | // 4 | 5 | #ifndef DATA_STRUCTURE_AND_ALGORITHM_AVLTREE_H 6 | #define DATA_STRUCTURE_AND_ALGORITHM_AVLTREE_H 7 | struct AvlNode; 8 | typedef struct AvlNode* Position; 9 | typedef struct AvlNode* AvlTree; 10 | typedef int ElementType; 11 | 12 | AvlTree makeEmpty(AvlTree T); 13 | Position find(ElementType X, AvlTree T); 14 | Position findMin(AvlTree T); 15 | Position findMax(AvlTree T); 16 | AvlTree insert(ElementType X, AvlTree T); 17 | AvlTree delete(ElementType X, AvlTree T); 18 | ElementType retrive(Position P); 19 | 20 | void preorderTraversal(AvlTree T); 21 | void inorderTraversal(AvlTree T); 22 | void postorderTraversal(AvlTree T); 23 | #endif //DATA_STRUCTURE_AND_ALGORITHM_AVLTREE_H 24 | -------------------------------------------------------------------------------- /chapter3/polynomial.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by aaron on 10/19/16. 3 | // 4 | 5 | #ifndef DATA_STRUCTURE_AND_ALGORITHM_POLYNOMIAL_H 6 | #define DATA_STRUCTURE_AND_ALGORITHM_POLYNOMIAL_H 7 | 8 | #define MAX_DEGREE 1000 9 | 10 | typedef struct { 11 | int coeffArray[MAX_DEGREE + 1]; 12 | int highPower; 13 | } * Polynomial; 14 | 15 | typedef struct Node* PtrToNode; 16 | 17 | struct Node { 18 | int coefficient; 19 | int exponent; 20 | PtrToNode next; 21 | }; 22 | 23 | void zeroPolynomial(Polynomial poly); 24 | void addPolynomial(const Polynomial poly1, const Polynomial poly2, Polynomial polySum); 25 | void multiplyPolynomial(const Polynomial poly1, const Polynomial poly2, Polynomial polyProd); 26 | #endif //DATA_STRUCTURE_AND_ALGORITHM_POLYNOMIAL_H 27 | -------------------------------------------------------------------------------- /chapter4/searchtree.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by aaron on 16-11-3. 3 | // 4 | 5 | #ifndef DATA_STRUCTURE_AND_ALGORITHM_SEARCHTREE_H 6 | #define DATA_STRUCTURE_AND_ALGORITHM_SEARCHTREE_H 7 | struct TreeNode; 8 | typedef struct TreeNode* Position; 9 | typedef struct TreeNode* SearchTree; 10 | typedef int ElementType; 11 | 12 | SearchTree makeEmpty(SearchTree T); 13 | Position find(ElementType X, SearchTree T); 14 | Position findMax(SearchTree T); 15 | Position findMin(SearchTree T); 16 | SearchTree insert(ElementType X, SearchTree T); 17 | SearchTree delete(ElementType X, SearchTree T); 18 | void preorderTraversal(SearchTree T); 19 | void inorderTraversal(SearchTree T); 20 | void postorderTraversal(SearchTree T); 21 | #endif //DATA_STRUCTURE_AND_ALGORITHM_SEARCHTREE_H 22 | -------------------------------------------------------------------------------- /chapter5/hashtable.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by aaron on 16-11-5. 3 | // 4 | 5 | #ifndef DATA_STRUCTURE_AND_ALGORITHM_HASHMAP_H 6 | #define DATA_STRUCTURE_AND_ALGORITHM_HASHMAP_H 7 | struct ListNode; 8 | typedef struct ListNode *Position; 9 | typedef Position Node; 10 | typedef Position List; 11 | 12 | struct HashTbl; 13 | typedef struct HashTbl *HashTable; 14 | typedef int ElementType; 15 | 16 | HashTable initializeTable(int tableSize); 17 | void destroyTable(HashTable hashTable); 18 | Position find(ElementType X, HashTable hashTable); 19 | void insert(ElementType X, HashTable hashTable); 20 | ElementType retrive(Position P); 21 | int hash(int key, int tableSize); 22 | static void destroyList(List L); 23 | int tableSize(HashTable hashTable); 24 | #endif //DATA_STRUCTURE_AND_ALGORITHM_HASHMAP_H 25 | -------------------------------------------------------------------------------- /chapter6/binary_heap.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by aaron on 16-11-9. 3 | // 4 | 5 | #include 6 | 7 | #ifndef DATA_STRUCTURE_AND_ALGORITHM_BINARY_HEAP_H 8 | #define DATA_STRUCTURE_AND_ALGORITHM_BINARY_HEAP_H 9 | 10 | typedef int ElementType; 11 | 12 | struct HeapStruct { 13 | int capacity; 14 | int size; 15 | ElementType *elements; 16 | }; 17 | 18 | typedef struct HeapStruct* PriorityQueue; 19 | 20 | PriorityQueue initialize(int maxElements); 21 | void destroy(PriorityQueue H); 22 | void makeEmpty(PriorityQueue H); 23 | void insert(ElementType X, PriorityQueue H); 24 | ElementType deleteMin(PriorityQueue H); 25 | ElementType findMin(PriorityQueue H); 26 | bool isEmpty(PriorityQueue H); 27 | bool isFull(PriorityQueue H); 28 | #endif //DATA_STRUCTURE_AND_ALGORITHM_BINARY_HEAP_H 29 | -------------------------------------------------------------------------------- /chapter2/pow.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by aaron on 10/13/16. 3 | // 4 | 5 | #include 6 | #include "pow.h" 7 | #include "util.h" 8 | 9 | long Pow(long X, unsigned long N) { 10 | unsigned int n = msb(N); 11 | long* powersOfX = malloc(n * sizeof(long)); 12 | powersOfX[0] = X; 13 | for (int i = 1; i < n; ++i) { 14 | powersOfX[i] = powersOfX[i-1] * powersOfX[i-1]; 15 | } 16 | 17 | long power = 1; 18 | int i = 0; 19 | while (N > 0) { 20 | if (N & 1) { 21 | power *= powersOfX[i]; 22 | } 23 | N >>= 1; 24 | i++; 25 | } 26 | 27 | return power; 28 | } 29 | 30 | long PowRecursion(long X, unsigned long N) { 31 | if (N == 0) { 32 | return 1; 33 | } else if (N == 1) { 34 | return X; 35 | } else if (isEven(N)) { 36 | return Pow(X * X, N / 2); 37 | } else { 38 | return Pow(X, N - 1) * X; 39 | } 40 | } 41 | 42 | -------------------------------------------------------------------------------- /chapter2/binary_search.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 董启宏 on 2016/10/12. 3 | // 4 | 5 | #include 6 | #include "binary_search.h" 7 | 8 | int BinarySearch(const int A[], int N, int X) { 9 | int low = 0; 10 | int high = N-1; 11 | while (low <= high) { 12 | int mid = (low + high) / 2; 13 | if (X > A[mid]) { 14 | low = mid + 1; 15 | } else if (X < A[mid]) { 16 | high = mid - 1; 17 | } else { 18 | return mid; 19 | } 20 | } 21 | 22 | return -1; 23 | } 24 | 25 | int BinarySearchAi(const int A[], int N) { 26 | int low = 0; 27 | int high = N-1; 28 | while (low <= high) { 29 | int mid = low + (high - low) / 2; 30 | if (mid == A[mid]) { 31 | return mid; 32 | } else if (mid > A[mid]) { 33 | low = mid + 1; 34 | } else { 35 | high = mid - 1; 36 | } 37 | } 38 | return -1; 39 | } -------------------------------------------------------------------------------- /chapter5/hashtable_quad.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by aaron on 16-11-8. 3 | // 4 | 5 | #ifndef DATA_STRUCTURE_AND_ALGORITHM_HASHTABLE_QUAD_H 6 | #define DATA_STRUCTURE_AND_ALGORITHM_HASHTABLE_QUAD_H 7 | 8 | typedef unsigned int Index; 9 | typedef Index Position; 10 | typedef int ElementType; 11 | 12 | enum KindOfEntry {Legitimate, Empty, Deleted}; 13 | 14 | struct HashEntry { 15 | ElementType element; 16 | enum KindOfEntry info; 17 | }; 18 | typedef struct HashEntry Cell; 19 | 20 | struct HashTbl { 21 | unsigned int tableSize; 22 | Cell *theCells; 23 | }; 24 | typedef struct HashTbl* HashTable; 25 | 26 | HashTable initializeTable(unsigned int tableSize); 27 | void destroyTable(HashTable H); 28 | Position find(ElementType Key, HashTable H); 29 | void insert(ElementType Key, HashTable H); 30 | ElementType retrive(Position P, HashTable H); 31 | HashTable rehash(HashTable H); 32 | 33 | 34 | #endif //DATA_STRUCTURE_AND_ALGORITHM_HASHTABLE_QUAD_H 35 | -------------------------------------------------------------------------------- /chapter3/cursor.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by aaron on 10/19/16. 3 | // 4 | 5 | #include 6 | 7 | #ifndef DATA_STRUCTURE_AND_ALGORITHM_CURSOR_H 8 | #define DATA_STRUCTURE_AND_ALGORITHM_CURSOR_H 9 | 10 | #define SPACE_SIZE 13 11 | 12 | typedef int PtrToNode; 13 | typedef PtrToNode List; 14 | typedef PtrToNode Position; 15 | typedef int ElementType; 16 | 17 | 18 | 19 | void initializeCursorSpace(void); 20 | static Position cursorAlloc(void); 21 | static void cursorFree(Position P); 22 | int capacity(void); 23 | 24 | List makeEmpty(List L); 25 | void deleteList(List L); 26 | bool isEmpty(const List L); 27 | bool isLast(const Position P, const List L); 28 | Position find(ElementType X, List L); 29 | Position findPrevious(ElementType X, List L); 30 | void delete(ElementType X, List L); 31 | void insert(ElementType X, List L, Position P); 32 | void printList(List L); 33 | List fromArray(ElementType* A, size_t N); 34 | 35 | 36 | #endif //DATA_STRUCTURE_AND_ALGORITHM_CURSOR_H 37 | -------------------------------------------------------------------------------- /chapter7/test_sort.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by aaron on 16-11-14. 3 | // 4 | 5 | #include 6 | #include 7 | #include 8 | #include "sort.h" 9 | 10 | int* getSequence(int N) { 11 | const int MAX = 100; 12 | srand((unsigned int) time(0)); 13 | int* A = malloc(N * sizeof(int)); 14 | for (int i = 0; i < N; ++i) { 15 | A[i] = rand() % MAX; 16 | } 17 | return A; 18 | } 19 | 20 | void printArray(int A[], int N) { 21 | const int LINE = 10; 22 | for (int i = 0; i < N; ++i) { 23 | if (i % LINE == 0) { 24 | printf("\n"); 25 | } 26 | printf("%4d, ", A[i]); 27 | } 28 | printf("\n\n"); 29 | } 30 | 31 | int main(void) { 32 | const size_t N = 30; 33 | int* A = getSequence(N); 34 | 35 | printArray(A, N); 36 | // InsertionSort(A, N); 37 | // ShellSort(A, N); 38 | // BubbleSort(A, N); 39 | // SelectionSort(A, N); 40 | // HeapSort(A, N); 41 | // MergeSort(A, N); 42 | QuickSort(A, N); 43 | printArray(A, N); 44 | 45 | 46 | } -------------------------------------------------------------------------------- /chapter3/linkedlist.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by aaron on 10/19/16. 3 | // 4 | 5 | #ifndef DATA_STRUCTURE_AND_ALGORITHM_LINKEDLIST_H 6 | #define DATA_STRUCTURE_AND_ALGORITHM_LINKEDLIST_H 7 | 8 | #include 9 | #include 10 | 11 | typedef struct Node* PtrToNode; 12 | typedef PtrToNode List; 13 | typedef PtrToNode Position; 14 | typedef int ElementType; 15 | 16 | struct Node { 17 | ElementType element; 18 | Position next; 19 | }; 20 | 21 | bool isLast(Position P, List L); 22 | bool isEmpty(List L); 23 | void makeEmpty(List L); 24 | void deleteList(List L); 25 | Position find(ElementType X, List L); 26 | Position findPrevious(ElementType X, List L); 27 | void insert(ElementType X, List L, Position P); 28 | void delete(ElementType X, List L); 29 | void printList(List L); 30 | List fromArray(ElementType* A, size_t N); 31 | Position header(List L); 32 | Position first(List L); 33 | Position advance(Position P); 34 | 35 | List intersect(List L1, List L2); 36 | List Union(List L1, List L2); 37 | List reverseList(List L); 38 | 39 | #endif //DATA_STRUCTURE_AND_ALGORITHM_LINKEDLIST_H 40 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Dong Qihong 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 | -------------------------------------------------------------------------------- /chapter3/polynomial.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by aaron on 10/19/16. 3 | // 4 | 5 | #include 6 | #include "polynomial.h" 7 | #include "util.h" 8 | 9 | void zeroPolynomial(Polynomial poly) { 10 | for (int i = 0; i < MAX_DEGREE; ++i) { 11 | poly->coeffArray[i] = 0; 12 | } 13 | 14 | poly->highPower = 0; 15 | } 16 | 17 | void addPolynomial(const Polynomial poly1, const Polynomial poly2, Polynomial polySum) { 18 | zeroPolynomial(polySum); 19 | polySum->highPower = max(poly1->highPower, poly2->highPower); 20 | for (int i = polySum->highPower; i >= 0; i--) { 21 | polySum->coeffArray[i] = poly1->coeffArray[i] + poly2->coeffArray[i]; 22 | } 23 | } 24 | 25 | void multiplyPolynomial(const Polynomial poly1, const Polynomial poly2, Polynomial polyProd) { 26 | zeroPolynomial(polyProd); 27 | polyProd->highPower = poly1->highPower + poly2->highPower; 28 | if (polyProd->highPower > MAX_DEGREE) { 29 | perror("multiplyPolynomial()"); 30 | return; 31 | } else { 32 | for (int i = 0; i < poly1->highPower; ++i) { 33 | for (int j = 0; j < poly2->highPower; ++j) { 34 | polyProd->coeffArray[i + j] += poly1->coeffArray[i] * poly2->coeffArray[j]; 35 | } 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /chapter3/exercise.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by aaron on 10/30/16. 3 | // 4 | 5 | #include 6 | #include 7 | #include 8 | #include "linkedlist.h" 9 | 10 | void printLots(List L, List P) { 11 | int counter = 1; 12 | Position l = first(L); 13 | Position p = first(P); 14 | while(l != NULL && p != NULL) { 15 | if (p->element == counter++) { 16 | printf("%d, ", l->element); 17 | p = advance(p); 18 | } 19 | l = advance(l); 20 | } 21 | } 22 | 23 | void swapWithNext(Position beforeP, List L) { 24 | Position P = beforeP->next; 25 | Position afterP = P->next; 26 | beforeP->next = afterP; 27 | P->next = afterP->next; 28 | afterP->next = P; 29 | } 30 | 31 | void main(void) { 32 | int arrL[] = {1, 2, 4, 5, 7}; 33 | List L = fromArray(arrL, 5); 34 | printList(L); 35 | 36 | int arrP[] = {1, 2, 3, 7, 9}; 37 | List P = fromArray(arrP, 5); 38 | printList(P); 39 | 40 | // printLots(L, P); 41 | 42 | // Position p2 = find(2, L); 43 | // swapWithNext(p2, L); 44 | // printList(L); 45 | 46 | List L12 = intersect(L, P); 47 | printList(L12); 48 | 49 | List UnionList = Union(L, P); 50 | 51 | printList(UnionList); 52 | 53 | deleteList(L); 54 | deleteList(P); 55 | deleteList(L12); 56 | deleteList(UnionList); 57 | } -------------------------------------------------------------------------------- /chapter6/left_heap.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by aaron on 16-11-10. 3 | // 4 | 5 | #include 6 | #include "left_heap.h" 7 | 8 | struct TreeNode { 9 | ElementType Element; 10 | PriorityQueue Left; 11 | PriorityQueue Right; 12 | int Npl; 13 | }; 14 | 15 | PriorityQueue Initialize(void) { 16 | PriorityQueue H = malloc(sizeof(struct TreeNode)); 17 | H->Left = NULL; 18 | H->Right = NULL; 19 | H->Npl = 0; 20 | return H; 21 | } 22 | 23 | ElementType FindMin(PriorityQueue H); 24 | bool isEmpty(PriorityQueue H); 25 | 26 | static PriorityQueue Merge1(PriorityQueue H1, PriorityQueue H2) { 27 | if (H1->Left == NULL) { 28 | H1->Left = H2; 29 | } else { 30 | H1->Right = Merge(H1->Right, H2); 31 | if (H1->Left->Npl < H1->Right->Npl) { 32 | SwapChildren(H1); 33 | } 34 | H1->Npl = H1->Right->Npl + 1; 35 | } 36 | return H1; 37 | } 38 | 39 | PriorityQueue Merge(PriorityQueue H1, PriorityQueue H2) { 40 | if (H1 == NULL) { 41 | return H2; 42 | } 43 | if (H2 == NULL) { 44 | return H1; 45 | } 46 | if (H1->Element < H2->Element) { 47 | return Merge1(H1, H2); 48 | } else { 49 | return Merge1(H2, H1); 50 | } 51 | } 52 | 53 | 54 | PriorityQueue Insert1(ElementType X, PriorityQueue H); 55 | PriorityQueue DeleteMin1(PriorityQueue H); -------------------------------------------------------------------------------- /chapter2/permutation.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by aaron on 10/13/16. 3 | // 4 | 5 | #include 6 | #include 7 | #include "permutation.h" 8 | #include "util.h" 9 | 10 | int* getPermutation_ON2LogN(int N) { 11 | srand((unsigned int) time(0)); 12 | 13 | int* A = malloc(N * sizeof(int)); 14 | 15 | int i = 0; 16 | while (i < N) { 17 | int n = randInt(1, N); 18 | if (isContain(A, n, i)) { 19 | continue; 20 | } else { 21 | A[i++] = n; 22 | } 23 | } 24 | return A; 25 | } 26 | 27 | int* getPermutation_ONLogN(int N) { 28 | srand((unsigned int) time(0)); 29 | 30 | int* A = malloc(N * sizeof(int)); 31 | bool* used = malloc((N+1) * sizeof(bool)); 32 | for (int j = 0; j < N + 1; ++j) { 33 | used[j] = false; 34 | } 35 | 36 | int i = 0; 37 | while (i < N) { 38 | int n = randInt(1, N); 39 | if (used[n]) continue; 40 | used[n] = true; 41 | A[i++] = n; 42 | } 43 | 44 | free(used); 45 | return A; 46 | } 47 | 48 | int* getPermutation_ON(int N) { 49 | srand((unsigned int) time(0)); 50 | 51 | int* A = malloc(N * sizeof(int)); 52 | for (int i = 0; i < N; ++i) { 53 | A[i] = i + 1; 54 | } 55 | 56 | for (int j = 1; j < N; ++j) { 57 | swap(&A[j], &A[randInt(0, j)]); 58 | } 59 | 60 | return A; 61 | } 62 | -------------------------------------------------------------------------------- /chapter3/linkedstack.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by aaron on 10/25/16. 3 | // 4 | 5 | #include 6 | #include 7 | #include 8 | #include "linkedstack.h" 9 | 10 | struct Node { 11 | PtrToNode next; 12 | ElementType element; 13 | }; 14 | 15 | bool isEmpty(Stack S) { 16 | return S->next == NULL ? true : false; 17 | } 18 | 19 | Stack createStack(void) { 20 | Stack S = malloc(sizeof(struct Node)); 21 | if (S == NULL) { 22 | perror("createStack()"); 23 | return NULL; 24 | } 25 | 26 | S->next = NULL; 27 | makeEmpty(S); 28 | return S; 29 | } 30 | 31 | void disposeStack(Stack S) { 32 | makeEmpty(S); 33 | free(S); 34 | } 35 | 36 | void makeEmpty(Stack S) { 37 | while (!isEmpty(S)) { 38 | pop(S); 39 | } 40 | } 41 | 42 | void push(ElementType X, Stack S) { 43 | PtrToNode tmp = malloc(sizeof(struct Node)); 44 | if (tmp == NULL) { 45 | perror("push()"); 46 | return; 47 | } 48 | tmp->element = X; 49 | tmp->next = S->next; 50 | S->next = tmp; 51 | } 52 | 53 | ElementType peek(Stack S) { 54 | if (isEmpty(S)) { 55 | fprintf(stderr, "Error! Empty Stack!\n"); 56 | return -1; 57 | } 58 | return S->next->element; 59 | } 60 | 61 | void pop(Stack S) { 62 | if (isEmpty(S)) { 63 | fprintf(stderr, "Error! Empty Stack!\n"); 64 | return; 65 | } 66 | PtrToNode tmp = S->next; 67 | S->next = S->next->next; 68 | free(tmp); 69 | } -------------------------------------------------------------------------------- /chapter3/arraystack.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by aaron on 10/25/16. 3 | // 4 | 5 | #include 6 | #include 7 | #include "arraystack.h" 8 | #define EmptyTOS (-1) 9 | #define MinStackSize (5) 10 | 11 | struct StackRecord { 12 | int capacity; 13 | int topOfStack; 14 | ElementType *array; 15 | }; 16 | 17 | bool isEmpty(Stack S) { 18 | return S->topOfStack == EmptyTOS; 19 | } 20 | 21 | bool isFull(Stack S) { 22 | return S->topOfStack == S->capacity-1; 23 | } 24 | 25 | Stack createStack(int maxElements) { 26 | Stack S = malloc(sizeof(struct StackRecord)); 27 | S->capacity = maxElements; 28 | S->topOfStack = EmptyTOS; 29 | S->array = malloc(maxElements * sizeof(ElementType)); 30 | return S; 31 | } 32 | 33 | void disposeStack(Stack S) { 34 | if (S != NULL) { 35 | free(S->array); 36 | free(S); 37 | } 38 | } 39 | 40 | void makeEmpty(Stack S) { 41 | S->topOfStack = EmptyTOS; 42 | } 43 | 44 | void push(ElementType X, Stack S) { 45 | if (!isFull(S)) { 46 | S->array[S->topOfStack+1] = X; 47 | S->topOfStack++; 48 | } 49 | } 50 | 51 | ElementType peek(Stack S) { 52 | if (isEmpty(S)) { 53 | fprintf(stderr, "Empty Stack!"); 54 | return EmptyTOS; 55 | } 56 | return S->array[S->topOfStack]; 57 | } 58 | 59 | void pop(Stack S) { 60 | if (isEmpty(S)) { 61 | fprintf(stderr, "Empty Stack!"); 62 | return; 63 | } 64 | S->topOfStack--; 65 | } 66 | 67 | ElementType peekAndPop(Stack S) { 68 | if (isEmpty(S)) { 69 | fprintf(stderr, "Empty Stack!"); 70 | return EmptyTOS; 71 | } 72 | return S->array[S->topOfStack--]; 73 | } -------------------------------------------------------------------------------- /chapter3/joesphus.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by aaron on 10/30/16. 3 | // 4 | 5 | 6 | #include 7 | #include 8 | 9 | struct Node { 10 | int id; 11 | struct Node* next; 12 | struct Node* prev; 13 | }; 14 | 15 | typedef struct Node* PtrToNode; 16 | typedef PtrToNode Circle; 17 | 18 | 19 | Circle makeCircle(int n) { 20 | Circle c = malloc(sizeof(struct Node)); 21 | c->id = 1; 22 | PtrToNode p = c; 23 | for (int i = 2; i <= n ; ++i) { 24 | PtrToNode tmp = malloc(sizeof(struct Node)); 25 | tmp->id = i; 26 | 27 | tmp->prev = p; 28 | p->next = tmp; 29 | 30 | p = p->next; 31 | if (i == n) { 32 | p->next = c; 33 | c->prev = p; 34 | } 35 | } 36 | return c; 37 | } 38 | 39 | void deleteNode(PtrToNode P) { 40 | P->prev->next = P->next; 41 | P->next->prev = P->prev; 42 | free(P); 43 | } 44 | 45 | void printCircle(Circle C) { 46 | PtrToNode pointer = C; 47 | do { 48 | printf("%d -> ", pointer->id); 49 | pointer = pointer->next; 50 | } while (pointer != C); 51 | printf("\n"); 52 | } 53 | 54 | void joesphus(int m, int n) { 55 | if (n < 1) { 56 | fprintf(stderr, "n must >= 1\n"); 57 | return; 58 | } 59 | m = m % n; 60 | Circle C = makeCircle(n); 61 | printCircle(C); 62 | 63 | while (n > 1) { 64 | for (int i = 0; i < m; ++i) { 65 | C = C->next; 66 | } 67 | printf("Player %d is out\n", C->id); 68 | PtrToNode P = C; 69 | C = C->next; 70 | deleteNode(P); 71 | 72 | printCircle(C); 73 | n--; 74 | } 75 | } 76 | 77 | void main(void) { 78 | joesphus(2, 41); 79 | } 80 | -------------------------------------------------------------------------------- /chapter6/binary_heap.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by aaron on 16-11-9. 3 | // 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include "binary_heap.h" 10 | 11 | PriorityQueue initialize(int maxElements) { 12 | PriorityQueue H = malloc(sizeof(struct HeapStruct)); 13 | H->capacity = maxElements; 14 | H->elements = malloc(sizeof(ElementType) * (maxElements+1)); 15 | H->elements[0] = INT_MIN; 16 | H->size = 0; 17 | return H; 18 | } 19 | 20 | void destroy(PriorityQueue H) { 21 | free(H->elements); 22 | free(H); 23 | } 24 | 25 | void makeEmpty(PriorityQueue H) { 26 | H->size = 0; 27 | } 28 | 29 | void insert(ElementType X, PriorityQueue H) { 30 | if (isFull(H)) { 31 | printf("Priority Queue is full\n"); 32 | return; 33 | } 34 | int i; 35 | for (i = ++H->size; H->elements[i/2] > X; i /= 2) { 36 | H->elements[i] = H->elements[i/2]; 37 | } 38 | H->elements[i] = X; 39 | } 40 | 41 | ElementType deleteMin(PriorityQueue H) { 42 | if (isEmpty(H)) { 43 | printf("Priority Queue is empty!\n"); 44 | return H->elements[0]; 45 | } 46 | ElementType min = H->elements[1]; 47 | ElementType last = H->elements[H->size--]; 48 | int i, child; 49 | for (i = 1; 2*i <= H->size ; i = child) { 50 | child = 2*i; 51 | if (child != H->size && H->elements[child+1] < H->elements[child]) { 52 | child++; 53 | } 54 | if (last > H->elements[child]) { 55 | H->elements[i] = H->elements[child]; 56 | } else { 57 | break; 58 | } 59 | } 60 | H->elements[i] = last; 61 | return min; 62 | 63 | } 64 | 65 | ElementType findMin(PriorityQueue H) { 66 | return H->elements[1]; 67 | } 68 | 69 | bool isEmpty(PriorityQueue H) { 70 | return H->size == 0; 71 | } 72 | 73 | bool isFull(PriorityQueue H) { 74 | return H->size == H->capacity; 75 | } -------------------------------------------------------------------------------- /chapter3/arrayqueue.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by aaron on 10/25/16. 3 | // 4 | 5 | #include 6 | #include 7 | #include "arrayqueue.h" 8 | 9 | struct QueueRecord { 10 | int Capacity; 11 | int Front; 12 | int Rear; 13 | int Size; 14 | ElementType *Array; 15 | }; 16 | 17 | bool isEmpty(Queue Q) { 18 | return Q->Size == 0; 19 | } 20 | 21 | bool isFull(Queue Q) { 22 | return Q->Size == Q->Capacity; 23 | } 24 | 25 | Queue createQueue(int maxElements) { 26 | Queue Q = malloc(sizeof(struct QueueRecord)); 27 | Q->Capacity = maxElements; 28 | Q->Array = malloc(maxElements * sizeof(ElementType)); 29 | makeEmpty(Q); 30 | return Q; 31 | } 32 | 33 | void disposeQueue(Queue Q) { 34 | free(Q->Array); 35 | free(Q); 36 | } 37 | 38 | void makeEmpty(Queue Q) { 39 | Q->Size = 0; 40 | Q->Front = 1; 41 | Q->Rear = 0; 42 | } 43 | 44 | static int succ(int val, Queue Q) { 45 | if (++val == Q->Capacity) { 46 | val = 0; 47 | } 48 | return val; 49 | } 50 | 51 | void enqueue(ElementType X, Queue Q) { 52 | if (isFull(Q)) { 53 | fprintf(stderr, "Queue is full!\n"); 54 | return; 55 | } 56 | Q->Size++; 57 | Q->Rear = succ(Q->Rear, Q); 58 | Q->Array[Q->Rear] = X; 59 | } 60 | 61 | ElementType front(Queue Q) { 62 | if (isEmpty(Q)) { 63 | fprintf(stderr, "Queue is empty!\n"); 64 | return -1; 65 | } 66 | return Q->Array[Q->Front]; 67 | } 68 | 69 | void dequeue(Queue Q) { 70 | if (isEmpty(Q)) { 71 | fprintf(stderr, "Queue is empty!\n"); 72 | return; 73 | } 74 | Q->Size--; 75 | Q->Front = succ(Q->Front, Q); 76 | } 77 | 78 | ElementType frontAndDequeue(Queue Q) { 79 | if (isEmpty(Q)) { 80 | fprintf(stderr, "Queue is empty!\n"); 81 | return -1; 82 | } 83 | Q->Size--; 84 | ElementType front = Q->Array[Q->Front]; 85 | Q->Front = succ(Q->Front, Q); 86 | return front; 87 | } -------------------------------------------------------------------------------- /chapter2/util.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 董启宏 on 2016/10/12. 3 | // 4 | 5 | #include 6 | #include 7 | #include 8 | #include "util.h" 9 | 10 | int max3(int a, int b, int c) { 11 | int temp = a > b ? a : b; 12 | return temp > c ? temp : c; 13 | } 14 | 15 | int* getSequence(int N) { 16 | const int MAX = 1000; 17 | srand((unsigned int) time(0)); 18 | int* A = malloc(N * sizeof(int)); 19 | for (int i = 0; i < N; ++i) { 20 | A[i] = (rand() - RAND_MAX / 2) % MAX; 21 | } 22 | return A; 23 | } 24 | 25 | int* getLinearSequence(int N) { 26 | const int MAX = 1000; 27 | srand((unsigned int) time(0)); 28 | int* A = malloc(N * sizeof(int)); 29 | int n = (rand() - RAND_MAX / 2) % MAX; 30 | int step = 1 + rand() % 10; 31 | for (int i = 0; i < N; ++i) { 32 | n += step; 33 | A[i] = n; 34 | } 35 | return A; 36 | } 37 | 38 | void printArray(int A[], int N) { 39 | const int LINE = 10; 40 | for (int i = 0; i < N; ++i) { 41 | if (i % LINE == 0) { 42 | printf("\n"); 43 | } 44 | printf("%4d, ", A[i]); 45 | } 46 | printf("\n\n"); 47 | } 48 | 49 | void printTestHeader(char* s) { 50 | printf("\n=====================================\n"); 51 | printf("%s\n", s); 52 | printf("=====================================\n"); 53 | } 54 | 55 | bool isEven(long n) { 56 | return (n & 1) ? false : true; 57 | } 58 | 59 | bool isOdd(long n) { 60 | return (n & 1) ? true : false; 61 | } 62 | 63 | int randInt(int i, int j) { 64 | return i + (rand() % (j-i+1)); 65 | } 66 | 67 | bool isContain(int* A, int X, int N) { 68 | for (int i = 0; i < N; ++i) { 69 | if (A[i] == X) { 70 | return true; 71 | } 72 | } 73 | return false; 74 | } 75 | 76 | void swap(int* a, int* b) { 77 | int tmp = *a; 78 | *a = *b; 79 | *b = tmp; 80 | } 81 | 82 | unsigned int msb(unsigned long N) { 83 | unsigned int n = 0; 84 | while (N) { 85 | N >>= 1; 86 | n += 1; 87 | } 88 | return n; 89 | } -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.6) 2 | project(data_structure_and_algorithm) 3 | 4 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") 5 | 6 | #set(SOURCE_FILES chapter2/fib.c chapter2/fib.h chapter2/binary_search.c chapter2/binary_search.h chapter2/MaxSubsequenceSum.c chapter2/MaxSubsequenceSum.h chapter2/main.c chapter2/util.c chapter2/util.h chapter2/gcd.c chapter2/gcd.h chapter2/pow.c chapter2/pow.h chapter2/permutation.c chapter2/permutation.h chapter2/horner.c chapter2/horner.h chapter2/prime.c chapter2/prime.h chapter3/linkedlist.c chapter3/linkedlist.h) 7 | #add_executable(data_structure_and_algorithm ${SOURCE_FILES}) 8 | #set(SOURCE_FILES chapter3/main.c chapter3/polynomial.c chapter3/polynomial.h chapter3/util.c chapter3/util.h chapter3/cursor.c chapter3/cursor.h chapter3/linkedstack.c chapter3/linkedstack.h) 9 | #add_executable(data_structure_and_algorithm ${SOURCE_FILES}) 10 | 11 | #set(SOURCE_FILES chapter3/main.c chapter3/arrayqueue.c chapter3/arrayqueue.h chapter3/exercise.c) 12 | #set(SOURCE_FILES chapter3/linkedlist.h chapter3/linkedlist.c chapter3/exercise.c chapter3/joesphus.c) 13 | #set(SOURCE_FILES chapter3/joesphus.c chapter3/testLinkedList.c) 14 | 15 | #set(SOURCE_FILES chapter4/searchtree.c chapter4/searchtree.h chapter4/testSearchTree.c) 16 | #set(SOURCE_FILES chapter4/avltree.c chapter4/avltree.h chapter4/testAVLTree.c chapter5/hashmap.c chapter5/hashmap.h) 17 | #set(SOURCE_FILES chapter5/hashtable.c chapter5/hashtable.h chapter5/prime.c chapter5/prime.h chapter5/testhashmap.c chapter5/hashtable_quad.c chapter5/hashtable_quad.h) 18 | #set(SOURCE_FILES chapter5/prime.c chapter5/prime.h chapter5/hashtable_quad.c chapter5/hashtable_quad.h chapter5/test_hash_quad.c chapter6/binary_heap.c chapter6/binary_heap.h) 19 | #set(SOURCE_FILES chapter6/binary_heap.c chapter6/binary_heap.h chapter6/test_binary_heap.c chapter6/left_heap.c chapter6/left_heap.h) 20 | #set(SOURCE_FILES chapter6/left_heap.c chapter6/left_heap.h chapter7/sort.c chapter7/sort.h) 21 | set(SOURCE_FILES chapter7/sort.c chapter7/sort.h chapter7/test_sort.c) 22 | add_executable(data_structure_and_algorithm ${SOURCE_FILES}) -------------------------------------------------------------------------------- /chapter5/hashtable_quad.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by aaron on 16-11-8. 3 | // 4 | 5 | #include 6 | #include "hashtable_quad.h" 7 | #include "prime.h" 8 | 9 | HashTable initializeTable(unsigned int tableSize) { 10 | HashTable H = malloc(sizeof(struct HashTbl)); 11 | if (H == NULL) { 12 | printf("Error, out of space!\n"); 13 | return NULL; 14 | } 15 | H->tableSize = nextPrime(tableSize); 16 | H->theCells = malloc(sizeof(struct HashEntry) * H->tableSize); 17 | if (H->theCells == NULL) { 18 | printf("Error, out of space!\n"); 19 | return NULL; 20 | } 21 | for (int i = 0; i < H->tableSize; ++i) { 22 | H->theCells[i].info = Empty; 23 | } 24 | 25 | return H; 26 | } 27 | 28 | void destroyTable(HashTable H) { 29 | if (H != NULL) { 30 | if (H->theCells != NULL) { 31 | free(H->theCells); 32 | } 33 | free(H); 34 | } 35 | } 36 | 37 | static Index hash(ElementType key, unsigned int tableSize) { 38 | return key % tableSize; 39 | } 40 | 41 | Position find(ElementType Key, HashTable H) { 42 | Position currentPos = hash(Key, H->tableSize); 43 | int collisionNum = 0; 44 | while (H->theCells[currentPos].info != Empty 45 | && H->theCells[currentPos].element != Key) { 46 | currentPos += 2 * ++collisionNum + 1; 47 | if (currentPos >= H->tableSize) { 48 | currentPos -= H->tableSize; 49 | } 50 | } 51 | return currentPos; 52 | } 53 | 54 | void insert(ElementType Key, HashTable H) { 55 | Position pos = find(Key, H); 56 | if (H->theCells[pos].info != Legitimate) { 57 | H->theCells[pos].element = Key; 58 | H->theCells[pos].info = Legitimate; 59 | } 60 | } 61 | 62 | ElementType retrive(Position P, HashTable H) { 63 | if (H != NULL) { 64 | return H->theCells[P].element; 65 | } 66 | return -1; 67 | } 68 | 69 | HashTable rehash(HashTable H) { 70 | unsigned int oldSize = H->tableSize; 71 | Cell *oldCells = H->theCells; 72 | H = initializeTable(2 * oldSize); 73 | for (int i = 0; i < oldSize; ++i) { 74 | if (oldCells[i].info == Legitimate) { 75 | insert(oldCells[i].element, H); 76 | } 77 | } 78 | free(oldCells); 79 | return H; 80 | } -------------------------------------------------------------------------------- /chapter2/MaxSubsequenceSum.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 董启宏 on 2016/10/12. 3 | // 4 | 5 | #include "MaxSubsequenceSum.h" 6 | #include "util.h" 7 | 8 | int MaxSubsequenceSum_ON3(const int A[], int N) { 9 | int maxSum = 0; 10 | for (int i = 0; i < N; ++i) { 11 | for (int j = i; j < N; ++j) { 12 | int thisSum = 0; 13 | for (int k = i; k <= j; ++k) { 14 | thisSum += A[k]; 15 | } 16 | if (thisSum > maxSum) { 17 | maxSum = thisSum; 18 | } 19 | } 20 | } 21 | return maxSum; 22 | } 23 | 24 | int MaxSubsequenceSum_ON2(const int A[], int N) { 25 | int maxSum = 0; 26 | for (int i = 0; i < N; ++i) { 27 | int thisSum = 0; 28 | for (int j = i; j < N; ++j) { 29 | thisSum += A[j]; 30 | if (thisSum > maxSum) { 31 | maxSum = thisSum; 32 | } 33 | } 34 | } 35 | return maxSum; 36 | } 37 | 38 | int MaxSubsequenceSum_ONLogN(const int A[], int N) { 39 | return MaxSubSum(A, 0, N-1); 40 | } 41 | 42 | static int MaxSubSum(const int A[], int left, int right) { 43 | if (left == right) { 44 | if (A[left] > 0) { 45 | return A[left]; 46 | } else { 47 | return 0; 48 | } 49 | } 50 | 51 | int center = (left + right) / 2; 52 | int maxLeftSum = MaxSubSum(A, left, center); 53 | int maxRightSum = MaxSubSum(A, center+1, right); 54 | 55 | int maxLeftBorderSum = 0; 56 | int leftBorderSum = 0; 57 | for (int i = center; i >= left; i--) { 58 | leftBorderSum += A[i]; 59 | if (leftBorderSum > maxLeftBorderSum) { 60 | maxLeftBorderSum = leftBorderSum; 61 | } 62 | } 63 | 64 | int maxRightBorderSum = 0; 65 | int rightBorderSum = 0; 66 | for (int i = center+1; i <= right; i++) { 67 | rightBorderSum += A[i]; 68 | if (rightBorderSum > maxRightBorderSum) { 69 | maxRightBorderSum = rightBorderSum; 70 | } 71 | } 72 | 73 | return max3(maxLeftSum, maxRightSum, maxLeftBorderSum + maxRightBorderSum); 74 | 75 | } 76 | 77 | int MaxSubsequenceSum_ON(const int A[], int N) { 78 | int thisSum = 0; 79 | int maxSum = 0; 80 | for (int i = 0; i < N; ++i) { 81 | thisSum += A[i]; 82 | if (thisSum > maxSum) { 83 | maxSum = thisSum; 84 | } else if (thisSum < 0) { 85 | thisSum = 0; 86 | } 87 | } 88 | 89 | return maxSum; 90 | } -------------------------------------------------------------------------------- /chapter5/hashtable.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by aaron on 16-11-5. 3 | // 4 | 5 | #include 6 | #include 7 | #include "hashtable.h" 8 | #include "prime.h" 9 | 10 | struct ListNode { 11 | ElementType element; 12 | Node next; 13 | }; 14 | 15 | struct HashTbl { 16 | int tableSize; 17 | List *theLists; 18 | }; 19 | 20 | static void printError(char* func, char* s) { 21 | fprintf(stderr, "%s: %s\n", func, s); 22 | } 23 | 24 | int hash(int key, int tableSize) { 25 | return key % tableSize; 26 | } 27 | 28 | 29 | HashTable initializeTable(int tableSize) { 30 | HashTable hashTable = malloc(sizeof(struct HashTbl)); 31 | if (hashTable == NULL) { 32 | printError("initializeTable","out of space!"); 33 | return NULL; 34 | } 35 | hashTable->tableSize = nextPrime(tableSize); 36 | hashTable->theLists = malloc(hashTable->tableSize * sizeof(List)); 37 | if (hashTable->theLists == NULL) { 38 | printError("initializeTable","out of space!"); 39 | return NULL; 40 | } 41 | 42 | for (int i = 0; i < hashTable->tableSize; ++i) { 43 | hashTable->theLists[i] = malloc(sizeof(struct ListNode)); 44 | if (hashTable->theLists[i] == NULL) { 45 | printError("initializeTable","out of space!"); 46 | return NULL; 47 | } else { 48 | hashTable->theLists[i]->next = NULL; 49 | } 50 | 51 | } 52 | 53 | return hashTable; 54 | } 55 | 56 | void destroyTable(HashTable hashTable) { 57 | for (int i = 0; i < hashTable->tableSize; ++i) { 58 | destroyList(hashTable->theLists[i]); 59 | } 60 | free(hashTable); 61 | } 62 | 63 | Position find(ElementType X, HashTable hashTable) { 64 | List L = hashTable->theLists[hash(X, hashTable->tableSize)]; 65 | Position P = L->next; 66 | while (P != NULL && P->element != X) { 67 | P = P->next; 68 | } 69 | return P; 70 | } 71 | 72 | void insert(ElementType X, HashTable hashTable) { 73 | if (find(X, hashTable) == NULL) { 74 | List L = hashTable->theLists[hash(X, hashTable->tableSize)]; 75 | Node tmp = malloc(sizeof(struct ListNode)); 76 | tmp->element = X; 77 | tmp->next = L->next; 78 | L->next = tmp; 79 | } 80 | } 81 | 82 | ElementType retrive(Position P) { 83 | if (P != NULL) return P->element; 84 | else return -1; 85 | } 86 | 87 | static void destroyList(List L) { 88 | Position P; 89 | while (L != NULL) { 90 | P = L; 91 | L = L->next; 92 | free(P); 93 | } 94 | } 95 | 96 | int tableSize(HashTable hashTable) { 97 | if (hashTable != NULL) { 98 | return hashTable->tableSize; 99 | } 100 | return 0; 101 | } -------------------------------------------------------------------------------- /chapter3/main.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by aaron on 10/18/16. 3 | // 4 | 5 | #include 6 | //#include "linkedlist.h" 7 | //#include "cursor.h" 8 | //#include "linkedstack.h" 9 | //#include "arraystack.h" 10 | //#include "arrayqueue.h" 11 | 12 | //void testCursor() { 13 | // initializeCursorSpace(); 14 | // int arr[] = {1, 2, 3, 4 ,5}; 15 | // List list = fromArray(arr, 5); 16 | // printList(list); 17 | // 18 | // Position P = find(3, list); 19 | // insert(0, list, P); 20 | // printList(list); 21 | // 22 | // delete(1, list); 23 | // printList(list); 24 | // 25 | // delete(-1, list); 26 | // printList(list); 27 | // 28 | //} 29 | // 30 | //void testCursorSpace() { 31 | // initializeCursorSpace(); 32 | // printf("Capacity: %d\n", capacity()); 33 | // int arr[] = {1, 2, 3, 4, 5}; 34 | // for (int i = 0; i < 100; ++i) { 35 | // printf("Capacity: %d\n", capacity()); 36 | // List list1 = fromArray(arr, 5); 37 | // printf("Capacity: %d\n", capacity()); 38 | // List list2 = fromArray(arr, 5); 39 | // deleteList(list1); 40 | // deleteList(list2); 41 | // } 42 | // printf("OK!"); 43 | //} 44 | 45 | //void testLinkedStack() { 46 | // Stack S = createStack(); 47 | // 48 | // int a[] = {1, 2, 3, 4, 5}; 49 | // for (int i = 0; i < 5; ++i) { 50 | // push(a[i], S); 51 | // } 52 | // while (peek(S) != -1) { 53 | // printf("%d, ", peek(S)); 54 | // pop(S); 55 | // } 56 | // 57 | // disposeStack(S); 58 | //} 59 | 60 | //void testArrayStack() { 61 | // Stack S = createStack(20); 62 | // 63 | // int a[] = {1, 2, 3, 4, 5}; 64 | // for (int i = 0; i < 5; ++i) { 65 | // push(a[i], S); 66 | // } 67 | // while (peek(S) != -1) { 68 | // printf("%d, ", peek(S)); 69 | // pop(S); 70 | // } 71 | // 72 | // disposeStack(S); 73 | //} 74 | 75 | //void testArrayQueue() { 76 | // Queue Q = createQueue(5); 77 | // 78 | // for (int i = 0; i < 5; ++i) { 79 | // enqueue(i, Q); 80 | // } 81 | // 82 | // for (int i = 0; i < 6; ++i) { 83 | // printf("%d, ", frontAndDequeue(Q)); 84 | // } 85 | // 86 | // disposeQueue(Q); 87 | //} 88 | 89 | //void testLinkedList() { 90 | // int arr[] = {1, 2, 3, 4 ,5}; 91 | // List list = fromArray(arr, 5); 92 | // printList(list); 93 | // 94 | // Position P = find(3, list); 95 | // insert(0, list, P); 96 | // printList(list); 97 | // 98 | // delete(1, list); 99 | // printList(list); 100 | // 101 | // delete(-1, list); 102 | // printList(list); 103 | // 104 | // deleteList(list); 105 | //} 106 | 107 | int main(void) { 108 | // testCursor(); 109 | // testCursorSpace(); 110 | // testLinkedStack(); 111 | // testArrayStack(); 112 | // testArrayQueue(); 113 | } -------------------------------------------------------------------------------- /chapter4/searchtree.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by aaron on 16-11-3. 3 | // 4 | 5 | #include 6 | #include 7 | #include 8 | #include "searchtree.h" 9 | 10 | struct TreeNode { 11 | ElementType element; 12 | SearchTree left; 13 | SearchTree right; 14 | }; 15 | 16 | SearchTree makeEmpty(SearchTree T) { 17 | if (T != NULL) { 18 | makeEmpty(T->left); 19 | makeEmpty(T->right); 20 | free(T); 21 | } 22 | return NULL; 23 | } 24 | 25 | Position find(ElementType X, SearchTree T) { 26 | if (T == NULL) { 27 | return NULL; 28 | } else { 29 | if (T->element == X) { 30 | return T; 31 | } else if (T->element > X) { 32 | return find(X, T->left); 33 | } else { 34 | return find(X, T->right); 35 | } 36 | } 37 | } 38 | 39 | Position findMax(SearchTree T) { 40 | if (T != NULL) { 41 | while (T->right != NULL) { 42 | T = T->right; 43 | } 44 | } 45 | return T; 46 | } 47 | 48 | Position findMin(SearchTree T) { 49 | if (T != NULL) { 50 | return findMin(T->left); 51 | } 52 | return T; 53 | } 54 | 55 | SearchTree insert(ElementType X, SearchTree T) { 56 | if (T == NULL) { 57 | T = malloc(sizeof(struct TreeNode)); 58 | T->element = X; 59 | T->left = T->right = NULL; 60 | } else if (X > T->element) { 61 | T->right = insert(X, T->right); 62 | } else if (X < T->element) { 63 | T->left = insert(X, T->left); 64 | } 65 | return T; 66 | } 67 | 68 | SearchTree delete(ElementType X, SearchTree T) { 69 | Position tmp; 70 | if (T == NULL) { 71 | fprintf(stderr, "can't find element\n"); 72 | } else if (X > T->element) { 73 | T->right = delete(X, T->right); 74 | } else if (X < T->element) { 75 | T->left = delete(X, T->left); 76 | } else if (T->left && T->right) { 77 | tmp = findMin(T->right); 78 | T->element = tmp->element; 79 | T->right = delete(T->element, T->right); 80 | } else { 81 | tmp = T; 82 | if (T->left == NULL) { 83 | T = T->right; 84 | } else if (T->right == NULL) { 85 | T = T->left; 86 | } 87 | free(tmp); 88 | } 89 | return T; 90 | } 91 | 92 | void preorderTraversal(SearchTree T) { 93 | if (T != NULL) { 94 | printf("%2d, ", T->element); 95 | preorderTraversal(T->left); 96 | preorderTraversal(T->right); 97 | } 98 | } 99 | 100 | void inorderTraversal(SearchTree T) { 101 | if (T != NULL) { 102 | inorderTraversal(T->left); 103 | printf("%2d, ", T->element); 104 | inorderTraversal(T->right); 105 | } 106 | } 107 | 108 | void postorderTraversal(SearchTree T) { 109 | if (T != NULL) { 110 | postorderTraversal(T->left); 111 | postorderTraversal(T->right); 112 | printf("%2d, ", T->element); 113 | } 114 | } -------------------------------------------------------------------------------- /chapter3/cursor.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by aaron on 10/19/16. 3 | // 4 | 5 | #include 6 | #include "cursor.h" 7 | 8 | struct Node { 9 | ElementType element; 10 | Position next; 11 | }; 12 | 13 | struct Node CursorSpace[SPACE_SIZE]; 14 | 15 | void initializeCursorSpace(void) { 16 | for (int i = 0; i < SPACE_SIZE-1; ++i) { 17 | CursorSpace[i].next = i+1; 18 | } 19 | CursorSpace[SPACE_SIZE-1].next = 0; 20 | } 21 | 22 | static Position cursorAlloc(void) { 23 | Position P = CursorSpace[0].next; 24 | CursorSpace[0].next = CursorSpace[P].next; 25 | return P; 26 | } 27 | 28 | static void cursorFree(Position P) { 29 | CursorSpace[P].next = CursorSpace[0].next; 30 | CursorSpace[0].next = P; 31 | } 32 | 33 | int capacity(void) { 34 | int n = 0; 35 | Position P = CursorSpace[0].next; 36 | while (P != 0) { 37 | n++; 38 | P = CursorSpace[P].next; 39 | } 40 | return n; 41 | } 42 | 43 | bool isEmpty(const List L) { 44 | return CursorSpace[L].next == 0 ? true : false; 45 | } 46 | 47 | bool isLast(const Position P, const List L) { 48 | return CursorSpace[P].next == 0 ? true : false; 49 | } 50 | 51 | Position find(ElementType X, List L) { 52 | Position P = CursorSpace[L].next; 53 | while (P != 0 && CursorSpace[P].element != X) { 54 | P = CursorSpace[P].next; 55 | } 56 | return P; 57 | } 58 | 59 | Position findPrevious(ElementType X, List L) { 60 | Position P = L; 61 | while (CursorSpace[P].next != 0 && CursorSpace[CursorSpace[P].next].element != X) { 62 | P = CursorSpace[P].next; 63 | } 64 | return P; 65 | } 66 | 67 | void delete(ElementType X, List L) { 68 | Position P = findPrevious(X, L); 69 | if (!isLast(P, L)) { 70 | Position tmp = CursorSpace[P].next; 71 | CursorSpace[P].next = CursorSpace[tmp].next; 72 | cursorFree(tmp); 73 | } 74 | } 75 | 76 | void insert(ElementType X, List L, Position P) { 77 | Position tmp = cursorAlloc(); 78 | if (tmp == 0) { 79 | fprintf(stderr, "insert(): Out of space!\n"); 80 | return; 81 | } 82 | 83 | CursorSpace[tmp].element = X; 84 | CursorSpace[tmp].next = CursorSpace[P].next; 85 | CursorSpace[P].next = tmp; 86 | } 87 | 88 | void printList(List L) { 89 | if (isEmpty(L)) return; 90 | Position P = CursorSpace[L].next; 91 | while (P != 0 && CursorSpace[P].next != 0) { 92 | printf("%d->", CursorSpace[P].element); 93 | P = CursorSpace[P].next; 94 | } 95 | if (P != 0 && CursorSpace[P].next == 0) { 96 | printf("%d\n", CursorSpace[P].element); 97 | } 98 | } 99 | 100 | List fromArray(ElementType* A, size_t N) { 101 | List L = cursorAlloc(); 102 | Position P = L; 103 | for (int i = 0; i < N; ++i) { 104 | insert(A[i], L, P); 105 | P = CursorSpace[P].next; 106 | } 107 | CursorSpace[P].next = 0; 108 | return L; 109 | } 110 | 111 | List makeEmpty(List L) { 112 | if (isEmpty(L)) return L; 113 | Position P = CursorSpace[L].next; 114 | Position tmp; 115 | while (P != 0) { 116 | tmp = P; 117 | P = CursorSpace[P].next; 118 | cursorFree(tmp); 119 | } 120 | return L; 121 | } 122 | 123 | void deleteList(List L) { 124 | List head = makeEmpty(L); 125 | cursorFree(head); 126 | } -------------------------------------------------------------------------------- /chapter4/avltree.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by aaron on 16-11-3. 3 | // 4 | 5 | #include 6 | #include 7 | #include 8 | #include "avltree.h" 9 | 10 | struct AvlNode { 11 | ElementType element; 12 | AvlTree left; 13 | AvlTree right; 14 | int height; 15 | }; 16 | 17 | static int height(Position P) { 18 | if (P == NULL) { 19 | return -1; 20 | } 21 | return P->height; 22 | } 23 | 24 | static int max(int a, int b) { 25 | return a > b ? a : b; 26 | } 27 | 28 | static Position singleRotateWithLeft(Position k2) { 29 | Position k1; 30 | k1 = k2->left; 31 | k2->left = k1->right; 32 | k1->right = k2; 33 | 34 | k2->height = max(height(k2->left), height(k2->right)) + 1; 35 | k1->height = max(height(k1->left), height(k2)) + 1; 36 | 37 | return k1; 38 | } 39 | 40 | static Position singleRotateWithRight(Position k2) { 41 | Position k1; 42 | k1 = k2->right; 43 | k2->right = k1->left; 44 | k1->left = k2; 45 | 46 | k2->height = max(height(k2->left), height(k2->right)) + 1; 47 | k1->height = max(height(k1->right), height(k2)) + 1; 48 | 49 | return k1; 50 | } 51 | 52 | static Position doubleRotateWithLeft(Position k3) { 53 | k3->left = singleRotateWithRight(k3->left); 54 | return singleRotateWithLeft(k3); 55 | } 56 | 57 | static Position doubleRotateWithRight(Position k3) { 58 | k3->right = singleRotateWithLeft(k3->right); 59 | return singleRotateWithRight(k3); 60 | } 61 | 62 | AvlTree insert(ElementType X, AvlTree T) { 63 | if (T == NULL) { 64 | T = malloc(sizeof(struct AvlNode)); 65 | T->element = X; 66 | T->height = 0; 67 | T->left = T->right = NULL; 68 | } else if (X < T->element) { 69 | T->left = insert(X, T->left); 70 | if (height(T->left) - height(T->right) == 2) { 71 | if (X < T->left->element) { 72 | T = singleRotateWithLeft(T); 73 | } else { 74 | T = doubleRotateWithLeft(T); 75 | } 76 | } 77 | } else if (X > T->element) { 78 | T->right = insert(X, T->right); 79 | if (height(T->right) - height(T->left) == 2) { 80 | if (X > T->right->element) { 81 | T = singleRotateWithRight(T); 82 | } else { 83 | T = doubleRotateWithRight(T); 84 | } 85 | } 86 | } 87 | 88 | T->height = max(height(T->left), height(T->right)) + 1; 89 | return T; 90 | } 91 | 92 | AvlTree makeEmpty(AvlTree T) { 93 | if (T != NULL) { 94 | makeEmpty(T->left); 95 | makeEmpty(T->right); 96 | free(T); 97 | } 98 | return NULL; 99 | } 100 | 101 | Position find(ElementType X, AvlTree T) { 102 | if (T == NULL) return NULL; 103 | if (T->element == X) { 104 | return T; 105 | } else if (T->element > X) { 106 | return find(X, T->left); 107 | } else { 108 | return find(X, T->right); 109 | } 110 | } 111 | 112 | Position findMin(AvlTree T) { 113 | if (T == NULL) return NULL; 114 | else if (T->left == NULL) return T; 115 | else return findMin(T->left); 116 | 117 | } 118 | Position findMax(AvlTree T) { 119 | if (T != NULL) { 120 | while (T->right != NULL) { 121 | T = T->right; 122 | } 123 | } 124 | return T; 125 | } 126 | 127 | ElementType retrive(Position P) { 128 | return P->element; 129 | } 130 | 131 | void preorderTraversal(AvlTree T) { 132 | if (T != NULL) { 133 | printf("%2d, ", T->element); 134 | preorderTraversal(T->left); 135 | preorderTraversal(T->right); 136 | } 137 | } 138 | 139 | void inorderTraversal(AvlTree T) { 140 | if (T != NULL) { 141 | inorderTraversal(T->left); 142 | printf("%2d, ", T->element); 143 | inorderTraversal(T->right); 144 | } 145 | } 146 | 147 | void postorderTraversal(AvlTree T) { 148 | if (T != NULL) { 149 | postorderTraversal(T->left); 150 | postorderTraversal(T->right); 151 | printf("%2d, ", T->element); 152 | } 153 | } 154 | -------------------------------------------------------------------------------- /chapter2/main.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 董启宏 on 2016/10/12. 3 | // 4 | // 算法的威力!真的是厉害了! 5 | 6 | #include 7 | #include 8 | #include 9 | #include "MaxSubsequenceSum.h" 10 | #include "util.h" 11 | #include "fib.h" 12 | #include "binary_search.h" 13 | #include "gcd.h" 14 | #include "pow.h" 15 | #include "permutation.h" 16 | #include "horner.h" 17 | #include "prime.h" 18 | 19 | void testMaxSubsequence() { 20 | printTestHeader("Test MaxSubsequence"); 21 | const int N = 1000; 22 | int* A = getSequence(N); 23 | 24 | 25 | printf("O(N^3): %d\n", MaxSubsequenceSum_ON3(A, N)); 26 | printf("O(N^2): %d\n", MaxSubsequenceSum_ON2(A, N)); 27 | printf("O(NLogN): %d\n", MaxSubsequenceSum_ONLogN(A, N)); 28 | printf("O(N): %d\n", MaxSubsequenceSum_ON(A, N)); 29 | 30 | free(A); 31 | } 32 | 33 | void testFib() { 34 | printTestHeader("Test Fib"); 35 | 36 | const int N = 20; 37 | for (int i = 0; i < N; ++i) { 38 | printf("Fib(%d) = %ld\n", i, fib(i)); 39 | } 40 | } 41 | 42 | void testBinarySearch() { 43 | printTestHeader("Test BinarySearch"); 44 | 45 | const int N = 20; 46 | int* A = getLinearSequence(N); 47 | 48 | int n = rand() % N; 49 | printArray(A, N); 50 | printf("Find A[%d] = %d in A\n", n, A[n]); 51 | printf("BinarySearch(%d) = %d\n", A[n], BinarySearch(A, N, A[n])); 52 | 53 | free(A); 54 | } 55 | 56 | void testBinarySearchAi() { 57 | printTestHeader("Test BinarySearchAi"); 58 | 59 | const int N = 7; 60 | int A[] = {1, 2, 3, 4, 5, 6, 7}; 61 | 62 | printArray(A, N); 63 | printf("BinarySearchAi: %d\n", BinarySearchAi(A, N)); 64 | 65 | } 66 | 67 | void testGCD() { 68 | printTestHeader("Test GCD"); 69 | 70 | const unsigned M = (unsigned) rand(); 71 | const unsigned N = (unsigned) rand(); 72 | printf("GCD(%u, %u) = %u\n", M, N, gcd(M, N)); 73 | } 74 | 75 | void testPow() { 76 | printTestHeader("Test Pow"); 77 | long X = 2; 78 | unsigned long N = 11; 79 | // Pow(2, 4); 80 | for (unsigned long i = 0; i < N; i++) { 81 | printf("Pow(%ld, %lu) = %lu\n", X, i, Pow(X, i)); 82 | printf("PowRecursion(%ld, %lu) = %lu\n", X, i, PowRecursion(X, i)); 83 | if (Pow(X, i) != PowRecursion(X, i)) { 84 | printf("Break! Pow"); 85 | } 86 | } 87 | } 88 | 89 | void testGetRand() { 90 | printTestHeader("Test randInt"); 91 | 92 | int N = 10; 93 | for (int i = 0; i < N; ++i) { 94 | printf("randInt(1, %d) = %d\n", N, randInt(1, N)); 95 | } 96 | } 97 | 98 | void testSwap(int a, int b) { 99 | printTestHeader("Test Swap"); 100 | 101 | printf("a = %d, b = %d\n", a, b); 102 | swap(&a, &b); 103 | printf("a = %d, b = %d\n", a, b); 104 | } 105 | 106 | void testPermutation() { 107 | printTestHeader("Test getPermutation"); 108 | 109 | const int N = 12000; 110 | printf("getPermutation(%d):\n", N); 111 | 112 | // int *A = getPermutation_ON2LogN(N); 113 | // int *A = getPermutation_ONLogN(N); 114 | int *A = getPermutation_ON(N); 115 | printArray(A, N); 116 | 117 | printf("Testing...\n"); 118 | for (int i = 0; i < N; ++i) { 119 | if (! isContain(A, i+1, N)) { 120 | printf("Break! %d is missing\n", i+1); 121 | } 122 | } 123 | printf("OK!\n"); 124 | 125 | free(A); 126 | } 127 | 128 | void testPolynomial() { 129 | printTestHeader("Test Polynomial"); 130 | 131 | double X = 3; 132 | double A[] = {2, 1, 0, 8, 4}; 133 | int N = 5; 134 | printf("polynomial(A, N=%d, X=%f) = %f\n", N, X, polynomial(A, N, X)); 135 | } 136 | 137 | void testPrime() { 138 | printTestHeader("Test isPrime()"); 139 | 140 | srand((unsigned int) time(0)); 141 | // long N = rand(); 142 | long N = 37; 143 | printf("isPrime(%ld) = %d\n", N, isPrime(N)); 144 | } 145 | 146 | void testMSB() { 147 | printTestHeader("Test MostSignifictBit()"); 148 | unsigned long N = 0xAA; 149 | printf("msb(0x%x) = %d\n", N, msb(N)); 150 | } 151 | 152 | int main(void) { 153 | // testMaxSubsequence(); 154 | // testBinarySearch(); 155 | // testFib(); 156 | // testGCD(); 157 | testPow(); 158 | // testGetRand(); 159 | // testSwap(5, -1); 160 | // testPermutation(); 161 | // testPolynomial(); 162 | // testBinarySearchAi(); 163 | // testPrime(); 164 | // testMSB(); 165 | } 166 | 167 | -------------------------------------------------------------------------------- /chapter3/linkedlist.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by aaron on 10/19/16. 3 | // 4 | 5 | #include 6 | #include 7 | #include 8 | #include "linkedlist.h" 9 | 10 | bool isLast(Position P, List L) { 11 | return P->next == NULL ? true : false; 12 | } 13 | 14 | bool isEmpty(List L) { 15 | return L->next == NULL ? true : false; 16 | } 17 | 18 | void makeEmpty(List L) { 19 | Position P = L->next; 20 | Position tmp; 21 | L->next = NULL; 22 | while (P != NULL) { 23 | tmp = P->next; 24 | free(P); 25 | P = tmp; 26 | } 27 | } 28 | 29 | void deleteList(List L) { 30 | makeEmpty(L); 31 | free(L); 32 | } 33 | 34 | /* 35 | * 如果找不到X,则返回NULL 36 | */ 37 | Position find(ElementType X, List L) { 38 | Position P = L->next; 39 | while (P != NULL && P->element != X) { 40 | P = P->next; 41 | } 42 | return P; 43 | } 44 | 45 | /* 46 | * 寻找X的前一个元素,如果找不到,则返回最后一个元素 47 | */ 48 | Position findPrevious(ElementType X, List L) { 49 | Position P = L; 50 | while (P->next != NULL && P->next->element != X) { 51 | P = P->next; 52 | } 53 | return P; 54 | } 55 | 56 | void insert(ElementType X, List L, Position P) { 57 | Position tmpCell = malloc(sizeof(struct Node)); 58 | if (tmpCell == NULL) { 59 | perror("insert()"); 60 | return; 61 | } 62 | tmpCell->element = X; 63 | tmpCell->next = P->next; 64 | P->next = tmpCell; 65 | } 66 | 67 | void delete(ElementType X, List L) { 68 | Position P = findPrevious(X, L); 69 | Position tmpCell; 70 | if (!isLast(P, L)) { 71 | tmpCell = P->next; 72 | P->next = tmpCell->next; 73 | free(tmpCell); 74 | } 75 | } 76 | 77 | void printList(List L) { 78 | if (isEmpty(L)) return; 79 | Position P = L->next; 80 | while (P != NULL && P->next != NULL) { 81 | printf("%d -> ", P->element); 82 | P = P->next; 83 | } 84 | if (P != NULL && P->next == NULL) { 85 | printf("%d\n", P->element); 86 | } 87 | } 88 | 89 | List fromArray(ElementType* A, size_t N) { 90 | List L = malloc(sizeof(struct Node)); 91 | Position P = L; 92 | for (int i = 0; i < N; ++i) { 93 | insert(A[i], L, P); 94 | P = P->next; 95 | } 96 | return L; 97 | } 98 | 99 | Position header(List L) { 100 | return L; 101 | } 102 | 103 | Position first(List L) { 104 | return L->next; 105 | } 106 | 107 | Position advance(Position P) { 108 | return P->next; 109 | } 110 | 111 | List intersect(List L1, List L2) { 112 | List L = malloc(sizeof(struct Node)); 113 | Position P = L; 114 | 115 | Position l1 = L1->next; 116 | Position l2 = L2->next; 117 | while (l1 != NULL && l2 != NULL) { 118 | if (l1->element == l2->element) { 119 | insert(l1->element, L, P); 120 | P = advance(P); 121 | l1 = advance(l1); 122 | l2 = advance(l2); 123 | } else if (l1->element < l2->element) { 124 | l1 = advance(l1); 125 | } else { 126 | l2 = advance(l2); 127 | } 128 | } 129 | return L; 130 | } 131 | 132 | List Union(List L1, List L2) { 133 | List result = malloc(sizeof(struct Node)); 134 | Position resultPos = result; 135 | 136 | Position l1 = first(L1); 137 | Position l2 = first(L2); 138 | while (l1 != NULL && l2 != NULL) { 139 | if (l1->element < l2->element) { 140 | insert(l1->element, result, resultPos); 141 | resultPos = advance(resultPos); 142 | 143 | l1 = advance(l1); 144 | } else if (l2->element < l1->element) { 145 | insert(l2->element, result, resultPos); 146 | resultPos = advance(resultPos); 147 | l2 = advance(l2); 148 | } else { 149 | insert(l1->element, result, resultPos); 150 | resultPos = advance(resultPos); 151 | l1 = advance(l1); 152 | l2 = advance(l2); 153 | } 154 | } 155 | 156 | while (l1 != NULL) { 157 | insert(l1->element, result, resultPos); 158 | resultPos = advance(result); 159 | l1 = advance(l1); 160 | } 161 | 162 | while (l2 != NULL) { 163 | insert(l2->element, result, resultPos); 164 | resultPos = advance(resultPos); 165 | l2 = advance(l2); 166 | } 167 | 168 | return result; 169 | } 170 | 171 | List reverseList(List L) { 172 | Position prev, curr, next; 173 | prev = NULL; 174 | curr = L; 175 | next = L->next; 176 | while (next != NULL) { 177 | curr->next = prev; 178 | prev = curr; 179 | curr = next; 180 | next = next->next; 181 | } 182 | curr->next = prev; 183 | return curr; 184 | } -------------------------------------------------------------------------------- /chapter7/sort.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by aaron on 16-11-14. 3 | // 4 | 5 | #include 6 | #include "sort.h" 7 | 8 | void InsertionSort(ElementType A[], size_t N) { 9 | for (int P = 1; P < N; ++P) { 10 | ElementType tmp = A[P]; 11 | int i = P; 12 | while(i > 0 && A[i-1] > tmp) { 13 | A[i] = A[i-1]; 14 | i--; 15 | } 16 | A[i] = tmp; 17 | } 18 | } 19 | 20 | void ShellSort(ElementType A[], size_t N) { 21 | int i, j, inc; 22 | ElementType tmp; 23 | for (inc = N / 2; inc > 0; inc /= 2) { 24 | for (i = inc; i < N; ++i) { 25 | tmp = A[i]; 26 | for (j = i; j >= inc; j -= inc) { 27 | if (A[j-inc] > tmp) { 28 | A[j] = A[j-inc]; 29 | } else { 30 | break; 31 | } 32 | } 33 | A[j] = tmp; 34 | } 35 | } 36 | } 37 | 38 | void BubbleSort(ElementType A[], size_t N) { 39 | for (int i = 0; i < N - 1; ++i) { 40 | for (int j = 0; j < N - i - 1; ++j) { 41 | if (A[j] > A[j+1]) { 42 | swap(&A[j], &A[j+1]); 43 | } 44 | } 45 | } 46 | } 47 | 48 | void SelectionSort(ElementType A[], size_t N) { 49 | for (int i = 0; i < N - 1; ++i) { 50 | int min = i; 51 | for (int j = i + 1; j < N; ++j) { 52 | if (A[min] > A[j]) { 53 | min = j; 54 | } 55 | } 56 | if (min != i) { 57 | swap(&A[i], &A[min]); 58 | } 59 | } 60 | } 61 | 62 | void swap(ElementType* a, ElementType *b) { 63 | ElementType tmp = *a; 64 | *a = *b; 65 | *b = tmp; 66 | } 67 | 68 | #define LeftChild(i) (2*(i) + 1) 69 | 70 | static void PercDown(ElementType A[], int i, size_t N) { 71 | int child; 72 | ElementType tmp; 73 | for (tmp = A[i]; LeftChild(i) < N; i = child) { 74 | child = LeftChild(i); 75 | if (child != N-1 && A[child+1] > A[child]) { 76 | child++; 77 | } 78 | if (tmp < A[child]) { 79 | A[i] = A[child]; 80 | } else { 81 | break; 82 | } 83 | } 84 | A[i] = tmp; 85 | } 86 | 87 | void HeapSort(ElementType A[], size_t N) { 88 | int i; 89 | 90 | for (i = N / 2; i >= 0; i--) { 91 | PercDown(A, i, N); 92 | } 93 | for (i = N-1; i > 0; i--) { 94 | swap(&A[0], &A[i]); 95 | PercDown(A, 0, i); 96 | } 97 | } 98 | 99 | static void Merge(ElementType A[], ElementType TmpArray[], int lpos, int rpos, int rightEnd) { 100 | int leftEnd, numElements, tmpPos; 101 | 102 | leftEnd = rpos - 1; 103 | tmpPos = lpos; 104 | numElements = rightEnd - lpos + 1; 105 | 106 | while (lpos <= leftEnd && rpos <= rightEnd) { 107 | if (A[lpos] <= A[rpos]) { 108 | TmpArray[tmpPos++] = A[lpos++]; 109 | } else { 110 | TmpArray[tmpPos++] = A[rpos++]; 111 | } 112 | } 113 | 114 | while (lpos <= leftEnd) { 115 | TmpArray[tmpPos++] = A[lpos++]; 116 | } 117 | 118 | while (rpos <= rightEnd) { 119 | TmpArray[tmpPos++] = A[rpos++]; 120 | } 121 | 122 | for (int i = 0; i < numElements; ++i, rightEnd--) { 123 | A[rightEnd] = TmpArray[rightEnd]; 124 | } 125 | } 126 | 127 | static void MSort(ElementType A[], ElementType TmpArray[], int left, int right) { 128 | int center; 129 | if (left < right) { 130 | center = (left + right) / 2; 131 | MSort(A, TmpArray, left, center); 132 | MSort(A, TmpArray, center+1, right); 133 | Merge(A, TmpArray, left, center+1, right); 134 | } 135 | } 136 | 137 | void MergeSort(ElementType A[], size_t N) { 138 | ElementType *TmpArray = malloc(N * sizeof(ElementType)); 139 | MSort(A, TmpArray, 0, N-1); 140 | free(TmpArray); 141 | } 142 | 143 | ElementType Median3(ElementType A[], int left, int right) { 144 | int center = (left + right) / 2; 145 | if (A[left] > A[center]) swap(&A[left], &A[center]); 146 | if (A[left] > A[right]) swap(&A[left], &A[right]); 147 | if (A[center] > A[right]) swap(&A[center], &A[right]); 148 | swap(&A[center], &A[right-1]); 149 | return A[right-1]; 150 | } 151 | 152 | #define Cutoff (3) 153 | 154 | static void QSort(ElementType A[], int left, int right) { 155 | ElementType pivot; 156 | 157 | if (left + Cutoff <= right) { 158 | pivot = Median3(A, left, right); 159 | int i = left; 160 | int j = right - 1; 161 | while (1) { 162 | while (A[++i] < pivot); 163 | while (A[--j] > pivot); 164 | if (i < j) { 165 | swap(&A[i], &A[j]); 166 | } else { 167 | break; 168 | } 169 | } 170 | swap(&A[i], &A[right-1]); 171 | QSort(A, left, i-1); 172 | QSort(A, i+1, right); 173 | } else { 174 | InsertionSort(A+left, right-left+1); 175 | } 176 | } 177 | 178 | void QuickSort(ElementType A[], size_t N) { 179 | QSort(A, 0, N-1); 180 | } --------------------------------------------------------------------------------