├── .gitignore ├── 第2章:栈和队列 ├── .DS_Store ├── 4、演示代码(栈&队列) │ ├── 1、Leetcode-20.cpp │ ├── 3、Leetcode-232.cpp │ └── 2、Leetcode-225.cpp ├── 5、演示代码(单调栈&单调队列) │ ├── 1、Leetcode-42.cpp │ ├── 4、Leetcode-239.cpp │ ├── 2、Leetcode-84.cpp │ └── 3、Leetcode-221.cpp ├── 2、单调队列 │ └── 1、HZOJ-270-最大子序和.cpp ├── 3、单调栈 │ └── 1、HZOJ-264-最大矩形面积.cpp └── 1、栈和队列 │ ├── 2、Stack.cpp │ └── 1、Queue.cpp ├── 第3章:树与二叉树 ├── .DS_Store ├── 5、演示代码(二) │ ├── 1、Leetcode-104.cpp │ ├── 3、Leetcode-112.cpp │ ├── 4、Leetcode-111.cpp │ └── 2、Leetcode-110.cpp ├── 4、演示代码(一) │ ├── 1、Leetcode-100.cpp │ ├── 2、Leetcode-101.cpp │ ├── 3、Leetcode-102.cpp │ └── 4、Leetcode-107.cpp ├── 6、演示代码(三) │ ├── 1、Leetcode-226.cpp │ ├── 2、Leetcode-235.cpp │ └── 3、Leetcode-257.cpp ├── 3、二叉树的线索化 │ └── 1、ThreadBinaryTree.cpp ├── 2、哈夫曼编码 │ └── 1、haffman.cpp └── 1、树与二叉树 │ └── 1、binary_tree.cpp ├── 第5章:排序与查找 ├── .DS_Store ├── 6、演示代码(二) │ ├── 2、Leetcode-35.cpp │ ├── 4、Leetcode-88.cpp │ ├── 1、Leetcode-21.cpp │ └── 3、Leetcode-38.cpp ├── 5、演示代码(一) │ ├── 4、Leetcode-2-2.cpp │ ├── 3、Leetcode-2-1.cpp │ ├── 5、Leetcode-4.cpp │ ├── 1、Leetcode-1-1.cpp │ └── 2、Leetcode-1-2.cpp ├── 7、演示代码(三) │ ├── 3、Leetcode-278.cpp │ ├── 1、Leetcode-217.cpp │ ├── 2、Leetcode-219.cpp │ └── 4、Leetcode-349.cpp ├── 8、演示代码(四) │ ├── 2、Leetcode-374.cpp │ ├── 3、Leetcode-378.cpp │ ├── 4、HZOJ-242-最大平均值.cpp │ ├── 5、HZOJ-243-秦腾与教学评估.cpp │ └── 1、Leetcode-350.cpp ├── 3、二分查找与三分查找 │ └── 1、binary_search.cpp ├── 2、非稳定排序 │ └── 1、unstable_sort.cpp ├── 4、哈希表 │ └── 1、hash_table.cpp └── 1、稳定排序 │ └── 1、stable_sort.cpp ├── 第10章:森林与并查集 ├── .DS_Store ├── 7、演示代码(四) │ ├── 2、Leetcode-547.cpp │ ├── 3、Leetcode-684.cpp │ ├── 1、Leetcode-200.cpp │ └── 4、Leetcode-685.cpp ├── 3、【竞赛版】并查集基础知识 │ └── 1、HZOJ-71-朋友圈.cpp ├── 5、演示代码(二) │ ├── 2、HZOJ-323-Supermarket.cpp │ └── 1、HZOJ-322-程序自动分析.cpp ├── 1、Quick-Find 代码演示 │ └── 1、Quick-Find.cpp ├── 4、演示代码(一) │ ├── 2、HZOJ-73-湖泊.cpp │ └── 1、HZOJ-72-猜拳.cpp ├── 6、演示代码(三) │ ├── 1、HZOJ-324-银河英雄传说.cpp │ ├── 3、Leetcode-130.cpp │ └── 2、Leetcode-128.cpp └── 2、Quick-Union 及优化代码演示 │ └── 1、Quick-Union.cpp ├── 第13章:贪心法习题课 ├── .DS_Store ├── 2、代码演示(二) │ ├── 2、HZOJ-258-最大子阵和.cpp │ └── 1、HZOJ-256-国王的游戏.cpp └── 1、代码演示(一) │ ├── 2、HZOJ-255-安装雷达.cpp │ ├── 1、HZOJ-253-奶牛晒太阳.cpp │ └── 3、HZOJ-257-树的颜色.cpp ├── 第1章:顺序表与链表 ├── .DS_Store ├── 5、习题课-演示代码(三) │ ├── 2、Leetcode-287.cpp │ ├── 4、Leetcode-268(2).cpp │ ├── 3、Leetcode-268(1).cpp │ └── 1、Leetcode-142.cpp ├── 4、习题课-演示代码(二) │ ├── 5、Leetcode-237.cpp │ ├── 1、Leetcode-202.cpp │ ├── 3、Leetcode-206.cpp │ ├── 2、Leetcode-203.cpp │ └── 4、Leetcode-234.cpp ├── 3、习题课-演示代码(一) │ ├── 5、Leetcode-160.cpp │ ├── 4、Leetcode-141.cpp │ ├── 3、Leetcode-83.cpp │ ├── 2、Leetcode-24.cpp │ └── 1、Leetcode-19.cpp ├── 1、顺序表 │ └── Vector.cpp └── 2、链表 │ └── LinkList.cpp ├── 第4章:堆与优先队列 ├── .DS_Store ├── 4、演示代码(二) │ ├── 1、HZOJ-287-合并果子(heap).cpp │ ├── 2、HZOJ-287-合并果子(set).cpp │ └── 3、HZOJ-284-超市卖货.cpp ├── 2、堆排序与线性建堆法 │ └── 1、heap_sort.cpp ├── 3、演示代码(一) │ ├── 5、Leetcode-313.cpp │ ├── 4、Leetcode-264.cpp │ ├── 1、Leetcode-703.cpp │ ├── 3、Leetcode-23.cpp │ └── 2、Leetcode-295.cpp └── 1、优先队列 │ └── 1、priority_queue.cpp ├── 第11章:树状数组与线段树 ├── .DS_Store ├── 1、树状数组结构基础 │ └── 1、HZOJ-329-弱化的整数问题.cpp ├── 2、线段树结构基础 │ ├── 1、HZOJ-222-线段树模板(一).cpp │ └── 2、HZOJ-223-线段树模板(二).cpp └── 3、HZOJ-333-最大子段和 │ └── 1、HZOJ-333-最大子段和.cpp ├── 第12章:平衡二叉查找树 ├── .DS_Store ├── 1、二叉排序树 │ └── 1、binary_search_tree.cpp └── 2、平衡二叉排序树 │ └── 1、AVL.cpp ├── 第6章:字符串匹配算法(1) ├── .DS_Store ├── 2、附录1-其余资料 │ └── 1、HZOJ-278-循环字符串.cpp └── 1、字符串代码演示 │ └── 1、字符串匹配算法.cpp ├── 第7章:字符串匹配算法(2) ├── .DS_Store ├── 3、演示代码(一) │ ├── 1、HZOJ-281-前缀统计.cpp │ └── 2、HZOJ-282-最大亦或和.cpp ├── 1、字典树 │ └── 1、Trie.cpp └── 2、双数组字典树 │ └── 1、DATrie.cpp ├── 第8章:字符串匹配算法(3) ├── .DS_Store ├── 2、AC 自动机--内容扩展 │ ├── 2、AC 自动机的线索化.cpp │ └── 1、AC 自动机的递归建立.cpp └── 1、AC 自动机 │ ├── 1、基于字典树的 AC 自动机.cpp │ └── 2、基于双数组字典树的 AC 自动机.cpp ├── README.md └── 第9章:递归函数转非递归函数 ├── 1、【程序演示】存储任意类型的栈.cpp ├── 2、【程序演示】二叉树前序遍历(非递归).cpp └── 3、【程序演示】快速排序(非递归).cpp /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | .DS_Store 3 | -------------------------------------------------------------------------------- /第2章:栈和队列/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huguangAOA/datastructure/HEAD/第2章:栈和队列/.DS_Store -------------------------------------------------------------------------------- /第3章:树与二叉树/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huguangAOA/datastructure/HEAD/第3章:树与二叉树/.DS_Store -------------------------------------------------------------------------------- /第5章:排序与查找/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huguangAOA/datastructure/HEAD/第5章:排序与查找/.DS_Store -------------------------------------------------------------------------------- /第10章:森林与并查集/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huguangAOA/datastructure/HEAD/第10章:森林与并查集/.DS_Store -------------------------------------------------------------------------------- /第13章:贪心法习题课/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huguangAOA/datastructure/HEAD/第13章:贪心法习题课/.DS_Store -------------------------------------------------------------------------------- /第1章:顺序表与链表/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huguangAOA/datastructure/HEAD/第1章:顺序表与链表/.DS_Store -------------------------------------------------------------------------------- /第4章:堆与优先队列/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huguangAOA/datastructure/HEAD/第4章:堆与优先队列/.DS_Store -------------------------------------------------------------------------------- /第11章:树状数组与线段树/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huguangAOA/datastructure/HEAD/第11章:树状数组与线段树/.DS_Store -------------------------------------------------------------------------------- /第12章:平衡二叉查找树/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huguangAOA/datastructure/HEAD/第12章:平衡二叉查找树/.DS_Store -------------------------------------------------------------------------------- /第6章:字符串匹配算法(1)/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huguangAOA/datastructure/HEAD/第6章:字符串匹配算法(1)/.DS_Store -------------------------------------------------------------------------------- /第7章:字符串匹配算法(2)/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huguangAOA/datastructure/HEAD/第7章:字符串匹配算法(2)/.DS_Store -------------------------------------------------------------------------------- /第8章:字符串匹配算法(3)/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huguangAOA/datastructure/HEAD/第8章:字符串匹配算法(3)/.DS_Store -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # B 站-数据结构与算法-系列课程代码 2 | 海贼胡船长-B站-数据结构与算法系列课程中的演示代码 3 | 4 | B 站账号:[海贼胡船长](https://space.bilibili.com/381346048) 5 | 微信公众号:海贼编程基地 6 | -------------------------------------------------------------------------------- /第5章:排序与查找/6、演示代码(二)/2、Leetcode-35.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 35.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 六 5/11 14:53:25 2019 7 | ************************************************************************/ 8 | 9 | int searchInsert(int* nums, int numsSize, int target){ 10 | int head = 0, tail = numsSize, mid; 11 | while (head < tail) { 12 | mid = (head + tail) >> 1; 13 | if (nums[mid] >= target) tail = mid; 14 | else head = mid + 1; 15 | } 16 | return head; 17 | } -------------------------------------------------------------------------------- /第1章:顺序表与链表/5、习题课-演示代码(三)/2、Leetcode-287.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 287.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 一 7/15 15:58:54 2019 7 | ************************************************************************/ 8 | 9 | int findDuplicate(int* nums, int numsSize){ 10 | int p = nums[0], q = nums[0]; 11 | do { 12 | p = nums[p]; 13 | q = nums[nums[q]]; 14 | } while (p != q); 15 | q = nums[0]; 16 | while (p != q) { 17 | p = nums[p]; 18 | q = nums[q]; 19 | } 20 | return p; 21 | } -------------------------------------------------------------------------------- /第5章:排序与查找/5、演示代码(一)/4、Leetcode-2-2.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 2-2.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 四 5/ 9 20:46:07 2019 7 | ************************************************************************/ 8 | 9 | int lengthOfLongestSubstring(char* s) { 10 | int ind[128], l = 0, ans = 0; 11 | memset(ind, -1, sizeof(ind)); 12 | for (int i = 0; s[i]; i++) { 13 | l += 1; 14 | if (i - ind[s[i]] < l) l = i - ind[s[i]]; 15 | ind[s[i]] = i; 16 | if (l > ans) ans = l; 17 | } 18 | return ans; 19 | } -------------------------------------------------------------------------------- /第1章:顺序表与链表/4、习题课-演示代码(二)/5、Leetcode-237.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 237.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 一 7/15 19:11:25 2019 7 | ************************************************************************/ 8 | 9 | /** 10 | * Definition for singly-linked list. 11 | * struct ListNode { 12 | * int val; 13 | * struct ListNode *next; 14 | * }; 15 | */ 16 | void deleteNode(struct ListNode* node) { 17 | struct ListNode *p = node->next; 18 | node->val = p->val; 19 | node->next = p->next; 20 | free(p); 21 | return ; 22 | } -------------------------------------------------------------------------------- /第5章:排序与查找/7、演示代码(三)/3、Leetcode-278.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 278.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 六 5/11 16:18:01 2019 7 | ************************************************************************/ 8 | 9 | // Forward declaration of isBadVersion API. 10 | bool isBadVersion(int version); 11 | 12 | int firstBadVersion(int n) { 13 | int head = 1, tail = n, mid; 14 | while (head < tail) { 15 | mid = head + ((tail - head) >> 1); 16 | if (isBadVersion(mid)) tail = mid; 17 | else head = mid + 1; 18 | } 19 | return head; 20 | } -------------------------------------------------------------------------------- /第5章:排序与查找/6、演示代码(二)/4、Leetcode-88.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 88.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 六 5/11 15:14:22 2019 7 | ************************************************************************/ 8 | 9 | void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n){ 10 | int p = m, q = n, t = m + n; 11 | while (p || q) { 12 | if (q == 0 || (p && nums1[p - 1] >= nums2[q - 1])) { 13 | nums1[--t] = nums1[--p]; 14 | } else { 15 | nums1[--t] = nums2[--q]; 16 | } 17 | } 18 | return ; 19 | } -------------------------------------------------------------------------------- /第3章:树与二叉树/5、演示代码(二)/1、Leetcode-104.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 104.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 四 4/25 20:08:25 2019 7 | ************************************************************************/ 8 | 9 | /** 10 | * Definition for a binary tree node. 11 | * struct TreeNode { 12 | * int val; 13 | * struct TreeNode *left; 14 | * struct TreeNode *right; 15 | * }; 16 | */ 17 | int maxDepth(struct TreeNode* root) { 18 | if (root == NULL) return 0; 19 | int d1 = maxDepth(root->left); 20 | int d2 = maxDepth(root->right); 21 | return fmax(d1, d2) + 1; 22 | } -------------------------------------------------------------------------------- /第1章:顺序表与链表/4、习题课-演示代码(二)/1、Leetcode-202.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 202.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 一 7/15 18:24:59 2019 7 | ************************************************************************/ 8 | 9 | int get_next(int x) { 10 | int temp = 0; 11 | while (x) { 12 | temp += (x % 10) * (x % 10); 13 | x /= 10; 14 | } 15 | return temp; 16 | } 17 | 18 | bool isHappy(int n) { 19 | int p = n, q = n; 20 | while (q != 1) { 21 | p = get_next(p); 22 | q = get_next(get_next(q)); 23 | if (p == q) break; 24 | } 25 | return (q == 1); 26 | } -------------------------------------------------------------------------------- /第1章:顺序表与链表/5、习题课-演示代码(三)/4、Leetcode-268(2).cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 268-2.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 一 7/15 16:45:45 2019 7 | ************************************************************************/ 8 | 9 | int missingNumber(int* nums, int numsSize){ 10 | for (int i = 0; i < numsSize; i++) { 11 | while (nums[i] != i && nums[i] != numsSize) { 12 | int a = nums[i], b = nums[nums[i]]; 13 | nums[a] = a, nums[i] = b; 14 | } 15 | } 16 | for (int i = 0; i < numsSize; i++) { 17 | if (nums[i] - i) return i; 18 | } 19 | return numsSize; 20 | } -------------------------------------------------------------------------------- /第1章:顺序表与链表/3、习题课-演示代码(一)/5、Leetcode-160.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 160.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 一 7/15 16:57:43 2019 7 | ************************************************************************/ 8 | /** 9 | * Definition for singly-linked list. 10 | * struct ListNode { 11 | * int val; 12 | * struct ListNode *next; 13 | * }; 14 | */ 15 | struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) { 16 | struct ListNode *p = headA, *q = headB; 17 | while (p != q) { 18 | p = p ? p->next : headB; 19 | q = q ? q->next : headA; 20 | } 21 | return p; 22 | } -------------------------------------------------------------------------------- /第1章:顺序表与链表/4、习题课-演示代码(二)/3、Leetcode-206.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 206.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 一 7/15 18:49:51 2019 7 | ************************************************************************/ 8 | 9 | /** 10 | * Definition for singly-linked list. 11 | * struct ListNode { 12 | * int val; 13 | * struct ListNode *next; 14 | * }; 15 | */ 16 | struct ListNode* reverseList(struct ListNode* head) { 17 | struct ListNode ret, *p = head, *q; 18 | ret.next = NULL; 19 | while (p) { 20 | q = p->next; 21 | p->next = ret.next; 22 | ret.next = p; 23 | p = q; 24 | } 25 | return ret.next; 26 | } -------------------------------------------------------------------------------- /第1章:顺序表与链表/5、习题课-演示代码(三)/3、Leetcode-268(1).cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 268.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 一 7/15 16:27:08 2019 7 | ************************************************************************/ 8 | 9 | int missingNumber(int* nums, int numsSize){ 10 | int ans = 0, n = numsSize + 1; 11 | for (int i = 0, j = 2; ; i += 1, j *= 2) { 12 | int cnt = n / j * (j >> 1); 13 | if (n % j > (j >> 1)) { 14 | cnt += n % j - (j >> 1); 15 | } 16 | if (cnt % 2) ans |= (1 << i); 17 | if (j >= n) break; 18 | } 19 | for (int i = 0; i < numsSize; i++) ans ^= nums[i]; 20 | return ans; 21 | } -------------------------------------------------------------------------------- /第3章:树与二叉树/5、演示代码(二)/3、Leetcode-112.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 112.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 四 4/25 20:19:13 2019 7 | ************************************************************************/ 8 | 9 | /** 10 | * Definition for a binary tree node. 11 | * struct TreeNode { 12 | * int val; 13 | * struct TreeNode *left; 14 | * struct TreeNode *right; 15 | * }; 16 | */ 17 | bool hasPathSum(struct TreeNode* root, int sum) { 18 | if (root == NULL) return false; 19 | if (root->left == 0 && root->right == NULL) return root->val == sum; 20 | return hasPathSum(root->left, sum - root->val) || hasPathSum(root->right, sum - root->val); 21 | } -------------------------------------------------------------------------------- /第3章:树与二叉树/4、演示代码(一)/1、Leetcode-100.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 100.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 四 4/25 18:19:03 2019 7 | ************************************************************************/ 8 | 9 | /** 10 | * Definition for a binary tree node. 11 | * struct TreeNode { 12 | * int val; 13 | * struct TreeNode *left; 14 | * struct TreeNode *right; 15 | * }; 16 | */ 17 | bool isSameTree(struct TreeNode* p, struct TreeNode* q) { 18 | if (p == NULL && q == NULL) return true; 19 | if (p == NULL || q == NULL) return false; 20 | if (p->val - q->val) return false; 21 | return isSameTree(p->left, q->left) && isSameTree(p->right, q->right); 22 | } -------------------------------------------------------------------------------- /第3章:树与二叉树/6、演示代码(三)/1、Leetcode-226.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 226.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 四 4/25 20:25:59 2019 7 | ************************************************************************/ 8 | 9 | /** 10 | * Definition for a binary tree node. 11 | * struct TreeNode { 12 | * int val; 13 | * struct TreeNode *left; 14 | * struct TreeNode *right; 15 | * }; 16 | */ 17 | struct TreeNode* invertTree(struct TreeNode* root) { 18 | if (root == NULL) return NULL; 19 | struct TreeNode *temp = root->left; 20 | root->left = root->right; 21 | root->right = temp; 22 | invertTree(root->left), invertTree(root->right); 23 | return root; 24 | } -------------------------------------------------------------------------------- /第1章:顺序表与链表/3、习题课-演示代码(一)/4、Leetcode-141.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 141.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 四 4/11 18:58:05 2019 7 | ************************************************************************/ 8 | 9 | /** 10 | * Definition for singly-linked list. 11 | * struct ListNode { 12 | * int val; 13 | * struct ListNode *next; 14 | * }; 15 | */ 16 | bool hasCycle(struct ListNode *head) { 17 | struct ListNode *p = head, *q = head; 18 | if (p == NULL) return false; 19 | do { 20 | p = p->next; 21 | q = q->next; 22 | if (q == NULL || q->next == NULL) return false; 23 | q = q->next; 24 | } while (p != q); 25 | return true; 26 | } -------------------------------------------------------------------------------- /第1章:顺序表与链表/3、习题课-演示代码(一)/3、Leetcode-83.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 83.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 四 4/11 18:58:05 2019 7 | ************************************************************************/ 8 | 9 | /** 10 | * Definition for singly-linked list. 11 | * struct ListNode { 12 | * int val; 13 | * struct ListNode *next; 14 | * }; 15 | */ 16 | struct ListNode* deleteDuplicates(struct ListNode* head) { 17 | struct ListNode *p = head, *q; 18 | while (p && p->next) { 19 | if (p->val - p->next->val) { 20 | p = p->next; 21 | } else { 22 | q = p->next; 23 | p->next = q->next; 24 | free(q); 25 | } 26 | } 27 | return head; 28 | } -------------------------------------------------------------------------------- /第1章:顺序表与链表/3、习题课-演示代码(一)/2、Leetcode-24.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 24.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 四 4/11 18:58:05 2019 7 | ************************************************************************/ 8 | 9 | /** 10 | * Definition for singly-linked list. 11 | * struct ListNode { 12 | * int val; 13 | * struct ListNode *next; 14 | * }; 15 | */ 16 | struct ListNode* swapPairs(struct ListNode* head) { 17 | struct ListNode *p, *q, ret; 18 | ret.next = head; 19 | p = &ret; 20 | q = head; 21 | while (q && q->next) { 22 | p->next = q->next; 23 | q->next = p->next->next; 24 | p->next->next = q; 25 | p = q; 26 | q = q->next; 27 | } 28 | return ret.next; 29 | } -------------------------------------------------------------------------------- /第3章:树与二叉树/5、演示代码(二)/4、Leetcode-111.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 111.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 四 4/25 20:23:14 2019 7 | ************************************************************************/ 8 | 9 | /** 10 | * Definition for a binary tree node. 11 | * struct TreeNode { 12 | * int val; 13 | * struct TreeNode *left; 14 | * struct TreeNode *right; 15 | * }; 16 | */ 17 | int minDepth(struct TreeNode* root) { 18 | if (root == NULL) return 0; 19 | if (root->left == NULL && root->right == NULL) return 1; 20 | if (root->left == NULL || root->right == NULL) 21 | return minDepth(root->right ? root->right : root->left) + 1; 22 | return fmin(minDepth(root->left), minDepth(root->right)) + 1; 23 | } -------------------------------------------------------------------------------- /第1章:顺序表与链表/3、习题课-演示代码(一)/1、Leetcode-19.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 19.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 四 4/11 18:40:05 2019 7 | ************************************************************************/ 8 | 9 | /** 10 | * Definition for singly-linked list. 11 | * struct ListNode { 12 | * int val; 13 | * struct ListNode *next; 14 | * }; 15 | */ 16 | struct ListNode* removeNthFromEnd(struct ListNode* head, int n) { 17 | struct ListNode ret, *p, *q; 18 | ret.next = head; 19 | p = q = &ret; 20 | while (n--) { q = q->next; } 21 | q = q->next; 22 | while (q) { 23 | p = p->next; 24 | q = q->next; 25 | } 26 | q = p->next; 27 | p->next = q->next; 28 | free(q); 29 | return ret.next; 30 | } -------------------------------------------------------------------------------- /第3章:树与二叉树/5、演示代码(二)/2、Leetcode-110.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 110.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 四 4/25 20:15:05 2019 7 | ************************************************************************/ 8 | 9 | /** 10 | * Definition for a binary tree node. 11 | * struct TreeNode { 12 | * int val; 13 | * struct TreeNode *left; 14 | * struct TreeNode *right; 15 | * }; 16 | */ 17 | 18 | int maxDepth(struct TreeNode* root) { 19 | if (root == NULL) return 0; 20 | int d1 = maxDepth(root->left); 21 | int d2 = maxDepth(root->right); 22 | if (d1 == -2 || d2 == -2 || abs(d1 - d2) > 1) return -2; 23 | return fmax(d1, d2) + 1; 24 | } 25 | 26 | bool isBalanced(struct TreeNode* root) { 27 | return maxDepth(root) >= 0; 28 | } -------------------------------------------------------------------------------- /第1章:顺序表与链表/4、习题课-演示代码(二)/2、Leetcode-203.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 203.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 一 7/15 18:40:23 2019 7 | ************************************************************************/ 8 | 9 | /** 10 | * Definition for singly-linked list. 11 | * struct ListNode { 12 | * int val; 13 | * struct ListNode *next; 14 | * }; 15 | */ 16 | struct ListNode* removeElements(struct ListNode* head, int val) { 17 | struct ListNode ret, *p = &ret, *q; 18 | ret.next = head; 19 | while (p && p->next) { 20 | if (p->next->val == val) { 21 | q = p->next; 22 | p->next = p->next->next; 23 | free(q); 24 | } else { 25 | p = p->next; 26 | } 27 | } 28 | return ret.next; 29 | } -------------------------------------------------------------------------------- /第5章:排序与查找/8、演示代码(四)/2、Leetcode-374.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 374.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 六 5/11 16:49:31 2019 7 | ************************************************************************/ 8 | 9 | // Forward declaration of guess API. 10 | // @param num, your guess 11 | // @return -1 if my number is lower, 1 if my number is higher, otherwise return 0 12 | int guess(int num); 13 | 14 | class Solution { 15 | public: 16 | int guessNumber(int n) { 17 | int head = 1, tail = n, mid; 18 | while (head <= tail) { 19 | mid = head + ((tail - head) >> 1); 20 | int ret = guess(mid); 21 | if (ret == 0) return mid; 22 | if (ret < 0) tail = mid - 1; 23 | else head = mid + 1; 24 | } 25 | return -1; 26 | } 27 | }; -------------------------------------------------------------------------------- /第1章:顺序表与链表/5、习题课-演示代码(三)/1、Leetcode-142.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 142.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 一 7/15 15:05:46 2019 7 | ************************************************************************/ 8 | 9 | /** 10 | * Definition for singly-linked list. 11 | * struct ListNode { 12 | * int val; 13 | * struct ListNode *next; 14 | * }; 15 | */ 16 | struct ListNode *detectCycle(struct ListNode *head) { 17 | struct ListNode *p = head, *q = head; 18 | while (q) { 19 | p = p->next; 20 | q = q->next; 21 | if (q == NULL) return NULL; 22 | q = q->next; 23 | if (p == q) break; 24 | } 25 | if (q == NULL) return NULL; 26 | q = head; 27 | while (p != q) { 28 | p = p->next; 29 | q = q->next; 30 | } 31 | return p; 32 | } -------------------------------------------------------------------------------- /第5章:排序与查找/6、演示代码(二)/1、Leetcode-21.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 21.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 六 5/11 14:49:13 2019 7 | ************************************************************************/ 8 | 9 | /** 10 | * Definition for singly-linked list. 11 | * struct ListNode { 12 | * int val; 13 | * struct ListNode *next; 14 | * }; 15 | */ 16 | 17 | 18 | struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2){ 19 | struct ListNode ret, *p, *q, *t; 20 | ret.next = NULL; 21 | t = &ret; 22 | p = l1, q = l2; 23 | while (p || q) { 24 | if (q == NULL || (p && p->val <= q->val)) { 25 | t->next = p; p = p->next; t = t->next; 26 | } else { 27 | t->next = q; q = q->next; t = t->next; 28 | } 29 | } 30 | return ret.next; 31 | } -------------------------------------------------------------------------------- /第3章:树与二叉树/4、演示代码(一)/2、Leetcode-101.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 101.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 四 4/25 18:24:21 2019 7 | ************************************************************************/ 8 | 9 | /** 10 | * Definition for a binary tree node. 11 | * struct TreeNode { 12 | * int val; 13 | * struct TreeNode *left; 14 | * struct TreeNode *right; 15 | * }; 16 | */ 17 | 18 | bool isSameTree(struct TreeNode* p, struct TreeNode* q) { 19 | if (p == NULL && q == NULL) return true; 20 | if (p == NULL || q == NULL) return false; 21 | if (p->val - q->val) return false; 22 | return isSameTree(p->left, q->right) && isSameTree(p->right, q->left); 23 | } 24 | 25 | bool isSymmetric(struct TreeNode* root) { 26 | if (root == NULL) return true; 27 | return isSameTree(root->left, root->right); 28 | } -------------------------------------------------------------------------------- /第2章:栈和队列/4、演示代码(栈&队列)/1、Leetcode-20.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 20.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 四 4/11 18:58:05 2019 7 | ************************************************************************/ 8 | 9 | bool isValid(char* s) { 10 | int len = strlen(s), top = -1, flag = 1; 11 | char *stack = (char *)malloc(sizeof(char) * len); 12 | while (s[0]) { 13 | switch (s[0]) { 14 | case '(': 15 | case '[': 16 | case '{': stack[++top] = s[0]; break; 17 | case ')': flag = (top != -1 && stack[top--] == '('); break; 18 | case ']': flag = (top != -1 && stack[top--] == '['); break; 19 | case '}': flag = (top != -1 && stack[top--] == '{'); break; 20 | } 21 | if (!flag) break; 22 | s++; 23 | } 24 | free(stack); 25 | return (flag && top == -1); 26 | } -------------------------------------------------------------------------------- /第4章:堆与优先队列/4、演示代码(二)/1、HZOJ-287-合并果子(heap).cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 287.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 一 8/12 19:10:24 2019 7 | ************************************************************************/ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | using namespace std; 19 | 20 | priority_queue, greater> q; 21 | 22 | int main() { 23 | int n, a, sum = 0; 24 | cin >> n; 25 | for (int i = 0; i < n; i++) cin >> a, q.push(a); 26 | for (int i = 1; i < n; i++) { 27 | int val1 = q.top(); q.pop(); 28 | int val2 = q.top(); q.pop(); 29 | q.push(val1 + val2); 30 | sum += val1 + val2; 31 | } 32 | cout << sum << endl; 33 | return 0; 34 | } -------------------------------------------------------------------------------- /第5章:排序与查找/6、演示代码(二)/3、Leetcode-38.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 38.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 六 5/11 15:06:15 2019 7 | ************************************************************************/ 8 | 9 | char* countAndSay(int n) { 10 | if (n == 1) return strdup("1"); 11 | char *s = countAndSay(n - 1); 12 | int len = 1; 13 | for (int i = 1; s[i]; i++) len += (s[i] != s[i - 1]); 14 | len = len << 1 + 1; 15 | char *ret = (char *)malloc(sizeof(char) * len); 16 | char ch = s[0]; 17 | int cnt = 1, offset = 0; 18 | for (int i = 1; s[i]; i++) { 19 | if (s[i] == s[i - 1]) { 20 | cnt += 1; 21 | } else { 22 | offset += sprintf(ret + offset, "%d%c\0", cnt, ch); 23 | ch = s[i]; 24 | cnt = 1; 25 | } 26 | } 27 | sprintf(ret + offset, "%d%c\0", cnt, ch); 28 | free(s); 29 | return ret; 30 | } -------------------------------------------------------------------------------- /第2章:栈和队列/5、演示代码(单调栈&单调队列)/1、Leetcode-42.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 42.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 三 7/17 20:47:11 2019 7 | ************************************************************************/ 8 | 9 | int trap(int* height, int heightSize) { 10 | int n = heightSize, ans = 0, top = -1; 11 | int *stack = (int *)malloc(sizeof(int) * n); 12 | for (int i = 0; i < heightSize; i++) { 13 | while (top != -1 && height[stack[top]] <= height[i]) { 14 | if (top >= 1) { 15 | int w = i - stack[top - 1] - 1; 16 | int val1 = height[i] - height[stack[top]]; 17 | int val2 = height[stack[top - 1]] - height[stack[top]]; 18 | int h = (val1 < val2 ? val1 : val2); 19 | ans += h * w; 20 | } 21 | top--; 22 | } 23 | stack[++top] = i; 24 | } 25 | free(stack); 26 | return ans; 27 | } -------------------------------------------------------------------------------- /第4章:堆与优先队列/4、演示代码(二)/2、HZOJ-287-合并果子(set).cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 287.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 一 8/12 19:10:24 2019 7 | ************************************************************************/ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | using namespace std; 20 | 21 | typedef pair PII; 22 | set s; 23 | 24 | int main() { 25 | int n, a, sum = 0; 26 | cin >> n; 27 | while (n--) cin >> a, s.insert(PII(a, n)); 28 | while (s.size() != 1) { 29 | int val1 = s.begin()->first; s.erase(s.begin()); 30 | int val2 = s.begin()->first; s.erase(s.begin()); 31 | s.insert(PII(val1 + val2, n--)); 32 | sum += val1 + val2; 33 | } 34 | cout << sum << endl; 35 | return 0; 36 | } -------------------------------------------------------------------------------- /第2章:栈和队列/5、演示代码(单调栈&单调队列)/4、Leetcode-239.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 239.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 四 4/11 18:58:05 2019 7 | ************************************************************************/ 8 | 9 | /** 10 | * Return an array of size *returnSize. 11 | * Note: The returned array must be malloced, assume caller calls free(). 12 | */ 13 | int* maxSlidingWindow(int* nums, int numsSize, int k, int* returnSize) { 14 | int n = (numsSize == 0 ? 0 : numsSize - k + 1); 15 | int *ret = (int *)malloc(sizeof(int) * n); 16 | int *q = (int *)malloc(sizeof(int) * numsSize); 17 | int head = 0, tail = 0; 18 | *returnSize = n; 19 | n = 0; 20 | for (int i = 0; i < numsSize; i++) { 21 | while (tail - head && nums[i] > nums[q[tail - 1]]) --tail; 22 | q[tail++] = i; 23 | if (i - q[head] + 1 > k) head++; 24 | if (i + 1 >= k) ret[n++] = nums[q[head]]; 25 | } 26 | free(q); 27 | return ret; 28 | } -------------------------------------------------------------------------------- /第5章:排序与查找/5、演示代码(一)/3、Leetcode-2-1.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 2-1.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 四 5/ 9 20:39:50 2019 7 | ************************************************************************/ 8 | 9 | int check(char *s, int n) { 10 | char cnt[128] = {0}; 11 | int p = 0; 12 | for (int i = 0; i < n; i++) { 13 | cnt[s[i]]++; 14 | if (cnt[s[i]] == 1) p += 1; 15 | } 16 | if (p == n) return 1; 17 | for (int i = n; s[i]; i++) { 18 | cnt[s[i]] += 1; 19 | if (cnt[s[i]] == 1) p += 1; 20 | cnt[s[i - n]] -= 1; 21 | if (cnt[s[i - n]] == 0) p -= 1; 22 | if (p == n) return 1; 23 | } 24 | return 0; 25 | } 26 | 27 | int lengthOfLongestSubstring(char* s) { 28 | int head = 0, tail = strlen(s), mid; 29 | while (head < tail) { 30 | mid = (head + tail + 1) >> 1; 31 | if (check(s, mid) == 1) head = mid; 32 | else tail = mid - 1; 33 | } 34 | return head; 35 | } -------------------------------------------------------------------------------- /第2章:栈和队列/2、单调队列/1、HZOJ-270-最大子序和.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 270.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 三 7/17 15:47:49 2019 7 | ************************************************************************/ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | using namespace std; 18 | #define MAX_N 300000 19 | int q[MAX_N + 5], head, tail; 20 | long long arr[MAX_N + 5]; 21 | 22 | int main() { 23 | long long n, m, ans; 24 | cin >> n >> m; 25 | for (int i = 1; i <= n; i++) cin >> arr[i], arr[i] += arr[i - 1]; 26 | head = tail = 0; 27 | q[tail++] = 0; 28 | ans = arr[1]; 29 | for (int i = 1; i <= n; i++) { 30 | ans = max(ans, arr[i] - arr[q[head]]); 31 | while (tail - head && arr[q[tail - 1]] >= arr[i]) tail--; 32 | q[tail++] = i; 33 | if (q[head] == i - m) head++; 34 | } 35 | cout << ans << endl; 36 | return 0; 37 | } -------------------------------------------------------------------------------- /第3章:树与二叉树/6、演示代码(三)/2、Leetcode-235.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 235.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 四 4/25 20:36:36 2019 7 | ************************************************************************/ 8 | 9 | /** 10 | * Definition for a binary tree node. 11 | * struct TreeNode { 12 | * int val; 13 | * struct TreeNode *left; 14 | * struct TreeNode *right; 15 | * }; 16 | */ 17 | 18 | struct TreeNode* __lowestCommonAncestor(struct TreeNode* root, struct TreeNode* p, struct TreeNode* q) { 19 | if (root->val == p->val) return p; 20 | if (root->val == q->val) return q; 21 | if (p->val < root->val && q->val > root->val) return root; 22 | if (p->val > root->val) return __lowestCommonAncestor(root->right, p, q); 23 | return __lowestCommonAncestor(root->left, p, q); 24 | } 25 | 26 | struct TreeNode* lowestCommonAncestor(struct TreeNode* root, struct TreeNode* p, struct TreeNode* q) { 27 | if (root == NULL) return NULL; 28 | if (p->val == q->val) return p; 29 | if (p->val > q->val) { 30 | struct TreeNode *temp = p; 31 | p = q; 32 | q = temp; 33 | } 34 | return __lowestCommonAncestor(root, p, q); 35 | } -------------------------------------------------------------------------------- /第13章:贪心法习题课/2、代码演示(二)/2、HZOJ-258-最大子阵和.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 258.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 四 6/20 19:48:26 2019 7 | ************************************************************************/ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | using namespace std; 18 | #define MAX_N 100 19 | int g[MAX_N + 5][MAX_N + 5]; 20 | 21 | int main() { 22 | int n, ans = -128; 23 | cin >> n; 24 | for (int i = 1; i <= n; i++) { 25 | for (int j = 1; j <= n; j++) { 26 | cin >> g[i][j]; 27 | ans = max(ans, g[i][j]); 28 | g[i][j] += g[i - 1][j]; 29 | } 30 | } 31 | for (int i = 1; i <= n; i++) { 32 | for (int j = i; j <= n; j++) { 33 | int sum = 0, pre_min = 0; 34 | for (int k = 1; k <= n; k++) { 35 | sum += g[j][k] - g[i - 1][k]; 36 | ans = max(ans, sum - pre_min); 37 | pre_min = min(pre_min, sum); 38 | } 39 | } 40 | } 41 | cout << ans << endl; 42 | return 0; 43 | } -------------------------------------------------------------------------------- /第5章:排序与查找/8、演示代码(四)/3、Leetcode-378.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 378.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 六 5/11 18:55:45 2019 7 | ************************************************************************/ 8 | 9 | typedef struct Data { 10 | int cnt, rank; 11 | } Data; 12 | 13 | Data count(int **matrix, int n, int m, int x) { 14 | int i = n, j = 0, rank = 0, cnt = 0, k; 15 | for (int j = 0; j < m; j++) { 16 | while (i > 0 && matrix[i - 1][j] > x) --i; 17 | rank += i; 18 | k = i - 1; 19 | while (k >= 0 && matrix[k][j] == x) --k, ++cnt; 20 | } 21 | Data d = {cnt, rank}; 22 | return d; 23 | } 24 | 25 | int kthSmallest(int** matrix, int matrixRowSize, int *matrixColSize, int k) { 26 | int n = matrixRowSize, m = matrixRowSize; 27 | int head = matrix[0][0], tail = matrix[n - 1][m - 1], mid; 28 | 29 | while (head <= tail) { 30 | mid = head + ((tail - head) >> 1); 31 | Data d = count(matrix, n, m, mid); 32 | if (k <= d.rank && k >= d.rank - d.cnt + 1) { 33 | return mid; 34 | } 35 | if (d.rank < k) head = mid + 1; 36 | else tail = mid - 1; 37 | } 38 | return -1; 39 | } -------------------------------------------------------------------------------- /第2章:栈和队列/5、演示代码(单调栈&单调队列)/2、Leetcode-84.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 84.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 四 4/11 18:58:05 2019 7 | ************************************************************************/ 8 | 9 | int largestRectangleArea(int* heights, int heightsSize) { 10 | int top = -1; 11 | int *stack = (int *)malloc(sizeof(int) * heightsSize); 12 | int *left = (int *)malloc(sizeof(int) * heightsSize); 13 | int *right = (int *)malloc(sizeof(int) * heightsSize); 14 | for (int i = 0; i < heightsSize; i++) { 15 | while (top != -1 && heights[stack[top]] >= heights[i]) --top; 16 | left[i] = (top == -1 ? i + 1 : i - stack[top]); 17 | stack[++top] = i; 18 | } 19 | top = -1; 20 | for (int i = heightsSize - 1; i >= 0; i--) { 21 | while (top != -1 && heights[stack[top]] >= heights[i]) --top; 22 | right[i] = (top == -1 ? heightsSize - i : stack[top] - i); 23 | stack[++top] = i; 24 | } 25 | int ans = 0; 26 | for (int i = 0; i < heightsSize; i++) { 27 | ans = fmax(ans, (left[i] + right[i] - 1) * heights[i]); 28 | } 29 | free(stack); 30 | free(left); 31 | free(right); 32 | return ans; 33 | } -------------------------------------------------------------------------------- /第13章:贪心法习题课/1、代码演示(一)/2、HZOJ-255-安装雷达.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 255.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 二 6/18 19:57:15 2019 7 | ************************************************************************/ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | using namespace std; 18 | #define MAX_N 1000 19 | struct Range { 20 | double l, r; 21 | } arr[MAX_N + 5]; 22 | 23 | bool cmp(const Range &a, const Range &b) { 24 | return a.r < b.r; 25 | } 26 | 27 | int main() { 28 | int n; 29 | double d; 30 | cin >> n >> d; 31 | for (int i = 0; i < n; i++) { 32 | double x, y; 33 | cin >> x >> y; 34 | if (y > d) { 35 | cout << -1 << endl; 36 | return 0; 37 | } 38 | arr[i].l = x - sqrt(d * d - y * y); 39 | arr[i].r = x + sqrt(d * d - y * y); 40 | } 41 | sort(arr, arr + n, cmp); 42 | double p = arr[0].r; 43 | int cnt = 1; 44 | for (int i = 1; i < n; i++) { 45 | if (arr[i].l > p) { 46 | cnt += 1; 47 | p = arr[i].r; 48 | } 49 | } 50 | cout << cnt << endl; 51 | return 0; 52 | } -------------------------------------------------------------------------------- /第1章:顺序表与链表/4、习题课-演示代码(二)/4、Leetcode-234.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 234.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 一 7/15 19:02:26 2019 7 | ************************************************************************/ 8 | 9 | /** 10 | * Definition for singly-linked list. 11 | * struct ListNode { 12 | * int val; 13 | * struct ListNode *next; 14 | * }; 15 | */ 16 | 17 | int get_length(struct ListNode *head) { 18 | int n = 0; 19 | while (head) n += 1, head = head->next; 20 | return n; 21 | } 22 | 23 | struct ListNode *get_node(struct ListNode *head, int ind) { 24 | while (ind--) head = head->next; 25 | return head; 26 | } 27 | 28 | struct ListNode *reverse(struct ListNode *head) { 29 | struct ListNode ret, *p = head, *q; 30 | ret.next = NULL; 31 | while (p) { 32 | q = p->next; 33 | p->next = ret.next; 34 | ret.next = p; 35 | p = q; 36 | } 37 | return ret.next; 38 | } 39 | 40 | bool isPalindrome(struct ListNode* head) { 41 | int len = get_length(head); 42 | struct ListNode *p = head, *q = reverse(get_node(head, (len + 1) / 2)); 43 | while (q) { 44 | if (p->val - q->val) return false; 45 | p = p->next; 46 | q = q->next; 47 | } 48 | return true; 49 | } -------------------------------------------------------------------------------- /第2章:栈和队列/3、单调栈/1、HZOJ-264-最大矩形面积.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 264.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 三 7/17 16:30:45 2019 7 | ************************************************************************/ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | using namespace std; 19 | #define MAX_N 100000 20 | long long arr[MAX_N + 5]; 21 | long long l[MAX_N + 5], r[MAX_N + 5]; 22 | 23 | int main() { 24 | int n; 25 | stack s; 26 | cin >> n; 27 | arr[0] = arr[n + 1] = -1; 28 | for (int i = 1; i <= n; i++) cin >> arr[i]; 29 | s.push(0); 30 | for (int i = 1; i <= n; i++) { 31 | while (arr[s.top()] >= arr[i]) s.pop(); 32 | l[i] = i - s.top(); 33 | s.push(i); 34 | } 35 | while (!s.empty()) s.pop(); 36 | s.push(n + 1); 37 | for (int i = n; i >= 1; i--) { 38 | while (arr[s.top()] >= arr[i]) s.pop(); 39 | r[i] = s.top() - i; 40 | s.push(i); 41 | } 42 | long long ans = 0; 43 | for (int i = 1; i <= n; i++) { 44 | ans = max(ans, arr[i] * (r[i] + l[i] - 1)); 45 | } 46 | cout << ans << endl; 47 | return 0; 48 | } -------------------------------------------------------------------------------- /第6章:字符串匹配算法(1)/2、附录1-其余资料/1、HZOJ-278-循环字符串.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 278.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 五 8/16 16:07:52 2019 7 | ************************************************************************/ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | using namespace std; 18 | #define MAX_N 1000000 19 | char str[MAX_N + 5]; 20 | int nxt[MAX_N + 5]; 21 | int ans[MAX_N + 5]; 22 | 23 | void get_next(char *str, int *nxt) { 24 | int j = -1; 25 | nxt[0] = -1; 26 | for (int i = 1; str[i]; i++) { 27 | while (j != -1 && str[j + 1] != str[i]) j = nxt[j]; 28 | if (str[j + 1] == str[i]) j += 1; 29 | nxt[i] = j; 30 | } 31 | return ; 32 | } 33 | 34 | int main() { 35 | int n; 36 | cin >> n; 37 | cin >> str; 38 | get_next(str, nxt); 39 | for (int i = 0; i < n; i++) { 40 | if (nxt[i] == -1 || i - nxt[i] != ans[nxt[i]]) { 41 | ans[i] = i + 1; 42 | } else { 43 | ans[i] = ans[nxt[i]]; 44 | } 45 | } 46 | for (int i = 0; i < n; i++) { 47 | if (ans[i] == i + 1) continue; 48 | cout << i + 1 << " " << (i + 1) / ans[i] << endl; 49 | } 50 | return 0; 51 | } -------------------------------------------------------------------------------- /第7章:字符串匹配算法(2)/3、演示代码(一)/1、HZOJ-281-前缀统计.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 281.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 三 8/21 16:07:35 2019 7 | ************************************************************************/ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | using namespace std; 18 | #define MAX_N 1000000 19 | 20 | struct Node { 21 | int flag; 22 | int next[26]; 23 | } tree[MAX_N + 5]; 24 | int root = 1, cnt = 1; 25 | char str[MAX_N + 5]; 26 | 27 | int getNode() { return ++cnt; } 28 | void insert(const char *str) { 29 | int p = root; 30 | for (int i = 0; str[i]; i++) { 31 | int ind = str[i] - 'a'; 32 | if (tree[p].next[ind] == 0) tree[p].next[ind] = getNode(); 33 | p = tree[p].next[ind]; 34 | } 35 | tree[p].flag += 1; 36 | return ; 37 | } 38 | 39 | int query(const char *str) { 40 | int p = root, cnt = 0; 41 | for (int i = 0; str[i] && p; i++) { 42 | p = tree[p].next[str[i] - 'a']; 43 | cnt += tree[p].flag; 44 | } 45 | return cnt; 46 | } 47 | 48 | int main() { 49 | int n, m; 50 | cin >> n >> m; 51 | while (n--) cin >> str, insert(str); 52 | while (m--) cin >> str, cout << query(str) << endl; 53 | return 0; 54 | } -------------------------------------------------------------------------------- /第10章:森林与并查集/7、演示代码(四)/2、Leetcode-547.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 547.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 四 5/23 19:17:29 2019 7 | ************************************************************************/ 8 | 9 | #define MC(T, n) (T *)malloc(sizeof(T) * (n)) 10 | #define CC(T, n) (T *)calloc(sizeof(T), (n)) 11 | 12 | typedef struct UnionSet { 13 | int *fa; 14 | int n; 15 | } UnionSet; 16 | 17 | UnionSet *init(int n) { 18 | UnionSet *u = MC(UnionSet, 1); 19 | u->fa = MC(int, n + 1); 20 | u->n = n; 21 | for (int i = 1; i <= n; i++) u->fa[i] = i; 22 | return u; 23 | } 24 | 25 | void clear(UnionSet *u) { 26 | if (u == NULL) return ; 27 | free(u->fa); 28 | free(u); 29 | return ; 30 | } 31 | 32 | int get(UnionSet *u, int x) { 33 | if (u->fa[x] == x) return x; 34 | return u->fa[x] = get(u, u->fa[x]); 35 | } 36 | 37 | void merge(UnionSet *u, int a, int b) { 38 | u->n -= (get(u, a) != get(u, b)); 39 | u->fa[get(u, a)] = get(u, b); 40 | } 41 | 42 | int findCircleNum(int** M, int n, int *m) { 43 | if (n == 0) return 0; 44 | UnionSet *u = init(n); 45 | for (int i = 0; i < n; i++) { 46 | for (int j = 0; j < n; j++) { 47 | if (M[i][j] == 0) continue; 48 | merge(u, i + 1, j + 1); 49 | } 50 | } 51 | int ans = u->n; 52 | clear(u); 53 | return ans; 54 | } -------------------------------------------------------------------------------- /第4章:堆与优先队列/4、演示代码(二)/3、HZOJ-284-超市卖货.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 284.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 一 8/12 19:47:15 2019 7 | ************************************************************************/ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | using namespace std; 19 | #define MAX_N 10000 20 | 21 | struct Data { 22 | int p, d; 23 | } arr[MAX_N + 5]; 24 | 25 | bool cmp(const Data &a, const Data &b) { 26 | return a.d < b.d; 27 | } 28 | 29 | typedef pair PII; 30 | set s; 31 | 32 | int main() { 33 | int n; 34 | cin >> n; 35 | for (int i = 0; i < n; i++) cin >> arr[i].p >> arr[i].d; 36 | sort(arr, arr + n, cmp); 37 | for (int i = 0; i < n; i++) { 38 | if (arr[i].d > s.size()) { 39 | s.insert(PII(arr[i].p, arr[i].d)); 40 | } else if (arr[i].p > s.begin()->first) { 41 | s.insert(PII(arr[i].p, s.begin()->second)); 42 | s.erase(s.begin()); 43 | } 44 | } 45 | int sum = 0; 46 | cout << "-----------" << endl; 47 | for (auto iter = s.begin(); iter != s.end(); iter++) { 48 | sum += iter->first; 49 | cout << iter->first << " " << iter->second << endl; 50 | } 51 | cout << sum << endl; 52 | return 0; 53 | } -------------------------------------------------------------------------------- /第5章:排序与查找/5、演示代码(一)/5、Leetcode-4.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 4.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 四 5/ 9 21:18:19 2019 7 | ************************************************************************/ 8 | 9 | double find(int *a, int *b, int n, int m, int k, int flag) { 10 | if (n == 0 && m == 0) return 0; 11 | if (n == 0 || m == 0) { 12 | if (m == 0) b = a; 13 | if (flag) return b[k - 1]; 14 | return 1.0 * (b[k - 1] + b[k]) / 2.0; 15 | } 16 | if (k == 1) { 17 | int ret[2], t = 0; 18 | int p = 0, q = 0; 19 | while ((p < n || q < m) && t < 2) { 20 | if (q >= m || (p < n && a[p] <= b[q])) { 21 | ret[t++] = a[p++]; 22 | } else { 23 | ret[t++] = b[q++]; 24 | } 25 | } 26 | if (flag) return ret[0]; 27 | return 1.0 * (ret[0] + ret[1]) / 2.0; 28 | } 29 | int ind_a = fmin(k >> 1, n); 30 | int ind_b = fmin(k - ind_a, m); 31 | ind_a = k - ind_b; 32 | if (ind_a > 0 && a[ind_a - 1] < b[ind_b - 1]) { 33 | return find(a + ind_a, b, n - ind_a, m, k - ind_a, flag); 34 | } 35 | return find(a, b + ind_b, n, m - ind_b, k - ind_b, flag); 36 | } 37 | 38 | double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size){ 39 | int n = nums1Size + nums2Size; 40 | int k = (n + 1) >> 1; 41 | return find(nums1, nums2, nums1Size, nums2Size, k, n & 1); 42 | } -------------------------------------------------------------------------------- /第2章:栈和队列/5、演示代码(单调栈&单调队列)/3、Leetcode-221.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 221.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 四 4/11 18:58:05 2019 7 | ************************************************************************/ 8 | 9 | int maximalSquare(char** matrix, int matrixRowSize, int matrixColSizes) { 10 | int n = matrixRowSize, m = matrixColSizes; 11 | if (n == 0) return 0; 12 | int **cnt = (int **)malloc(sizeof(int *) * n); 13 | int *q = (int *)malloc(sizeof(int) * m); 14 | int head, tail, l; 15 | for (int i = 0; i < n; i++) cnt[i] = (int *)malloc(sizeof(int) * m); 16 | for (int i = 0; i < m; i++) cnt[0][i] = (matrix[0][i] == '1'); 17 | for (int i = 1; i < n; i++) { 18 | for (int j = 0; j < m; j++) { 19 | cnt[i][j] = (matrix[i][j] == '1' ? cnt[i - 1][j] + 1 : 0); 20 | } 21 | } 22 | int ans = 0; 23 | for (int i = 0; i < n; i++) { 24 | head = tail = 0; 25 | l = 0; 26 | for (int j = 0; j < m; j++) { 27 | while (tail - head > 0 && cnt[i][q[tail - 1]] > cnt[i][j]) --tail; 28 | q[tail++] = j; 29 | while (j - l >= 0 && j - l + 1 > cnt[i][q[head]]) { 30 | ++l; 31 | if (q[head] < l) ++head; 32 | } 33 | ans = fmax(ans, (j - l + 1) * (j - l + 1)); 34 | } 35 | } 36 | for (int i = 0; i < n; i++) free(cnt[i]); 37 | free(cnt); 38 | free(q); 39 | return ans; 40 | } -------------------------------------------------------------------------------- /第11章:树状数组与线段树/1、树状数组结构基础/1、HZOJ-329-弱化的整数问题.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 329.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 四 8/22 20:39:12 2019 7 | ************************************************************************/ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | using namespace std; 18 | #define MAX_N 100000 19 | int c[MAX_N + 5]; 20 | inline int lowbit(int x) { return x & (-x); } 21 | void add(int x, int val, int n) { 22 | while (x <= n) c[x] += val, x += lowbit(x); 23 | } 24 | int query(int x) { 25 | int sum = 0; 26 | while (x) sum += c[x], x -= lowbit(x); 27 | return sum; 28 | } 29 | 30 | int main() { 31 | int n, m, pre = 0, now; 32 | char str[10]; 33 | cin >> n; 34 | for (int i = 1; i <= n; i++) { 35 | cin >> now; 36 | add(i, now - pre, n); 37 | pre = now; 38 | } 39 | cin >> m; 40 | for (int i = 0; i < m; i++) { 41 | cin >> str; 42 | switch (str[0]) { 43 | case 'C': { 44 | int a, b, c; 45 | cin >> a >> b >> c; 46 | add(a, c, n); 47 | add(b + 1, -c, n); 48 | } break; 49 | case 'Q': { 50 | int x; 51 | cin >> x; 52 | cout << query(x) << endl; 53 | } 54 | } 55 | } 56 | return 0; 57 | } -------------------------------------------------------------------------------- /第13章:贪心法习题课/1、代码演示(一)/1、HZOJ-253-奶牛晒太阳.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 253.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 二 6/18 19:31:12 2019 7 | ************************************************************************/ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | using namespace std; 18 | #define MAX_N 2500 19 | struct Range { 20 | int l, r; 21 | } arr[MAX_N + 5], item[MAX_N + 5]; 22 | 23 | bool cmp(const Range &a, const Range &b) { 24 | return a.r < b.r; 25 | } 26 | 27 | int main() { 28 | int n, l; 29 | cin >> n >> l; 30 | for (int i = 0; i < n; i++) { 31 | cin >> arr[i].l >> arr[i].r; 32 | } 33 | for (int i = 0; i < l; i++) { 34 | cin >> item[i].l >> item[i].r; 35 | } 36 | sort(arr, arr + n, cmp); 37 | int ans = 0; 38 | for (int i = 0; i < n; i++) { 39 | int flag = 0, ind = -1; 40 | for (int j = 0; j < l; j++) { 41 | if (item[j].r == 0) continue; 42 | if (item[j].l < arr[i].l || item[j].l > arr[i].r) continue; 43 | if (ind == -1) { 44 | ind = j; 45 | flag = 1; 46 | continue; 47 | } 48 | if (item[j].l < item[ind].l) ind = j; 49 | } 50 | if (flag) item[ind].r -= 1; 51 | ans += flag; 52 | } 53 | cout << ans << endl; 54 | return 0; 55 | } -------------------------------------------------------------------------------- /第10章:森林与并查集/3、【竞赛版】并查集基础知识/1、HZOJ-71-朋友圈.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 71.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 三 8/21 20:03:31 2019 7 | ************************************************************************/ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | using namespace std; 18 | #define MAX_N 10000 19 | 20 | struct UnionSet { 21 | int fa[MAX_N + 5], size[MAX_N + 5]; 22 | void init(int n) { 23 | for (int i = 1; i <= n; i++) { 24 | fa[i] = i; 25 | size[i] = 1; 26 | } 27 | } 28 | int get(int x) { 29 | return (fa[x] = (x == fa[x] ? x : get(fa[x]))); 30 | } 31 | void merge(int a, int b) { 32 | int aa = get(a), bb = get(b); 33 | if (aa == bb) return ; 34 | if (size[aa] < size[bb]) swap(aa, bb); 35 | fa[bb] = aa; 36 | size[aa] += size[bb]; 37 | return ; 38 | } 39 | }; 40 | 41 | UnionSet u; 42 | 43 | void read(int &n, int &m) { 44 | cin >> n >> m; 45 | u.init(n); 46 | return ; 47 | } 48 | 49 | int main() { 50 | int n, m; 51 | read(n, m); 52 | for (int i = 0; i < m; i++) { 53 | int a, b, c; 54 | cin >> a >> b >> c; 55 | if (a == 1) { 56 | u.merge(b, c); 57 | } else { 58 | cout << (u.get(b) == u.get(c) ? "Yes" : "No") << endl; 59 | } 60 | } 61 | return 0; 62 | } -------------------------------------------------------------------------------- /第10章:森林与并查集/5、演示代码(二)/2、HZOJ-323-Supermarket.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 323.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 四 8/22 18:15:11 2019 7 | ************************************************************************/ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | using namespace std; 18 | #define MAX_N 10000 19 | 20 | struct Data { 21 | int p, d; 22 | } arr[MAX_N + 5]; 23 | 24 | struct UnionSet { 25 | int fa[MAX_N + 5]; 26 | void init(int n) { 27 | for (int i = 0; i <= n; i++) fa[i] = i; 28 | } 29 | int get(int x) { 30 | return (fa[x] = (x == fa[x] ? x : get(fa[x]))); 31 | } 32 | void merge(int a, int b) { 33 | fa[get(a)] = get(b); 34 | } 35 | }; 36 | 37 | 38 | bool cmp(const Data &a, const Data &b) { 39 | return a.p > b.p; 40 | } 41 | 42 | UnionSet u; 43 | 44 | int solve() { 45 | int n; 46 | if (!(cin >> n)) return 0; 47 | for (int i = 0; i < n; i++) { 48 | cin >> arr[i].p >> arr[i].d; 49 | } 50 | sort(arr, arr + n, cmp); 51 | u.init(MAX_N); 52 | int ans = 0; 53 | for (int i = 0; i < n; i++) { 54 | if (u.get(arr[i].d) == 0) continue; 55 | ans += arr[i].p; 56 | int day = u.get(arr[i].d); 57 | u.merge(day, day - 1); 58 | } 59 | cout << ans << endl; 60 | return 1; 61 | } 62 | 63 | int main() { 64 | while (solve()) ; 65 | return 0; 66 | } -------------------------------------------------------------------------------- /第7章:字符串匹配算法(2)/3、演示代码(一)/2、HZOJ-282-最大亦或和.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 282.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 三 8/21 16:25:46 2019 7 | ************************************************************************/ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | using namespace std; 18 | #define MAX_N 320000 19 | #define BASE 30 20 | 21 | struct Node { 22 | int num; 23 | int next[2]; 24 | } tree[MAX_N + 5]; 25 | int root = 1, cnt = 1; 26 | int arr[(MAX_N >> 5 )+ 5]; 27 | inline int getNode() { return ++cnt; } 28 | void insert(int num) { 29 | int p = root; 30 | for (int i = BASE; i >= 0; --i) { 31 | int ind = !!((1 << i) & num); 32 | if (tree[p].next[ind] == 0) tree[p].next[ind] = getNode(); 33 | p = tree[p].next[ind]; 34 | } 35 | tree[p].num = num; 36 | return ; 37 | } 38 | 39 | int query(int num) { 40 | int p = root; 41 | for (int i = BASE; i >= 0; i--) { 42 | int ind = !!((1 << i) & num); 43 | int rind = !ind; 44 | if (tree[p].next[rind]) p = tree[p].next[rind]; 45 | else p = tree[p].next[ind]; 46 | } 47 | return num ^ tree[p].num; 48 | } 49 | 50 | int main() { 51 | int n, ans = 0; 52 | cin >> n; 53 | for (int i = 0; i < n; i++) cin >> arr[i], insert(arr[i]); 54 | for (int i = 0; i < n; i++) { 55 | ans = max(ans, query(arr[i])); 56 | } 57 | cout << ans << endl; 58 | return 0; 59 | } -------------------------------------------------------------------------------- /第10章:森林与并查集/1、Quick-Find 代码演示/1、Quick-Find.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 13.UnionSet.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 二 5/21 19:26:12 2019 7 | ************************************************************************/ 8 | 9 | #include 10 | #include 11 | 12 | typedef struct UnionSet { 13 | int *color; 14 | int n; 15 | } UnionSet; 16 | 17 | UnionSet *init(int n) { 18 | UnionSet *u = (UnionSet *)malloc(sizeof(UnionSet)); 19 | u->color = (int *)malloc(sizeof(int) * (n + 1)); 20 | u->n = n; 21 | for (int i = 1; i <= n; i++) { 22 | u->color[i] = i; 23 | } 24 | return u; 25 | } 26 | 27 | int find(UnionSet *u, int x) { 28 | return u->color[x]; 29 | } 30 | 31 | int merge(UnionSet *u, int a, int b) { 32 | if (find(u, a) == find(u, b)) return 0; 33 | int color_a = u->color[a]; 34 | for (int i = 1; i <= u->n; i++) { 35 | if (u->color[i] - color_a) continue; 36 | u->color[i] = u->color[b]; 37 | } 38 | return 1; 39 | } 40 | 41 | void clear(UnionSet *u) { 42 | if (u == NULL) return ; 43 | free(u->color); 44 | free(u); 45 | return ; 46 | } 47 | 48 | int main() { 49 | int n, m; 50 | scanf("%d%d", &n, &m); 51 | UnionSet *u = init(n); 52 | for (int i = 0; i < m; i++) { 53 | int a, b, c; 54 | scanf("%d%d%d", &a, &b, &c); 55 | switch (a) { 56 | case 1: merge(u, b, c); break; 57 | case 2: printf("%s\n", find(u, b) == find(u, c) ? "Yes" : "No"); break; 58 | } 59 | } 60 | return 0; 61 | } -------------------------------------------------------------------------------- /第10章:森林与并查集/7、演示代码(四)/3、Leetcode-684.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 684.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 四 5/23 19:24:39 2019 7 | ************************************************************************/ 8 | 9 | /** 10 | * Return an array of size *returnSize. 11 | * Note: The returned array must be malloced, assume caller calls free(). 12 | */ 13 | #define MC(T, n) (T *)malloc(sizeof(T) * (n)) 14 | #define CC(T, n) (T *)calloc(sizeof(T), (n)) 15 | 16 | typedef struct UnionSet { 17 | int *fa; 18 | int n; 19 | } UnionSet; 20 | 21 | UnionSet *init(int n) { 22 | UnionSet *u = MC(UnionSet, 1); 23 | u->fa = MC(int, n + 1); 24 | u->n = n; 25 | for (int i = 1; i <= n; i++) u->fa[i] = i; 26 | return u; 27 | } 28 | 29 | void clear(UnionSet *u) { 30 | if (u == NULL) return ; 31 | free(u->fa); 32 | free(u); 33 | return ; 34 | } 35 | 36 | int get(UnionSet *u, int x) { 37 | if (u->fa[x] == x) return x; 38 | return u->fa[x] = get(u, u->fa[x]); 39 | } 40 | 41 | int merge(UnionSet *u, int a, int b) { 42 | u->n -= (get(u, a) != get(u, b)); 43 | u->fa[get(u, a)] = get(u, b); 44 | return u->n; 45 | } 46 | 47 | int* findRedundantConnection(int** edges, int n, int *m, int* rs) { 48 | UnionSet *u = init(n); 49 | int *ret = MC(int, 2); 50 | for (int i = 0; i < n; i++) { 51 | if (u->n == merge(u, edges[i][0], edges[i][1])) { 52 | ret[0] = edges[i][0]; 53 | ret[1] = edges[i][1]; 54 | break; 55 | } 56 | } 57 | *rs = 2; 58 | return ret; 59 | } -------------------------------------------------------------------------------- /第5章:排序与查找/3、二分查找与三分查找/1、binary_search.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 13.binary_search.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 二 11/ 6 19:27:01 2018 7 | ************************************************************************/ 8 | #include 9 | #define P(func) { \ 10 | printf("%s = %d\n", #func, func); \ 11 | } 12 | 13 | // 1 2 3 4 5 6 14 | int binary_search1(int *num, int n, int x) { 15 | int head = 0, tail = n - 1, mid; 16 | while (head <= tail) { 17 | mid = (head + tail) >> 1; 18 | if (num[mid] == x) return mid; 19 | if (num[mid] > x) tail = mid - 1; 20 | else head = mid + 1; 21 | } 22 | return -1; 23 | } 24 | 25 | // 111111000000 26 | int binary_search2(int *num, int n) { 27 | int head = -1, tail = n - 1, mid; 28 | while (head < tail) { 29 | mid = (head + tail + 1) >> 1; 30 | if (num[mid] == 1) head = mid; 31 | else tail = mid - 1; 32 | } 33 | return head; 34 | } 35 | 36 | // 00000111111 37 | int binary_search3(int *num, int n) { 38 | int head = 0, tail = n, mid; 39 | while (head < tail) { 40 | mid = (head + tail) >> 1; 41 | if (num[mid] == 1) tail = mid; 42 | else head = mid + 1; 43 | } 44 | return head == n ? -1 : head; 45 | } 46 | 47 | int main() { 48 | int arr1[10] = {1, 3, 5, 7, 11, 13, 17, 19, 23, 29}; 49 | int arr2[10] = {1, 1, 1, 0, 0, 0, 0, 0, 0, 0}; 50 | int arr3[10] = {0, 0, 0, 0, 0, 0, 1, 1, 1, 1}; 51 | P(binary_search1(arr1, 10, 11)); 52 | P(binary_search2(arr2, 10)); 53 | P(binary_search3(arr3, 10)); 54 | return 0; 55 | } -------------------------------------------------------------------------------- /第4章:堆与优先队列/2、堆排序与线性建堆法/1、heap_sort.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 9.heap_sort.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 五 8/ 9 19:52:25 2019 7 | ************************************************************************/ 8 | 9 | #include 10 | #include 11 | #include 12 | #define swap(a, b) { \ 13 | __typeof(a) __temp = a; \ 14 | a = b, b = __temp; \ 15 | } 16 | 17 | void downUpdate(int *arr, int n, int ind) { 18 | while ((ind << 1) <= n) { 19 | int temp = ind, l = ind << 1, r = ind << 1 | 1; 20 | if (arr[l] > arr[temp]) temp = l; 21 | if (r <= n && arr[r] > arr[temp]) temp = r; 22 | if (temp == ind) break; 23 | swap(arr[temp], arr[ind]); 24 | ind = temp; 25 | } 26 | return ; 27 | } 28 | 29 | void heap_sort(int *arr, int n) { 30 | arr -= 1; 31 | for (int i = n >> 1; i >= 1; --i) { 32 | downUpdate(arr, n, i); 33 | } 34 | for (int i = n; i > 1; --i) { 35 | swap(arr[1], arr[i]); 36 | downUpdate(arr, i - 1, 1); 37 | } 38 | return ; 39 | } 40 | 41 | void output(int *arr, int n) { 42 | printf("arr[%d] = [", n); 43 | for (int i = 0; i < n; i++) { 44 | printf(" %d", arr[i]); 45 | } 46 | printf("]\n"); 47 | return ; 48 | } 49 | 50 | int main() { 51 | srand(time(0)); 52 | #define MAX_OP 20 53 | int *arr = (int *)malloc(sizeof(int) * MAX_OP); 54 | for (int i = 0; i < MAX_OP; i++) { 55 | arr[i] = rand() % 100; 56 | } 57 | output(arr, MAX_OP); 58 | heap_sort(arr, MAX_OP); 59 | output(arr, MAX_OP); 60 | return 0; 61 | } -------------------------------------------------------------------------------- /第3章:树与二叉树/6、演示代码(三)/3、Leetcode-257.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 257.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 一 8/07 19:33:00 2019 7 | ************************************************************************/ 8 | 9 | /** 10 | * Definition for a binary tree node. 11 | * struct TreeNode { 12 | * int val; 13 | * struct TreeNode *left; 14 | * struct TreeNode *right; 15 | * }; 16 | */ 17 | 18 | 19 | /** 20 | * Note: The returned array must be malloced, assume caller calls free(). 21 | */ 22 | 23 | #include 24 | 25 | int getPathCnt(struct TreeNode *root) { 26 | if (root == NULL) return 0; 27 | if (root->left == NULL && root->right == NULL) return 1; 28 | return getPathCnt(root->left) + getPathCnt(root->right); 29 | } 30 | 31 | int getResult(struct TreeNode *root, int len, int k, char **ret, char *buff) { 32 | if (root == NULL) return 0; 33 | len += sprintf(buff + len, "%d", root->val); 34 | buff[len] = 0; 35 | if (root->left == NULL && root->right == NULL) { 36 | ret[k] = strdup(buff); 37 | return 1; 38 | } 39 | len += sprintf(buff + len, "->"); 40 | int cnt = getResult(root->left, len, k, ret, buff); 41 | cnt += getResult(root->right, len, k + cnt, ret, buff); 42 | return cnt; 43 | } 44 | 45 | char ** binaryTreePaths(struct TreeNode* root, int* returnSize){ 46 | int pathCnt = getPathCnt(root); 47 | char **ret = (char **)malloc(sizeof(char *) * pathCnt); 48 | int max_len = 10000; 49 | char *buff = (char *)malloc(sizeof(char) * max_len); 50 | getResult(root, 0, 0, ret, buff); 51 | free(buff); 52 | *returnSize = pathCnt; 53 | return ret; 54 | } -------------------------------------------------------------------------------- /第5章:排序与查找/8、演示代码(四)/4、HZOJ-242-最大平均值.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 242.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 四 5/23 20:21:52 2019 7 | ************************************************************************/ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | using namespace std; 18 | #define MAX_N 100000 19 | int arr[MAX_N + 5]; 20 | 21 | int check(int *arr, int n, int m, int a) { 22 | long long sj = 0, si = 0, pre_min = 0; 23 | for (int i = 0; i < m; i++) { 24 | sj += arr[i] - a; 25 | } 26 | if (sj >= 0) return 1; 27 | for (int i = m; i < n; i++) { 28 | si += arr[i - m] - a; 29 | pre_min = min(pre_min, si); 30 | sj += arr[i] - a; 31 | if (sj >= pre_min) return 1; 32 | } 33 | return 0; 34 | } 35 | 36 | int binary_search(int *arr, int n, int m, int l, int r) { 37 | if (l == r) return l; 38 | int mid = (l + r + 1) >> 1; 39 | if (check(arr, n, m, mid)) return binary_search(arr, n, m, mid, r); 40 | return binary_search(arr, n, m, l, mid - 1); 41 | } 42 | 43 | int main() { 44 | int n, m, min_num, max_num; 45 | cin >> n >> m; 46 | for (int i = 0; i < n; i++) { 47 | cin >> arr[i]; 48 | arr[i] *= 1000; 49 | if (i == 0) { 50 | min_num = max_num = arr[i]; 51 | } else { 52 | if (min_num > arr[i]) min_num = arr[i]; 53 | else if (max_num < arr[i]) max_num = arr[i]; 54 | } 55 | } 56 | cout << binary_search(arr, n, m, min_num, max_num) << endl; 57 | return 0; 58 | } -------------------------------------------------------------------------------- /第9章:递归函数转非递归函数/1、【程序演示】存储任意类型的栈.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | > File Name: 15.any_stack.h 3 | > Author: hug 4 | > Mail: hug@haizeix.com 5 | > Created Time: 三 2/28 10:49:10 2018 6 | ************************************************************************/ 7 | 8 | #ifndef _15_ANY_STACK_H 9 | #define _15_ANY_STACK_H 10 | 11 | #include 12 | #include 13 | 14 | #define STACK_OK 1 15 | #define STACK_ERROR 0 16 | 17 | typedef struct Stack { 18 | char *data; 19 | int data_size; 20 | int size, top; 21 | } Stack; 22 | 23 | #define init_stack(n, T) (__init_stack(n, sizeof(T))) 24 | #define push_stack(s, data) (__push_stack(s, (char *)(data))) 25 | #define top_stack(s, T) ((T *)(__top_stack(s))) 26 | 27 | Stack *__init_stack(int n, int data_size) { 28 | Stack *s = (Stack *)malloc(sizeof(Stack) * 1); 29 | s->data = (char *)malloc(n * data_size); 30 | s->data_size = data_size; 31 | s->size = n; 32 | s->top = -1; 33 | return s; 34 | } 35 | 36 | int __push_stack(Stack *s, char *data) { 37 | if (s->size - 1 == s->top) { 38 | return STACK_ERROR; 39 | } 40 | s->top += 1; 41 | memcpy(s->data + s->top * s->data_size, data, s->data_size); 42 | return STACK_OK; 43 | } 44 | 45 | int empty_stack(Stack *s) { 46 | return s->top == -1; 47 | } 48 | 49 | char *__top_stack(Stack *s) { 50 | if (empty_stack(s)) { 51 | return NULL; 52 | } 53 | return s->data + s->top * s->data_size; 54 | } 55 | 56 | int pop_stack(Stack *s) { 57 | if (empty_stack(s)) { 58 | return STACK_ERROR; 59 | } 60 | s->top -= 1; 61 | return STACK_OK; 62 | } 63 | 64 | void clear_stack(Stack *s) { 65 | free(s->data); 66 | free(s); 67 | return ; 68 | } 69 | 70 | #endif -------------------------------------------------------------------------------- /第10章:森林与并查集/4、演示代码(一)/2、HZOJ-73-湖泊.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 73.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 四 8/22 14:19:28 2019 7 | ************************************************************************/ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | using namespace std; 18 | #define MAX_N 1000 19 | #define MAX_M 1000000 20 | #define ind(i, j) ((i) * (m) + (j) + 1) 21 | char g[MAX_N + 5][MAX_N + 5]; 22 | 23 | struct UnionSet { 24 | int fa[MAX_M + 5]; 25 | void init(int n) { 26 | for (int i = 0; i <= n; i++) fa[i] = i; 27 | } 28 | int get(int x) { 29 | return (fa[x] = (x - fa[x] ? get(fa[x]) : x)); 30 | } 31 | void merge(int a, int b) { 32 | fa[get(a)] = get(b); 33 | } 34 | }; 35 | 36 | UnionSet u; 37 | 38 | int main() { 39 | int n, m; 40 | cin >> n >> m; 41 | u.init(n * m); 42 | for (int i = 0; i < n; i++) { 43 | cin >> g[i]; 44 | for (int j = 0; j < m; j++) { 45 | if (g[i][j] == 'X') continue; 46 | if (i && g[i - 1][j] == 'O') u.merge(ind(i, j), ind(i - 1, j)); 47 | if (j && g[i][j - 1] == 'O') u.merge(ind(i, j), ind(i, j - 1)); 48 | if (i == 0 || i == n - 1) u.merge(ind(i, j), 0); 49 | if (j == 0 || j == m - 1) u.merge(ind(i, j), 0); 50 | } 51 | } 52 | int ans = 0; 53 | for (int i = 0; i < n; i++) { 54 | for (int j = 0; j < m; j++) { 55 | if (g[i][j] == 'X') continue; 56 | if (u.get(ind(i, j)) - u.get(0)) ans += 1; 57 | } 58 | } 59 | cout << ans << endl; 60 | return 0; 61 | } -------------------------------------------------------------------------------- /第10章:森林与并查集/6、演示代码(三)/1、HZOJ-324-银河英雄传说.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 324.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 四 8/22 18:49:39 2019 7 | ************************************************************************/ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | using namespace std; 18 | #define MAX_N 500000 19 | 20 | struct UnionSet { 21 | int fa[MAX_N + 5], val[MAX_N + 5], size[MAX_N + 5]; 22 | void init(int n) { 23 | for (int i = 1; i <= n; i++) { 24 | fa[i] = i; 25 | val[i] = 0; 26 | size[i] = 1; 27 | } 28 | return ; 29 | } 30 | int get(int x) { 31 | if (x == fa[x]) return x; 32 | int root = get(fa[x]); 33 | val[x] += val[fa[x]]; 34 | return fa[x] = root; 35 | } 36 | void merge(int a, int b) { 37 | int aa = get(a), bb = get(b); 38 | if (aa == bb) return ; 39 | fa[aa] = bb; 40 | val[aa] = size[bb]; 41 | size[bb] += size[aa]; 42 | return ; 43 | } 44 | }; 45 | 46 | UnionSet u; 47 | 48 | int main() { 49 | int n; 50 | scanf("%d", &n); 51 | u.init(n); 52 | char str[10]; 53 | for (int i = 0; i < n; i++) { 54 | int a, b; 55 | scanf("%s%d%d", str, &a, &b); 56 | switch (str[0]) { 57 | case 'M': u.merge(a, b); break; 58 | case 'C': { 59 | if (u.get(a) - u.get(b)) { 60 | printf("-1\n"); 61 | } else { 62 | printf("%d\n", abs(u.val[a] - u.val[b]) - 1); 63 | } 64 | } break; 65 | } 66 | } 67 | return 0; 68 | } -------------------------------------------------------------------------------- /第10章:森林与并查集/7、演示代码(四)/1、Leetcode-200.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 200.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 四 5/23 19:08:07 2019 7 | ************************************************************************/ 8 | 9 | #define MC(T, n) (T *)malloc(sizeof(T) * (n)) 10 | #define CC(T, n) (T *)calloc(sizeof(T), (n)) 11 | 12 | typedef struct UnionSet { 13 | int *fa; 14 | int n; 15 | } UnionSet; 16 | 17 | UnionSet *init(int n) { 18 | UnionSet *u = MC(UnionSet, 1); 19 | u->fa = MC(int, n + 1); 20 | u->n = n; 21 | for (int i = 1; i <= n; i++) u->fa[i] = i; 22 | return u; 23 | } 24 | 25 | void clear(UnionSet *u) { 26 | if (u == NULL) return ; 27 | free(u->fa); 28 | free(u); 29 | return ; 30 | } 31 | 32 | int get(UnionSet *u, int x) { 33 | if (u->fa[x] == x) return x; 34 | return u->fa[x] = get(u, u->fa[x]); 35 | } 36 | 37 | void merge(UnionSet *u, int a, int b) { 38 | u->fa[get(u, a)] = get(u, b); 39 | } 40 | 41 | int numIslands(char** grid, int n, int *M) { 42 | if (n == 0) return 0; 43 | int m = M[0]; 44 | #define ind(i, j) ((i) * (m) + (j) + 1) 45 | UnionSet *u = init(n * m); 46 | for (int i = 0; i < n; i++) { 47 | for (int j = 0; j < m; j++) { 48 | if (grid[i][j] == '0') continue; 49 | if (i - 1 >= 0 && grid[i - 1][j] == '1') 50 | merge(u, ind(i, j), ind(i - 1, j)); 51 | if (j - 1 >= 0 && grid[i][j - 1] == '1') 52 | merge(u, ind(i, j), ind(i, j - 1)); 53 | } 54 | } 55 | int ans = 0; 56 | for (int i = 0; i < n; i++) { 57 | for (int j = 0; j < m; j++) { 58 | if (grid[i][j] == '0') continue; 59 | ans += (get(u, ind(i, j)) == ind(i, j)); 60 | } 61 | } 62 | clear(u); 63 | return ans; 64 | } -------------------------------------------------------------------------------- /第10章:森林与并查集/2、Quick-Union 及优化代码演示/1、Quick-Union.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 13.UnionSet.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 二 5/21 19:26:12 2019 7 | ************************************************************************/ 8 | 9 | #include 10 | #include 11 | #define swap(a, b) { \ 12 | __typeof(a) __temp = a; \ 13 | a = b, b = __temp; \ 14 | } 15 | 16 | typedef struct UnionSet { 17 | int *father, *size; 18 | int n; 19 | } UnionSet; 20 | 21 | UnionSet *init(int n) { 22 | UnionSet *u = (UnionSet *)malloc(sizeof(UnionSet)); 23 | u->father = (int *)malloc(sizeof(int) * (n + 1)); 24 | u->size = (int *)malloc(sizeof(int) * (n + 1)); 25 | u->n = n; 26 | for (int i = 1; i <= n; i++) { 27 | u->father[i] = i; 28 | u->size[i] = 1; 29 | } 30 | return u; 31 | } 32 | 33 | int find(UnionSet *u, int x) { 34 | return u->father[x] = (u->father[x] == x ? x : find(u, u->father[x])); 35 | } 36 | 37 | int merge(UnionSet *u, int a, int b) { 38 | int fa = find(u, a), fb = find(u, b); 39 | if (fa == fb) return 0; 40 | if (u->size[fa] > u->size[fb]) swap(fa, fb); 41 | u->father[fa] = fb; 42 | u->size[fb] += u->size[fa]; 43 | return 1; 44 | } 45 | 46 | void clear(UnionSet *u) { 47 | if (u == NULL) return ; 48 | free(u->father); 49 | free(u->size); 50 | free(u); 51 | return ; 52 | } 53 | 54 | int main() { 55 | int n, m; 56 | scanf("%d%d", &n, &m); 57 | UnionSet *u = init(n); 58 | for (int i = 0; i < m; i++) { 59 | int a, b, c; 60 | scanf("%d%d%d", &a, &b, &c); 61 | switch (a) { 62 | case 1: merge(u, b, c); break; 63 | case 2: printf("%s\n", find(u, b) == find(u, c) ? "Yes" : "No"); break; 64 | } 65 | } 66 | clear(u); 67 | return 0; 68 | } -------------------------------------------------------------------------------- /第3章:树与二叉树/4、演示代码(一)/3、Leetcode-102.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 102.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 一 8/07 19:33:00 2019 7 | ************************************************************************/ 8 | 9 | /** 10 | * Definition for a binary tree node. 11 | * struct TreeNode { 12 | * int val; 13 | * struct TreeNode *left; 14 | * struct TreeNode *right; 15 | * }; 16 | */ 17 | /** 18 | * Return an array of arrays of size *returnSize. 19 | * The sizes of the arrays are returned as *columnSizes array. 20 | * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free(). 21 | */ 22 | 23 | 24 | int getDepth(struct TreeNode *root) { 25 | if (root == NULL) return 0; 26 | int l = getDepth(root->left), r = getDepth(root->right); 27 | return (l > r ? l : r) + 1; 28 | } 29 | 30 | void getCnt(struct TreeNode *root, int k, int *cnt) { 31 | if (root == NULL) return ; 32 | cnt[k] += 1; 33 | getCnt(root->left, k + 1, cnt); 34 | getCnt(root->right, k + 1, cnt); 35 | return ; 36 | } 37 | 38 | void getResult(struct TreeNode *root, int k, int *cnt, int **ret) { 39 | if (root == NULL) return ; 40 | ret[k][cnt[k]++] = root->val; 41 | getResult(root->left, k + 1, cnt, ret); 42 | getResult(root->right, k + 1, cnt, ret); 43 | return ; 44 | } 45 | 46 | int** levelOrder(struct TreeNode* root, int* returnSize, int** columnSizes) { 47 | int depth = getDepth(root); 48 | int *cnt = (int *)calloc(sizeof(int), depth); 49 | int **ret = (int **)malloc(sizeof(int *) * depth); 50 | getCnt(root, 0, cnt); 51 | for (int i = 0; i < depth; i++) { 52 | ret[i] = (int *)malloc(sizeof(int) * cnt[i]); 53 | cnt[i] = 0; 54 | } 55 | getResult(root, 0, cnt, ret); 56 | *returnSize = depth; 57 | *columnSizes = cnt; 58 | return ret; 59 | } -------------------------------------------------------------------------------- /第10章:森林与并查集/4、演示代码(一)/1、HZOJ-72-猜拳.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 72.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 三 8/21 20:47:24 2019 7 | ************************************************************************/ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | using namespace std; 18 | #define MAX_N 10000 19 | 20 | struct UnionSet { 21 | int fa[MAX_N + 5], val[MAX_N + 5]; 22 | void init(int n) { 23 | for (int i = 1; i <= n; i++) fa[i] = i; 24 | } 25 | int get(int x) { 26 | if (x == fa[x]) return x; 27 | int root = get(fa[x]); 28 | val[x] += val[fa[x]]; 29 | val[x] %= 3; 30 | return fa[x] = root; 31 | } 32 | void merge(int a, int b, int c) { 33 | int aa = get(a), bb = get(b); 34 | if (aa == bb) return ; 35 | fa[aa] = bb; 36 | val[aa] = (c + val[b] - val[a] + 3) % 3; 37 | return ; 38 | } 39 | }; 40 | 41 | UnionSet u; 42 | 43 | void read(int &n, int &m) { 44 | cin >> n >> m; 45 | u.init(n); 46 | return ; 47 | } 48 | 49 | int main() { 50 | int n, m; 51 | read(n, m); 52 | for (int i = 0; i < m; i++) { 53 | int a, b, c; 54 | cin >> a >> b >> c; 55 | if (a == 1) { 56 | u.merge(b, c, 2); 57 | } else { 58 | if (u.get(b) != u.get(c)) { 59 | cout << "Unknown" << endl; 60 | } else { 61 | switch ((u.val[b] - u.val[c] + 3) % 3) { 62 | case 0: cout << "Tie" << endl; break; 63 | case 1: cout << "Loss" << endl; break; 64 | case 2: cout << "Win" << endl; break; 65 | } 66 | } 67 | } 68 | } 69 | return 0; 70 | } -------------------------------------------------------------------------------- /第10章:森林与并查集/5、演示代码(二)/1、HZOJ-322-程序自动分析.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 322.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 四 8/22 14:54:15 2019 7 | ************************************************************************/ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | using namespace std; 18 | #define MAX_N 1000000 19 | map ind; 20 | int cnt = 0; 21 | 22 | struct Data { 23 | int i, j, e; 24 | } arr[MAX_N + 5]; 25 | 26 | struct UnionSet { 27 | int fa[(MAX_N << 1) + 5]; 28 | void init(int n) { 29 | for (int i = 1; i <= n; i++) fa[i] = i; 30 | } 31 | int get(int x) { 32 | return (fa[x] = (x == fa[x] ? x : get(fa[x]))); 33 | } 34 | void merge(int a, int b) { 35 | fa[get(a)] = get(b); 36 | } 37 | }; 38 | 39 | UnionSet u; 40 | 41 | int solve() { 42 | int n; 43 | cnt = 0, ind.clear(); 44 | cin >> n; 45 | for (int i = 0; i < n; i++) { 46 | cin >> arr[i].i >> arr[i].j >> arr[i].e; 47 | if (ind.find(arr[i].i) == ind.end()) ind[arr[i].i] = (++cnt); 48 | if (ind.find(arr[i].j) == ind.end()) ind[arr[i].j] = (++cnt); 49 | arr[i].i = ind[arr[i].i]; 50 | arr[i].j = ind[arr[i].j]; 51 | } 52 | u.init(cnt); 53 | for (int i = 0; i < n; i++) { 54 | if (arr[i].e != 1) continue; 55 | u.merge(arr[i].i, arr[i].j); 56 | } 57 | int flag = 1; 58 | for (int i = 0; i < n; i++) { 59 | if (arr[i].e == 1) continue; 60 | if (u.get(arr[i].i) != u.get(arr[i].j)) continue; 61 | flag = 0; 62 | break; 63 | } 64 | cout << (flag ? "YES" : "NO") << endl; 65 | return 0; 66 | } 67 | 68 | int main() { 69 | int t; 70 | cin >> t; 71 | while (t--) solve(); 72 | return 0; 73 | } -------------------------------------------------------------------------------- /第3章:树与二叉树/4、演示代码(一)/4、Leetcode-107.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 107.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 四 4/25 19:57:11 2019 7 | ************************************************************************/ 8 | 9 | /** 10 | * Definition for a binary tree node. 11 | * struct TreeNode { 12 | * int val; 13 | * struct TreeNode *left; 14 | * struct TreeNode *right; 15 | * }; 16 | */ 17 | /** 18 | * Return an array of arrays of size *returnSize. 19 | * The sizes of the arrays are returned as *columnSizes array. 20 | * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free(). 21 | */ 22 | 23 | 24 | 25 | int getDepth(struct TreeNode *root) { 26 | if (root == NULL) return 0; 27 | int d1 = getDepth(root->left); 28 | int d2 = getDepth(root->right); 29 | return fmax(d1, d2) + 1; 30 | } 31 | 32 | void getSize(struct TreeNode *root, int k, int *size) { 33 | if (root == NULL) return ; 34 | size[k] += 1; 35 | getSize(root->left, k - 1, size); 36 | getSize(root->right, k - 1, size); 37 | return ; 38 | } 39 | 40 | void getData(struct TreeNode *root, int **ret, int *size, int k) { 41 | if (root == NULL) return ; 42 | ret[k][size[k]++] = root->val; 43 | getData(root->left, ret, size, k - 1); 44 | getData(root->right, ret, size, k - 1); 45 | return ; 46 | } 47 | 48 | int** levelOrderBottom(struct TreeNode* root, int** columnSizes, int* returnSize) { 49 | if (root == NULL) return NULL; 50 | int n = getDepth(root); 51 | int **ret = (int **)malloc(sizeof(int *) * n); 52 | int *size = (int *)calloc(sizeof(int), n); 53 | getSize(root, n - 1, size); 54 | for (int i = 0; i < n; i++) { 55 | ret[i] = (int *)malloc(sizeof(int) * size[i]); 56 | size[i] = 0; 57 | } 58 | getData(root, ret, size, n - 1); 59 | *returnSize = n; 60 | *columnSizes = size; 61 | return ret; 62 | } -------------------------------------------------------------------------------- /第5章:排序与查找/5、演示代码(一)/1、Leetcode-1-1.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 1-1.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 四 5/ 9 19:59:26 2019 7 | ************************************************************************/ 8 | 9 | /** 10 | * Note: The returned array must be malloced, assume caller calls free(). 11 | */ 12 | 13 | void radix_sort(int *arr, int *main_ind, int n) { 14 | #define MAX_N 65536 15 | #define MAX_M 32768 16 | #define L(x) (x & 0xffff) 17 | #define H(x) ((x >> 16) & 0xffff) 18 | int cnt[MAX_N] = {0}, *p; 19 | int *temp = (int *)malloc(sizeof(int) * n); 20 | int *ind = (int *)malloc(sizeof(int) * n); 21 | for (int i = 0; i < n; i++) cnt[L(arr[i])] += 1; 22 | for (int i = 1 ; i < MAX_N; i++) cnt[i] += cnt[i - 1]; 23 | for (int i = n - 1; i >= 0; i--) { 24 | temp[--(cnt[L(arr[i])])] = arr[i]; 25 | ind[cnt[L(arr[i])]] = i; 26 | } 27 | memset(cnt, 0, sizeof(cnt)); 28 | for (int i = 0; i < n; i++) cnt[H(temp[i])] += 1; 29 | for (int i = MAX_M; i < MAX_M + MAX_N; i++) cnt[i % MAX_N] += cnt[(i - 1) % MAX_N]; 30 | for (int i = n - 1; i >= 0; i--) { 31 | arr[--(cnt[H(temp[i])])] = temp[i]; 32 | main_ind[cnt[H(temp[i])]] = ind[i]; 33 | } 34 | free(temp); 35 | free(ind); 36 | return ; 37 | } 38 | 39 | int* twoSum(int* nums, int numsSize, int target, int *returnSize) { 40 | int *ind = (int *)malloc(sizeof(int) * numsSize); 41 | radix_sort(nums, ind, numsSize); 42 | int p = 0, q = numsSize - 1; 43 | while (nums[p] + nums[q] != target) { 44 | if (nums[p] + nums[q] > target) --q; 45 | else ++p; 46 | } 47 | int *ret = (int *)malloc(sizeof(int) * 2); 48 | ret[0] = ind[p]; 49 | ret[1] = ind[q]; 50 | if (ret[0] > ret[1]) { 51 | ret[0] ^= ret[1], ret[1] ^= ret[0], ret[0] ^= ret[1]; 52 | } 53 | free(ind); 54 | returnSize[0] = 2; 55 | return ret; 56 | } -------------------------------------------------------------------------------- /第2章:栈和队列/1、栈和队列/2、Stack.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 4.stack.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 三 7/17 14:42:20 2019 7 | ************************************************************************/ 8 | #include 9 | #include 10 | #include 11 | 12 | typedef struct Stack { 13 | int *data; 14 | int top, size; 15 | } Stack; 16 | 17 | Stack *init(int n) { 18 | Stack *s = (Stack *)malloc(sizeof(Stack)); 19 | s->data = (int *)malloc(sizeof(int) * n); 20 | s->size = n; 21 | s->top = -1; 22 | return s; 23 | } 24 | 25 | int empty(Stack *s) { 26 | return s->top == -1; 27 | } 28 | 29 | int top(Stack *s) { 30 | if (empty(s)) return 0; 31 | return s->data[s->top]; 32 | } 33 | 34 | int push(Stack *s, int val) { 35 | if (s == NULL) return 0; 36 | if (s->top + 1 == s->size) return 0; 37 | s->top += 1; 38 | s->data[s->top] = val; 39 | return 1; 40 | } 41 | 42 | int pop(Stack *s) { 43 | if (s == NULL) return 0; 44 | if (empty(s)) return 0; 45 | s->top -= 1; 46 | return 1; 47 | } 48 | 49 | void clear(Stack *s) { 50 | if (s == NULL) return ; 51 | free(s->data); 52 | free(s); 53 | return ; 54 | } 55 | 56 | void output(Stack *s) { 57 | printf("stack(%d) = [", s->top + 1); 58 | for (int i = s->top; i >= 0; i--) { 59 | printf(" %d", s->data[i]); 60 | } 61 | printf("]\n"); 62 | return ; 63 | } 64 | 65 | int main() { 66 | srand(time(0)); 67 | #define MAX_OP 20 68 | Stack *s = init(MAX_OP); 69 | for (int i = 0; i < MAX_OP; i++) { 70 | int op = rand() % 2, val = rand() % 100; 71 | switch (op) { 72 | case 0: { 73 | printf("push %d to stack = %d\n", val, push(s, val)); 74 | } break; 75 | case 1: { 76 | printf("pop %d from stack = %d\n", top(s), pop(s)); 77 | } 78 | } 79 | output(s); 80 | } 81 | return 0; 82 | } -------------------------------------------------------------------------------- /第5章:排序与查找/7、演示代码(三)/1、Leetcode-217.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 217.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 六 5/11 15:26:13 2019 7 | ************************************************************************/ 8 | 9 | typedef struct HashTable { 10 | int *data; 11 | int *flag; 12 | int size; 13 | } HashTable; 14 | 15 | HashTable *init(int n) { 16 | HashTable *h = (HashTable *)malloc(sizeof(HashTable)); 17 | h->data = (int *)malloc(sizeof(int) * n); 18 | h->flag = (int *)calloc(sizeof(int), (n / 31 + 1)); 19 | h->size = n; 20 | return h; 21 | } 22 | 23 | int hash(int val) { 24 | return val & 0x7fffffff; 25 | } 26 | 27 | int check(HashTable *h, int ind) { 28 | int x = ind / 31, y = ind % 31; 29 | return h->flag[x] & (1 << y); 30 | } 31 | 32 | void set(HashTable *h, int ind, int val) { 33 | int x = ind / 31, y = ind % 31; 34 | h->flag[x] |= (1 << y); 35 | h->data[ind] = val; 36 | return ; 37 | } 38 | 39 | void insert(HashTable *h, int val) { 40 | int ind = hash(val) % h->size; 41 | int times = 1; 42 | while (check(h, ind)) { 43 | ind += (times * times); 44 | ind %= h->size; 45 | } 46 | set(h, ind, val); 47 | return ; 48 | } 49 | 50 | int query(HashTable *h, int val) { 51 | int ind = hash(val) % h->size; 52 | int times = 1; 53 | while (check(h, ind) && h->data[ind] != val) { 54 | ind += (times * times); 55 | ind %= h->size; 56 | } 57 | return check(h, ind); 58 | } 59 | 60 | void clear(HashTable *h) { 61 | if (h == NULL) return ; 62 | free(h->data); 63 | free(h->flag); 64 | free(h); 65 | return ; 66 | } 67 | 68 | bool containsDuplicate(int* nums, int numsSize){ 69 | HashTable *h = init(numsSize * 3); 70 | for (int i = 0; i < numsSize; i++) { 71 | if (query(h, nums[i])) { 72 | clear(h); 73 | return true; 74 | } 75 | insert(h, nums[i]); 76 | } 77 | clear(h); 78 | return false; 79 | } -------------------------------------------------------------------------------- /第5章:排序与查找/2、非稳定排序/1、unstable_sort.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 12.unstable_sort.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 日 11/ 4 20:35:49 2018 7 | ************************************************************************/ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #define swap(a, b) { \ 15 | __typeof(a) _temp = a; a = b; b = _temp; \ 16 | } 17 | 18 | #define TEST(arr, n, func, args...) { \ 19 | int *num = (int *)malloc(sizeof(int) * n); \ 20 | memcpy(num, arr, sizeof(int) * n); \ 21 | output(num, n); \ 22 | printf("%s = ", #func); \ 23 | func(args); \ 24 | output(num, n); \ 25 | free(num); \ 26 | } 27 | 28 | void select_sort(int *num, int n) { 29 | for (int i = 0; i < n - 1; i++) { 30 | int ind = i; 31 | for (int j = i + 1; j < n; j++) { 32 | if (num[ind] > num[j]) ind = j; 33 | } 34 | swap(num[i], num[ind]); 35 | } 36 | return ; 37 | } 38 | 39 | void quick_sort(int *num, int l, int r) { 40 | if (r <= l) return ; 41 | int x = l, y = r, z = num[l]; 42 | while (x < y) { 43 | while (x < y && num[y] >= z) --y; 44 | if (x < y) num[x++] = num[y]; 45 | while (x < y && num[x] <= z) ++x; 46 | if (x < y) num[y--] = num[x]; 47 | } 48 | num[x] = z; 49 | quick_sort(num, l, x - 1); 50 | quick_sort(num, x + 1, r); 51 | return ; 52 | } 53 | 54 | void randint(int *num, int n) { 55 | while (n--) num[n] = rand() % 100; 56 | return ; 57 | } 58 | 59 | void output(int *num, int n) { 60 | printf("["); 61 | for (int i = 0; i < n; i++) { 62 | printf(" %d", num[i]); 63 | } 64 | printf("]\n"); 65 | return ; 66 | } 67 | 68 | int main() { 69 | srand(time(0)); 70 | #define MAX_OP 20 71 | int arr[MAX_OP]; 72 | randint(arr, MAX_OP); 73 | TEST(arr, MAX_OP, select_sort, num, MAX_OP); 74 | TEST(arr, MAX_OP, quick_sort, num, 0, MAX_OP - 1); 75 | return 0; 76 | } -------------------------------------------------------------------------------- /第5章:排序与查找/8、演示代码(四)/5、HZOJ-243-秦腾与教学评估.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 243.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 四 5/23 20:59:38 2019 7 | ************************************************************************/ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | using namespace std; 18 | #define MAX_N 200000 19 | struct Node { 20 | long long s, e, d, num; 21 | } arr[MAX_N + 5]; 22 | 23 | long long check(Node *arr, int n, long long pos) { 24 | long long cnt = 0; 25 | for (int i = 0; i < n; i++) { 26 | if (arr[i].e <= pos) cnt += arr[i].num; 27 | else if (arr[i].s > pos) continue; 28 | else cnt += (pos - arr[i].s) / arr[i].d + 1; 29 | } 30 | return cnt; 31 | } 32 | 33 | long long binary_search(Node *arr, int n, long long l, long long r) { 34 | if (l == r) return l; 35 | long long mid = (l + r) >> 1; 36 | if (check(arr, n, mid) % 2) return binary_search(arr, n, l, mid); 37 | return binary_search(arr, n, mid + 1, r); 38 | } 39 | 40 | 41 | void solve() { 42 | long long n, min_num, max_num; 43 | scanf("%lld", &n); 44 | for (int i = 0; i < n; i++) { 45 | scanf("%lld%lld%lld", &arr[i].s, &arr[i].e, &arr[i].d); 46 | arr[i].num = (arr[i].e - arr[i].s) / arr[i].d + 1; 47 | if (i == 0) { 48 | min_num = arr[i].s; 49 | max_num = arr[i].e; 50 | } else { 51 | if (arr[i].s < min_num) min_num = arr[i].s; 52 | if (arr[i].e > max_num) max_num = arr[i].e; 53 | } 54 | } 55 | long long pos = binary_search(arr, n, min_num, max_num); 56 | if (check(arr, n, pos) % 2) { 57 | printf("%lld %lld\n", pos, check(arr, n, pos) - check(arr, n, pos - 1)); 58 | } else { 59 | cout << "Poor QIN Teng:(" << endl; 60 | } 61 | return ; 62 | } 63 | 64 | int main() { 65 | int t; 66 | scanf("%d", &t); 67 | while (t--) solve(); 68 | return 0; 69 | } -------------------------------------------------------------------------------- /第7章:字符串匹配算法(2)/1、字典树/1、Trie.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 11.trie.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 一 8/19 19:11:36 2019 7 | ************************************************************************/ 8 | 9 | #include 10 | #include 11 | 12 | #define BASE 26 13 | #define BASE_LETTER 'a' 14 | 15 | typedef struct Node { 16 | int flag; 17 | struct Node *next[BASE]; 18 | } Node; 19 | 20 | Node *getNewNode() { 21 | Node *p = (Node *)calloc(sizeof(Node), 1); 22 | return p; 23 | } 24 | 25 | inline int code(char ch) { 26 | return ch - BASE_LETTER; 27 | } 28 | 29 | void insert(Node *root, char *str) { 30 | Node *p = root; 31 | for (int i = 0; str[i]; i++) { 32 | if (p->next[code(str[i])] == NULL) p->next[code(str[i])] = getNewNode(); 33 | p = p->next[code(str[i])]; 34 | } 35 | p->flag = 1; 36 | return ; 37 | } 38 | 39 | int query(Node *root, char *str) { 40 | Node *p = root; 41 | for (int i = 0; str[i]; i++) { 42 | p = p->next[code(str[i])]; 43 | if (p == NULL) return 0; 44 | } 45 | return p->flag; 46 | } 47 | 48 | void output(Node *root, int k, char *buff) { 49 | if (root == NULL) return ; 50 | if (root->flag) printf("%s\n", buff); 51 | for (int i = 0; i < BASE; i++) { 52 | buff[k] = BASE_LETTER + i; 53 | buff[k + 1] = '\0'; 54 | output(root->next[i], k + 1, buff); 55 | } 56 | return ; 57 | } 58 | 59 | void clear(Node *root) { 60 | if (root == NULL) return ; 61 | for (int i = 0; i < BASE; i++) { 62 | clear(root->next[i]); 63 | } 64 | free(root); 65 | return ; 66 | } 67 | 68 | int main() { 69 | char str[1000]; 70 | int n; 71 | Node *root = getNewNode(); 72 | scanf("%d", &n); 73 | for (int i = 0; i < n; i++) { 74 | scanf("%s", str); 75 | insert(root, str); 76 | } 77 | output(root, 0, str); 78 | while (~scanf("%s", str)) { 79 | printf("query %s, result = %s\n", str, query(root, str) ? "Yes" : "No"); 80 | } 81 | return 0; 82 | } -------------------------------------------------------------------------------- /第11章:树状数组与线段树/2、线段树结构基础/1、HZOJ-222-线段树模板(一).cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 222.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 六 8/24 19:29:40 2019 7 | ************************************************************************/ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | using namespace std; 18 | #define MAX_N 10000 19 | #define lc(ind) (ind << 1) 20 | #define rc(ind) (ind << 1 | 1) 21 | 22 | struct node { 23 | int sum; 24 | } tree[(MAX_N << 2) + 5]; 25 | int root = 1; 26 | int arr[MAX_N + 5]; 27 | 28 | void UP(int ind) { 29 | tree[ind].sum = max(tree[lc(ind)].sum, tree[rc(ind)].sum); 30 | return ; 31 | } 32 | 33 | void build(int ind, int l, int r) { 34 | if (l == r) { 35 | tree[ind].sum = arr[l]; 36 | return ; 37 | } 38 | int mid = (l + r) >> 1; 39 | build(lc(ind), l, mid); 40 | build(rc(ind), mid + 1, r); 41 | UP(ind); 42 | return ; 43 | } 44 | 45 | void modify(int ind, int x, int y, int l, int r) { 46 | if (l == r) { 47 | tree[ind].sum = y; 48 | return ; 49 | } 50 | int mid = (l + r) >> 1; 51 | if (x <= mid) modify(lc(ind), x, y, l, mid); 52 | else modify(rc(ind), x, y, mid + 1, r); 53 | UP(ind); 54 | return ; 55 | } 56 | 57 | int query(int ind, int x, int y, int l, int r) { 58 | if (x <= l && r <= y) { 59 | return tree[ind].sum; 60 | } 61 | int ans = 0x80000000, mid = (l + r) >> 1; 62 | if (x <= mid) ans = max(ans, query(lc(ind), x, y, l, mid)); 63 | if (y > mid) ans = max(ans, query(rc(ind), x, y, mid + 1, r)); 64 | return ans; 65 | } 66 | 67 | int main() { 68 | int n, m; 69 | cin >> n >> m; 70 | for (int i = 1; i <= n; i++) cin >> arr[i]; 71 | build(root, 1, n); 72 | for (int i = 0; i < m; i++) { 73 | int a, b, c; 74 | cin >> a >> b >> c; 75 | if (a == 1) modify(root, b, c, 1, n); 76 | else { 77 | cout << query(root, b, c, 1, n) << endl; 78 | } 79 | } 80 | return 0; 81 | } -------------------------------------------------------------------------------- /第4章:堆与优先队列/3、演示代码(一)/5、Leetcode-313.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 313.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 二 5/ 7 19:56:43 2019 7 | ************************************************************************/ 8 | #define swap(a, b) { \ 9 | __typeof(a) __temp = a; \ 10 | a = b, b = __temp; \ 11 | } 12 | 13 | typedef struct Heap { 14 | long long *data; 15 | int n, size; 16 | } Heap; 17 | 18 | Heap *init(int n) { 19 | Heap *h = (Heap *)malloc(sizeof(Heap)); 20 | h->n = 0; 21 | h->size = n + 1; 22 | h->data = (long long *)malloc(sizeof(long long) * h->size); 23 | return h; 24 | } 25 | 26 | int empty(Heap *h) { 27 | return h->n == 0; 28 | } 29 | 30 | #define V(x) h->data[x] 31 | 32 | void push(Heap *h, long long val) { 33 | V(++(h->n)) = val; 34 | int ind = h->n; 35 | while (ind > 1 && V(ind) < V(ind >> 1)) { 36 | swap(V(ind), V(ind >> 1)); 37 | ind >>= 1; 38 | } 39 | return ; 40 | } 41 | 42 | long long top(Heap *h) { return V(1); } 43 | 44 | void pop(Heap *h) { 45 | if (empty(h)) return ; 46 | V(1) = V((h->n)--); 47 | int ind = 1; 48 | while ((ind << 1) <= h->n) { 49 | int temp = ind, l = ind << 1, r = ind << 1 | 1; 50 | if (V(l) < V(temp)) temp = l; 51 | if (r <= h->n && V(r) < V(temp)) temp = r; 52 | if (temp == ind) break; 53 | swap(V(temp), V(ind)); 54 | ind = temp; 55 | } 56 | return ; 57 | } 58 | 59 | void clear(Heap *h) { 60 | if (h == NULL) return ; 61 | free(h->data); 62 | free(h); 63 | return ; 64 | } 65 | 66 | int nthSuperUglyNumber(int n, int* primes, int primesSize){ 67 | int k = primesSize; 68 | Heap *h = init(n * primesSize); 69 | push(h, 1); 70 | long long ans = 0; 71 | while (n--) { 72 | ans = top(h); 73 | pop(h); 74 | int i = k - 1; 75 | for (; i > 0; i--) { 76 | if (ans % primes[i]) continue; 77 | break; 78 | } 79 | for (int j = i; j < k; j++) { 80 | push(h, ans * primes[j]); 81 | } 82 | } 83 | clear(h); 84 | return ans; 85 | } -------------------------------------------------------------------------------- /第4章:堆与优先队列/3、演示代码(一)/4、Leetcode-264.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 264.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 二 5/ 7 19:18:49 2019 7 | ************************************************************************/ 8 | 9 | #define swap(a, b) { \ 10 | __typeof(a) __temp = a; \ 11 | a = b, b = __temp; \ 12 | } 13 | 14 | typedef struct Heap { 15 | long long *data; 16 | int n, size; 17 | } Heap; 18 | 19 | Heap *init(int n) { 20 | Heap *h = (Heap *)malloc(sizeof(Heap)); 21 | h->n = 0; 22 | h->size = n + 1; 23 | h->data = (long long *)malloc(sizeof(long long) * h->size); 24 | return h; 25 | } 26 | 27 | int empty(Heap *h) { 28 | return h->n == 0; 29 | } 30 | 31 | #define V(x) h->data[x] 32 | 33 | void push(Heap *h, long long val) { 34 | h->data[++(h->n)] = val; 35 | int ind = h->n; 36 | while (ind > 1 && V(ind) < V(ind >> 1)) { 37 | swap(V(ind), V(ind >> 1)); 38 | ind >>= 1; 39 | } 40 | return ; 41 | } 42 | 43 | long long top(Heap *h) { return V(1); } 44 | 45 | void pop(Heap *h) { 46 | if (empty(h)) return ; 47 | V(1) = V(h->n); 48 | (h->n)--; 49 | int ind = 1; 50 | while ((ind << 1) <= h->n) { 51 | int temp = ind, l = ind << 1, r = ind << 1 | 1; 52 | if (V(l) < V(temp)) temp = l; 53 | if (r <= h->n && V(r) < V(temp)) temp = r; 54 | if (temp == ind) break; 55 | swap(V(ind), V(temp)); 56 | ind = temp; 57 | } 58 | return ; 59 | } 60 | 61 | void clear(Heap *h) { 62 | if (h == NULL) return ; 63 | free(h->data); 64 | free(h); 65 | return ; 66 | } 67 | 68 | int nthUglyNumber(int n){ 69 | Heap *h = init(3 * n); 70 | push(h, 1); 71 | long long ans = 0; 72 | while (n--) { 73 | ans = top(h); 74 | pop(h); 75 | if (ans % 5 == 0) { 76 | push(h, 5 * ans); 77 | } else if (ans % 3 == 0) { 78 | push(h, 3 * ans); 79 | push(h, 5 * ans); 80 | } else { 81 | push(h, 2 * ans); 82 | push(h, 3 * ans); 83 | push(h, 5 * ans); 84 | } 85 | } 86 | clear(h); 87 | return ans; 88 | } -------------------------------------------------------------------------------- /第10章:森林与并查集/6、演示代码(三)/3、Leetcode-130.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 130.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 四 5/23 18:52:24 2019 7 | ************************************************************************/ 8 | 9 | typedef struct UnionSet { 10 | int *fa; 11 | int *size; 12 | int n; 13 | } UnionSet; 14 | 15 | UnionSet *init(int n) { 16 | UnionSet *u = (UnionSet *)malloc(sizeof(UnionSet)); 17 | u->fa = (int *)malloc(sizeof(int) * n); 18 | u->size = (int *)malloc(sizeof(int) * n); 19 | for (int i = 0; i < n; i++) { 20 | u->fa[i] = i; 21 | u->size[i] = 1; 22 | } 23 | u->n = n; 24 | return u; 25 | } 26 | 27 | int find(UnionSet *u, int x) { 28 | if (u->fa[x] == x) return x; 29 | return (u->fa[x] = find(u, u->fa[x])); 30 | } 31 | 32 | void merge(UnionSet *u, int a, int b) { 33 | int fa = find(u, a), fb = find(u, b); 34 | if (fa == fb) return ; 35 | if (u->size[fa] < u->size[fb]) { 36 | fa ^= fb, fb ^= fa, fa ^= fb; 37 | } 38 | u->fa[fb] = fa; 39 | u->size[fa] += u->size[fb]; 40 | return ; 41 | } 42 | 43 | void clear(UnionSet *u) { 44 | if (u == NULL) return ; 45 | free(u->fa); 46 | free(u->size); 47 | free(u); 48 | return ; 49 | } 50 | 51 | int getInd(int i, int j, int m) { 52 | return i * m + j + 1; 53 | } 54 | 55 | void solve(char** board, int n, int m) { 56 | UnionSet *u = init(n * m + 1); 57 | for (int i = 0; i < n; i++) { 58 | for (int j = 0; j < m; j++) { 59 | if (board[i][j] != 'O') continue; 60 | if (i == 0 || i == n - 1 || j == 0 || j == m - 1) { 61 | merge(u, 0, getInd(i, j, m)); 62 | } 63 | if (i - 1 >= 0 && board[i - 1][j] == 'O') { 64 | merge(u, getInd(i, j, m), getInd(i - 1, j, m)); 65 | } 66 | if (j - 1 >= 0 && board[i][j - 1] == 'O') { 67 | merge(u, getInd(i, j, m), getInd(i, j - 1, m)); 68 | } 69 | } 70 | } 71 | for (int i = 0; i < n; i++) { 72 | for (int j = 0; j < m; j++) { 73 | if (board[i][j] != 'O') continue; 74 | if (find(u, getInd(i, j, m)) != find(u, 0)) board[i][j] = 'X'; 75 | } 76 | } 77 | clear(u); 78 | return ; 79 | } -------------------------------------------------------------------------------- /第4章:堆与优先队列/1、优先队列/1、priority_queue.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 8.priority_queue.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 五 8/ 9 18:38:08 2019 7 | ************************************************************************/ 8 | 9 | #include 10 | #include 11 | #include 12 | #define swap(a, b) { \ 13 | __typeof(a) __temp = a; \ 14 | a = b, b = __temp; \ 15 | } 16 | 17 | typedef struct priority_queue { 18 | int *data; 19 | int cnt, size; 20 | } priority_queue; 21 | 22 | priority_queue *init(int n) { 23 | priority_queue *q = (priority_queue *)malloc(sizeof(priority_queue)); 24 | q->data = (int *)malloc(sizeof(int) * (n + 1)); 25 | q->cnt = 0, q->size = n; 26 | return q; 27 | } 28 | 29 | int empty(priority_queue *q) { 30 | return q->cnt == 0; 31 | } 32 | 33 | int top(priority_queue *q) { 34 | return q->data[1]; 35 | } 36 | 37 | int push(priority_queue *q, int val) { 38 | if (q->cnt == q->size) return 0; 39 | q->cnt += 1; 40 | q->data[q->cnt] = val; 41 | int ind = q->cnt; 42 | while (ind >> 1 && q->data[ind] > q->data[ind >> 1]) { 43 | swap(q->data[ind], q->data[ind >> 1]); 44 | ind >>= 1; 45 | } 46 | return 1; 47 | } 48 | 49 | int pop(priority_queue *q) { 50 | if (empty(q)) return 0; 51 | q->data[1] = q->data[q->cnt--]; 52 | int ind = 1; 53 | while ((ind << 1) <= q->cnt) { 54 | int temp = ind, l = ind << 1, r = ind << 1 | 1; 55 | if (q->data[l] > q->data[temp]) temp = l; 56 | if (r <= q->cnt && q->data[r] > q->data[temp]) temp = r; 57 | if (temp == ind) break; 58 | swap(q->data[ind], q->data[temp]); 59 | ind = temp; 60 | } 61 | return 1; 62 | } 63 | 64 | void clear(priority_queue *q) { 65 | if (q == NULL) return ; 66 | free(q->data); 67 | free(q); 68 | return ; 69 | } 70 | 71 | int main() { 72 | srand(time(0)); 73 | #define MAX_OP 20 74 | priority_queue *q = init(MAX_OP); 75 | for (int i = 0; i < MAX_OP; i++) { 76 | int val = rand() % 100; 77 | push(q, val); 78 | printf("insert %d to queue\n", val); 79 | } 80 | for (int i = 0; i < MAX_OP; i++) { 81 | printf("%d ", top(q)); 82 | pop(q); 83 | } 84 | return 0; 85 | } -------------------------------------------------------------------------------- /第13章:贪心法习题课/1、代码演示(一)/3、HZOJ-257-树的颜色.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 257.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 二 6/18 20:36:44 2019 7 | ************************************************************************/ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | using namespace std; 19 | #define MAX_N 1000 20 | 21 | struct Node { 22 | int father, head, tail; 23 | int val, cnt; 24 | }; 25 | 26 | bool operator<(const Node &a, const Node &b) { 27 | return a.val * b.cnt < a.cnt * b.val; 28 | } 29 | 30 | struct UnionSet { 31 | int fa[MAX_N + 5]; 32 | Node arr[MAX_N + 5]; 33 | int ans[MAX_N + 5]; 34 | inline void init(int n) { 35 | for (int i = 1 ; i <= n; i++) { 36 | fa[i] = i; 37 | ans[i] = 0; 38 | arr[i].father = 0; 39 | arr[i].head = arr[i].tail = i; 40 | arr[i].cnt = 1; 41 | } 42 | } 43 | int get(int x) { 44 | return (fa[x] == x ? x : get(fa[x])); 45 | } 46 | void merge(int a, int b) { 47 | int aa = get(a), bb = get(b); 48 | if (aa == bb) return ; 49 | fa[bb] = aa; 50 | ans[arr[aa].tail] = arr[bb].head; 51 | arr[aa].tail = arr[bb].tail; 52 | arr[aa].val += arr[bb].val; 53 | arr[aa].cnt += arr[bb].cnt; 54 | return ; 55 | } 56 | }; 57 | 58 | UnionSet u; 59 | priority_queue que; 60 | 61 | int val[MAX_N + 5]; 62 | 63 | int main() { 64 | int n, r; 65 | cin >> n >> r; 66 | u.init(n); 67 | for (int i = 1; i <= n; i++) { 68 | cin >> val[i]; 69 | u.arr[i].val = val[i]; 70 | que.push(u.arr[i]); 71 | } 72 | for (int i = 1; i < n; i++) { 73 | int a, b; 74 | cin >> a >> b; 75 | u.arr[b].father = a; 76 | } 77 | while (!que.empty()) { 78 | int ind = que.top().head, fa = u.arr[ind].father; 79 | que.pop(); 80 | if (fa == 0) continue; 81 | u.merge(fa, ind); 82 | que.push(u.arr[u.get(ind)]); 83 | } 84 | int p = r, t = 1, ans = 0; 85 | while (p) { 86 | ans += val[p] * t; 87 | p = u.ans[p]; 88 | t++; 89 | } 90 | cout << ans << endl; 91 | return 0; 92 | } -------------------------------------------------------------------------------- /第4章:堆与优先队列/3、演示代码(一)/1、Leetcode-703.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 703.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 五 8/ 9 20:38:12 2019 7 | ************************************************************************/ 8 | 9 | #define swap(a, b) { \ 10 | __typeof(a) __temp = a; \ 11 | a = b, b = __temp; \ 12 | } 13 | 14 | typedef struct { 15 | int *data; 16 | int cnt, size; 17 | } KthLargest; 18 | 19 | void downUpdate(int *arr, int n, int ind) { 20 | while ((ind << 1) <= n) { 21 | int temp = ind, l = ind << 1, r = ind << 1 | 1; 22 | if (arr[l] < arr[temp]) temp = l; 23 | if (r <= n && arr[r] < arr[temp]) temp = r; 24 | if (temp == ind) break; 25 | swap(arr[temp], arr[ind]); 26 | ind = temp; 27 | } 28 | return ; 29 | } 30 | 31 | void upUpdate(int *arr, int ind) { 32 | while (ind >> 1) { 33 | if (arr[ind] >= arr[ind >> 1]) break; 34 | swap(arr[ind], arr[ind >> 1]); 35 | ind >>= 1; 36 | } 37 | return ; 38 | } 39 | 40 | int kthLargestAdd(KthLargest*, int); 41 | KthLargest* kthLargestCreate(int k, int* nums, int numsSize) { 42 | KthLargest *p = (KthLargest *)malloc(sizeof(KthLargest)); 43 | p->data = (int *)malloc(sizeof(int) * (k + 1)); 44 | p->size = k; 45 | p->cnt = k - 1; 46 | memcpy(p->data + 1, nums, sizeof(int) * (k - 1)); 47 | for (int i = (k - 1) >> 1; i >= 1; --i) { 48 | downUpdate(p->data, k - 1, i); 49 | } 50 | for (int i = k - 1; i < numsSize; i++) { 51 | kthLargestAdd(p, nums[i]); 52 | } 53 | return p; 54 | } 55 | 56 | int kthLargestAdd(KthLargest* obj, int val) { 57 | if (obj->cnt == obj->size) { 58 | if (val > obj->data[1]) { 59 | obj->data[1] = val; 60 | downUpdate(obj->data, obj->size, 1); 61 | } 62 | } else { 63 | obj->cnt += 1; 64 | obj->data[obj->cnt] = val; 65 | upUpdate(obj->data, obj->cnt); 66 | } 67 | return obj->data[1]; 68 | } 69 | 70 | void kthLargestFree(KthLargest* obj) { 71 | if (obj == NULL) return ; 72 | free(obj->data); 73 | free(obj); 74 | return ; 75 | } 76 | 77 | /** 78 | * Your KthLargest struct will be instantiated and called as such: 79 | * KthLargest* obj = kthLargestCreate(k, nums, numsSize); 80 | * int param_1 = kthLargestAdd(obj, val); 81 | 82 | * kthLargestFree(obj); 83 | */ -------------------------------------------------------------------------------- /第5章:排序与查找/5、演示代码(一)/2、Leetcode-1-2.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 1-2.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 四 5/ 9 19:59:26 2019 7 | ************************************************************************/ 8 | 9 | /** 10 | * Note: The returned array must be malloced, assume caller calls free(). 11 | */ 12 | 13 | typedef struct Data { 14 | int val, ind; 15 | } Data; 16 | 17 | typedef struct HashTable { 18 | Data *data; 19 | int *flag; 20 | int size; 21 | } HashTable; 22 | 23 | HashTable *init(int n) { 24 | HashTable *h = (HashTable *)malloc(sizeof(HashTable)); 25 | h->data = (Data *)malloc(sizeof(Data) * n); 26 | h->size = n; 27 | h->flag = (int *)calloc(sizeof(int), (n / 32 + 1)); 28 | return h; 29 | } 30 | 31 | int hash(int val) { 32 | return val & 0x7fffffff; 33 | } 34 | 35 | int check(HashTable *h, int ind) { 36 | int x = ind / 32, y = ind % 32; 37 | return (h->flag[x] & (1LL << y)) != 0; 38 | } 39 | 40 | void set(HashTable *h, int ind, Data d) { 41 | int x = ind / 32, y = ind % 32; 42 | h->data[ind] = d; 43 | h->flag[x] |= (1LL << y); 44 | return ; 45 | } 46 | 47 | void insert(HashTable *h, int val, int val_ind) { 48 | Data d = {val, val_ind}; 49 | int ind = hash(val) % h->size; 50 | int time = 1; 51 | while (check(h, ind)) { 52 | ind += (time * time); 53 | ind %= h->size; 54 | } 55 | set(h, ind, d); 56 | return ; 57 | } 58 | 59 | int query(HashTable *h, int val) { 60 | int ind = hash(val) % h->size; 61 | int time = 1; 62 | while (check(h, ind) && h->data[ind].val != val) { 63 | ind += (time * time); 64 | ind %= h->size; 65 | } 66 | if (check(h, ind)) return h->data[ind].ind; 67 | return -1; 68 | } 69 | 70 | void clear(HashTable *h) { 71 | if (h == NULL) return ; 72 | free(h->data); 73 | free(h->flag); 74 | free(h); 75 | return ; 76 | } 77 | 78 | int* twoSum(int* nums, int numsSize, int target, int *returnSize) { 79 | HashTable *h = init(numsSize * 3); 80 | int *ret = (int *)malloc(sizeof(int) * 2); 81 | for (int i = 0, ind; i < numsSize; i++) { 82 | if ((ind = query(h, target - nums[i])) == -1) { 83 | insert(h, nums[i], i); 84 | continue; 85 | } 86 | ret[0] = ind; 87 | ret[1] = i; 88 | break; 89 | } 90 | returnSize[0] = 2; 91 | return ret; 92 | } -------------------------------------------------------------------------------- /第2章:栈和队列/1、栈和队列/1、Queue.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 3.queue.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 三 7/17 14:11:03 2019 7 | ************************************************************************/ 8 | #include 9 | #include 10 | #include 11 | 12 | typedef struct Queue { 13 | int *data; 14 | int head, tail; 15 | int length, cnt; 16 | } Queue; 17 | 18 | Queue *init(int n) { 19 | Queue *q = (Queue *)malloc(sizeof(Queue)); 20 | q->data = (int *)malloc(sizeof(int) * n); 21 | q->head = q->tail = q->cnt = 0; 22 | q->length = n; 23 | return q; 24 | } 25 | 26 | int empty(Queue *q) { 27 | return q->cnt == 0; 28 | } 29 | 30 | int front(Queue *q) { 31 | return q->data[q->head]; 32 | } 33 | 34 | int push(Queue *q, int val) { 35 | if (q == NULL) return 0; 36 | if (q->cnt == q->length) return 0; 37 | q->data[q->tail++] = val; 38 | if (q->tail == q->length) q->tail -= q->length; 39 | q->cnt += 1; 40 | return 1; 41 | } 42 | 43 | int pop(Queue *q) { 44 | if (q == NULL) return 0; 45 | if (empty(q)) return 0; 46 | q->head++; 47 | if (q->head == q->length) q->head -= q->length; 48 | q->cnt -= 1; 49 | return 1; 50 | } 51 | 52 | void clear(Queue *q) { 53 | if (q == NULL) return ; 54 | free(q->data); 55 | free(q); 56 | return ; 57 | } 58 | 59 | void output(Queue *q) { 60 | printf("queue = ["); 61 | for (int i = q->head, j = 0; j < q->cnt; j++) { 62 | int ind = (i + j) % q->length; 63 | printf(" %d", q->data[ind]); 64 | } 65 | printf("]\n"); 66 | return ; 67 | } 68 | 69 | int main() { 70 | srand(time(0)); 71 | #define MAX_OP 20 72 | Queue *q = init(MAX_OP); 73 | for (int i = 0; i < MAX_OP; i++) { 74 | int val = rand() % 100, op = rand() % 2; 75 | switch (op) { 76 | case 0: { 77 | printf("push %d to queue = %d\n", val, push(q, val)); 78 | } break; 79 | case 1: { 80 | printf("pop %d from queue = %d\n", front(q), pop(q)); 81 | } break; 82 | } 83 | output(q); 84 | } 85 | printf("head : %d, tail : %d, count : %d\n", q->head, q->tail, q->cnt); 86 | for (int i = 0; i < MAX_OP; i++) { 87 | int val = rand() % 100; 88 | printf("push %d to queue = %d\n", val, push(q, val)); 89 | } 90 | output(q); 91 | return 0; 92 | } -------------------------------------------------------------------------------- /第13章:贪心法习题课/2、代码演示(二)/1、HZOJ-256-国王的游戏.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 256.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 四 6/20 19:57:07 2019 7 | ************************************************************************/ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | using namespace std; 18 | #define MAX_N 1000 19 | #define MAX_M 6000 20 | 21 | struct Data { 22 | int a, b; 23 | } arr[MAX_N + 5]; 24 | 25 | bool cmp(const Data &a, const Data &b) { 26 | return a.a * a.b < b.a * b.b; 27 | } 28 | 29 | void set(int *arr, int x) { 30 | arr[0] = 0; 31 | do { 32 | arr[0]++; 33 | arr[arr[0]] = x % 10; 34 | x /= 10; 35 | } while (x); 36 | return ; 37 | } 38 | 39 | void multiply(int *arr, int x) { 40 | for (int i = 1; i <= arr[0]; i++) arr[i] *= x; 41 | for (int i = 1; i <= arr[0]; i++) { 42 | if (arr[i] < 10) continue; 43 | arr[i + 1] += arr[i] / 10; 44 | arr[i] %= 10; 45 | arr[0] += (i == arr[0]); 46 | arr[arr[0] + 1] = 0; 47 | } 48 | return ; 49 | } 50 | 51 | void div(int *arr, int x, int *ret) { 52 | int i = arr[0], temp = 0; 53 | while (i && temp * 10 + arr[i] < x) temp = temp * 10 + arr[i--]; 54 | if (i == 0) { 55 | set(ret, 0); 56 | return ; 57 | } 58 | ret[0] = i; 59 | while (i) { 60 | temp = temp * 10 + arr[i]; 61 | ret[i--] = temp / x; 62 | temp %= x; 63 | } 64 | return ; 65 | } 66 | 67 | bool bigger_than(int *num1, int *num2) { 68 | if (num1[0] - num2[0]) return num1[0] > num2[0]; 69 | for (int i = num1[0]; i >= 1; i--) { 70 | if (num1[i] - num2[i]) return num1[i] > num2[i]; 71 | } 72 | return false; 73 | } 74 | 75 | int main() { 76 | int n; 77 | cin >> n; 78 | for (int i = 0; i <= n; i++) cin >> arr[i].a >> arr[i].b; 79 | sort(arr + 1, arr + 1 + n, cmp); 80 | int p[MAX_M + 5], ans[MAX_M + 5], temp[MAX_M + 5]; 81 | set(p, arr[0].a); 82 | set(ans, 0); 83 | for (int i = 1; i <= n; i++) { 84 | div(p, arr[i].b, temp); 85 | if (bigger_than(temp, ans)) memcpy(ans, temp, sizeof(temp)); 86 | multiply(p, arr[i].a); 87 | } 88 | for (int i = ans[0]; i >= 1; i--) { 89 | cout << ans[i]; 90 | } 91 | cout << endl; 92 | return 0; 93 | } -------------------------------------------------------------------------------- /第5章:排序与查找/4、哈希表/1、hash_table.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 14.hash_table.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 二 11/ 6 20:41:45 2018 7 | ************************************************************************/ 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | typedef struct Node { 14 | char *str; 15 | struct Node *next; 16 | } Node; 17 | 18 | typedef struct HashTable { 19 | Node **data; 20 | int size; 21 | } HashTable; 22 | 23 | Node *init_node(char *str, Node *head) { 24 | Node *p = (Node *)malloc(sizeof(Node)); 25 | p->str = strdup(str); 26 | p->next = head; 27 | return p; 28 | } 29 | 30 | HashTable *init_hashtable(int n) { 31 | HashTable *h = (HashTable *)malloc(sizeof(HashTable)); 32 | h->size = n << 1; 33 | h->data = (Node **)calloc(sizeof(Node *), h->size); 34 | return h; 35 | } 36 | 37 | int BKDRHash(char *str) { 38 | int seed = 31, hash = 0; 39 | for (int i = 0; str[i]; i++) hash = hash * seed + str[i]; 40 | return hash & 0x7fffffff; 41 | } 42 | 43 | int insert(HashTable *h, char *str) { 44 | int hash = BKDRHash(str); 45 | int ind = hash % h->size; 46 | h->data[ind] = init_node(str, h->data[ind]); 47 | return 1; 48 | } 49 | 50 | int search(HashTable *h, char *str) { 51 | int hash = BKDRHash(str); 52 | int ind = hash % h->size; 53 | Node *p = h->data[ind]; 54 | while (p && strcmp(p->str, str)) p = p->next; 55 | return p != NULL; 56 | } 57 | 58 | void clear_node(Node *node) { 59 | if (node == NULL) return ; 60 | Node *p = node, *q; 61 | while (p) { 62 | q = p->next; 63 | free(p->str); 64 | free(p); 65 | p = q; 66 | } 67 | return ; 68 | } 69 | 70 | void clear_hashtable(HashTable *h) { 71 | if (h == NULL) return ; 72 | for (int i = 0; i < h->size; i++) clear_node(h->data[i]); 73 | free(h->data); 74 | free(h); 75 | return ; 76 | } 77 | 78 | int main() { 79 | int op; 80 | char str[100]; 81 | HashTable *h = init_hashtable(100); 82 | while (scanf("%d%s", &op, str) != EOF) { 83 | switch (op) { 84 | case 0: { 85 | printf("insert %s to hash table\n", str); 86 | insert(h, str); 87 | } break; 88 | case 1: { 89 | printf("search %s result = %d\n", str, search(h, str)); 90 | } break; 91 | } 92 | } 93 | return 0; 94 | } -------------------------------------------------------------------------------- /第12章:平衡二叉查找树/1、二叉排序树/1、binary_search_tree.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 13.binary_search_tree.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 二 9/17 18:49:15 2019 7 | ************************************************************************/ 8 | 9 | #include 10 | #include 11 | 12 | typedef struct Node { 13 | int key; 14 | struct Node *lchild, *rchild; 15 | } Node; 16 | 17 | Node *getNewNode(int key) { 18 | Node *p = (Node *)malloc(sizeof(Node)); 19 | p->key = key; 20 | p->lchild = p->rchild = NULL; 21 | return p; 22 | } 23 | 24 | Node *insert(Node *root, int key) { 25 | if (root == NULL) return getNewNode(key); 26 | if (root->key == key) return root; 27 | if (root->key > key) root->lchild = insert(root->lchild, key); 28 | else root->rchild = insert(root->rchild, key); 29 | return root; 30 | } 31 | 32 | Node *predecessor(Node *root) { 33 | Node *temp = root->lchild; 34 | while (temp->rchild) temp = temp->rchild; 35 | return temp; 36 | } 37 | 38 | Node *erase(Node *root, int key) { 39 | if (root == NULL) return root; 40 | if (root->key > key) root->lchild = erase(root->lchild, key); 41 | else if (root->key < key) root->rchild = erase(root->rchild, key); 42 | else { 43 | if (root->lchild == NULL || root->rchild == NULL) { 44 | Node *temp = root->lchild ? root->lchild : root->rchild; 45 | free(root); 46 | return temp; 47 | } else { 48 | Node *temp = predecessor(root); 49 | root->key = temp->key; 50 | root->lchild = erase(root->lchild, temp->key); 51 | } 52 | } 53 | return root; 54 | } 55 | 56 | void __in_order(Node *root) { 57 | if (root == NULL) return ; 58 | __in_order(root->lchild); 59 | printf("%d ", root->key); 60 | __in_order(root->rchild); 61 | return ; 62 | } 63 | 64 | void in_order(Node *root) { 65 | printf("in order output : "); 66 | __in_order(root); 67 | printf("\n"); 68 | return ; 69 | } 70 | 71 | void clear(Node *node) { 72 | if (node == NULL) return ; 73 | clear(node->lchild); 74 | clear(node->rchild); 75 | free(node); 76 | return ; 77 | } 78 | 79 | int main() { 80 | int op, val; 81 | Node *root = NULL; 82 | while (~scanf("%d%d", &op, &val)) { 83 | switch (op) { 84 | case 1: root = insert(root, val); break; 85 | case 2: root = erase(root, val); break; 86 | } 87 | in_order(root); 88 | } 89 | clear(root); 90 | return 0; 91 | } -------------------------------------------------------------------------------- /第5章:排序与查找/1、稳定排序/1、stable_sort.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 10.stable_sort.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 日 11/ 4 19:45:48 2018 7 | ************************************************************************/ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #define swap(a, b) { \ 15 | a ^= b; b ^= a; a ^= b; \ 16 | } 17 | 18 | #define TEST(arr, n, func, args...) { \ 19 | int *num = (int *)malloc(sizeof(int) * n); \ 20 | memcpy(num, arr, sizeof(int) * n); \ 21 | output(num, n); \ 22 | printf("%s = ", #func); \ 23 | func(args); \ 24 | output(num, n); \ 25 | free(num); \ 26 | } 27 | 28 | void insert_sort(int *num, int n) { 29 | for (int i = 1; i < n; i++) { 30 | for (int j = i; j > 0 && num[j] < num[j - 1]; --j) { 31 | swap(num[j], num[j - 1]); 32 | } 33 | } 34 | return ; 35 | } 36 | 37 | void bubble_sort(int *num, int n) { 38 | int times = 1; 39 | for (int i = 1; i < n && times; i++) { 40 | times = 0; 41 | for (int j = 0; j < n - i; j++) { 42 | if (num[j] <= num[j + 1]) continue; 43 | swap(num[j], num[j + 1]); 44 | times++; 45 | } 46 | } 47 | return ; 48 | } 49 | 50 | void merge_sort(int *num, int l, int r) { 51 | if (r - l <= 1) { 52 | if (r - l == 1 && num[l] > num[r]) { 53 | swap(num[l], num[r]); 54 | } 55 | return ; 56 | } 57 | int mid = (l + r) >> 1; 58 | merge_sort(num, l, mid); 59 | merge_sort(num, mid + 1, r); 60 | int *temp = (int *)malloc(sizeof(int) * (r - l + 1)); 61 | int p1 = l, p2 = mid + 1, k = 0; 62 | while (p1 <= mid || p2 <= r) { 63 | if (p2 > r || (p1 <= mid && num[p1] <= num[p2])) { 64 | temp[k++] = num[p1++]; 65 | } else { 66 | temp[k++] = num[p2++]; 67 | } 68 | } 69 | memcpy(num + l, temp, sizeof(int) * (r - l + 1)); 70 | free(temp); 71 | return ; 72 | } 73 | 74 | void randint(int *num, int n) { 75 | while (n--) num[n] = rand() % 100; 76 | return ; 77 | } 78 | 79 | void output(int *num, int n) { 80 | printf("["); 81 | for (int i = 0; i < n; i++) { 82 | printf(" %d", num[i]); 83 | } 84 | printf("]\n"); 85 | return ; 86 | } 87 | 88 | int main() { 89 | srand(time(0)); 90 | #define MAX_OP 20 91 | int arr[MAX_OP]; 92 | randint(arr, MAX_OP); 93 | TEST(arr, MAX_OP, insert_sort, num, MAX_OP); 94 | TEST(arr, MAX_OP, bubble_sort, num, MAX_OP); 95 | TEST(arr, MAX_OP, merge_sort, num, 0, MAX_OP - 1); 96 | return 0; 97 | } -------------------------------------------------------------------------------- /第4章:堆与优先队列/3、演示代码(一)/3、Leetcode-23.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 23.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 二 5/ 7 18:42:07 2019 7 | ************************************************************************/ 8 | 9 | /** 10 | * Definition for singly-linked list. 11 | * struct ListNode { 12 | * int val; 13 | * struct ListNode *next; 14 | * }; 15 | */ 16 | 17 | #define swap(a, b) { \ 18 | __typeof(a) __temp = a; \ 19 | a = b, b = __temp; \ 20 | } 21 | 22 | typedef struct Data { 23 | struct ListNode *p; 24 | int ind; 25 | } Data; 26 | 27 | typedef struct Heap { 28 | Data *data; 29 | int size, n; 30 | } Heap; 31 | 32 | Heap *init(int k) { 33 | Heap *h = (Heap *)malloc(sizeof(Heap)); 34 | h->size = k + 1; 35 | h->n = 0; 36 | h->data = (Data *)malloc(sizeof(Data) * (k + 1)); 37 | return h; 38 | } 39 | 40 | #define V(x) h->data[x].p->val 41 | #define IND(x) h->data[x].ind 42 | 43 | void push(Heap *h, struct ListNode *d, int i) { 44 | Data data = {d, i}; 45 | h->data[++(h->n)] = data; 46 | int ind = h->n; 47 | while (ind != 1 && V(ind) < V(ind >> 1)) { 48 | swap(h->data[ind], h->data[ind >> 1]); 49 | ind >>= 1; 50 | } 51 | return ; 52 | } 53 | 54 | Data top(Heap *h) { 55 | return h->data[1]; 56 | } 57 | 58 | int empty(Heap *h) { 59 | return h->n == 0; 60 | } 61 | 62 | void pop(Heap *h) { 63 | if (empty(h)) return ; 64 | h->data[1] = h->data[h->n]; 65 | (h->n)--; 66 | int ind = 1; 67 | while ((ind << 1) <= h->n) { 68 | int temp = ind, l = ind << 1, r = ind << 1 | 1; 69 | if (V(l) < V(temp)) temp = l; 70 | if (r <= h->n && V(r) < V(temp)) temp = r; 71 | if (temp == ind) break; 72 | swap(h->data[temp], h->data[ind]); 73 | ind = temp; 74 | } 75 | return ; 76 | } 77 | 78 | void clear(Heap *h) { 79 | if (h == NULL) return ; 80 | free(h->data); 81 | free(h); 82 | return ; 83 | } 84 | 85 | struct ListNode* mergeKLists(struct ListNode** lists, int listsSize){ 86 | Heap *h = init(listsSize); 87 | for (int i = 0; i < listsSize; i++) { 88 | if (lists[i] == NULL) continue; 89 | push(h, lists[i], i); 90 | lists[i] = lists[i]->next; 91 | } 92 | struct ListNode ret, *p; 93 | ret.next = NULL; 94 | p = &ret; 95 | while (!empty(h)) { 96 | Data d = top(h); 97 | pop(h); 98 | p->next = d.p; 99 | p = p->next; 100 | p->next = NULL; 101 | if (lists[d.ind]) { 102 | push(h, lists[d.ind], d.ind); 103 | lists[d.ind] = lists[d.ind]->next; 104 | } 105 | } 106 | clear(h); 107 | return ret.next; 108 | } -------------------------------------------------------------------------------- /第6章:字符串匹配算法(1)/1、字符串代码演示/1、字符串匹配算法.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 10.string.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 五 8/16 18:13:38 2019 7 | ************************************************************************/ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | using namespace std; 18 | #define MAX_N 1000 19 | #define TEST(func, a, b) { \ 20 | printf("TEST %s(%s, %s) = %d\n", #func, a, b, func(a, b)); \ 21 | } 22 | char text[MAX_N + 5], pattern[MAX_N + 5]; 23 | 24 | int brute_force(char *s, char *t) { 25 | int len1 = strlen(s); 26 | int len2 = strlen(t); 27 | for (int i = 0, I = len1 - len2 + 1; i < I; i++) { 28 | int j = 0; 29 | for (; t[j]; j++) { 30 | if (t[j] == s[i + j]) continue; 31 | break; 32 | } 33 | if (!t[j]) return i; 34 | } 35 | return -1; 36 | } 37 | 38 | int sunday(char *s, char *t) { 39 | int ind[128] = {0}; 40 | int len1 = strlen(s); 41 | int len2 = strlen(t); 42 | for (int i = 0; i < 128; i++) ind[i] = len2 + 1; 43 | for (int i = 0; t[i]; i++) ind[t[i]] = len2 - i; 44 | for (int i = 0, I = len1 - len2 + 1; i < I;) { 45 | int flag = 1; 46 | for (int j = 0; j < len2; j++) { 47 | if (t[j] == s[i + j]) continue; 48 | i += ind[s[i + len2]]; 49 | flag = 0; 50 | break; 51 | } 52 | if (flag) return i; 53 | } 54 | return -1; 55 | } 56 | 57 | int shift_and(char *s, char *t) { 58 | int code[128] = {0}; 59 | int len = 0; 60 | for (len = 0; t[len]; len++) { 61 | code[t[len]] |= (1 << len); 62 | } 63 | int p = 0; 64 | for (int i = 0; s[i]; i++) { 65 | p = (p << 1 | 1) & code[s[i]]; 66 | if (p & (1 << (len - 1))) return i - len + 1; 67 | } 68 | return -1; 69 | } 70 | 71 | int kmp(char *s, char *t) { 72 | int len1 = strlen(s); 73 | int len2 = strlen(t); 74 | int *next = (int *)malloc(sizeof(int) * len2); 75 | next[0] = -1; 76 | for (int i = 1, j = -1; i < len2; i++) { 77 | while (j != -1 && t[j + 1] != t[i]) j = next[j]; 78 | if (t[j + 1] == t[i]) j += 1; 79 | next[i] = j; 80 | } 81 | for (int i = 0, j = -1; s[i]; i++) { 82 | while (j != -1 && t[j + 1] != s[i]) j = next[j]; 83 | if (t[j + 1] == s[i]) j += 1; 84 | if (t[j + 1] == 0) return i - len2 + 1; 85 | } 86 | free(next); 87 | return -1; 88 | } 89 | 90 | int main() { 91 | scanf("%s%s", text, pattern); 92 | TEST(brute_force, text, pattern); 93 | TEST(kmp, text, pattern); 94 | TEST(sunday, text, pattern); 95 | TEST(shift_and, text, pattern); 96 | return 0; 97 | } -------------------------------------------------------------------------------- /第5章:排序与查找/7、演示代码(三)/2、Leetcode-219.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 219.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 六 5/11 16:07:27 2019 7 | ************************************************************************/ 8 | 9 | typedef struct Data { 10 | int val, cnt; 11 | } Data; 12 | 13 | typedef struct HashTable { 14 | Data *data; 15 | int *flag; 16 | int size; 17 | } HashTable; 18 | 19 | HashTable *init(int n) { 20 | HashTable *h = (HashTable *)malloc(sizeof(HashTable)); 21 | h->data = (Data *)malloc(sizeof(Data) * n); 22 | h->flag = (int *)calloc(sizeof(int), (n / 31 + 1)); 23 | h->size = n; 24 | return h; 25 | } 26 | 27 | int hash(int val) { 28 | return val & 0x7fffffff; 29 | } 30 | 31 | int check(HashTable *h, int ind) { 32 | int x = ind / 31, y = ind % 31; 33 | return h->flag[x] & (1 << y); 34 | } 35 | 36 | void set(HashTable *h, int ind, int val) { 37 | int x = ind / 31, y = ind % 31; 38 | h->flag[x] |= (1 << y); 39 | h->data[ind].val = val; 40 | h->data[ind].cnt = 0; 41 | return ; 42 | } 43 | 44 | void insert(HashTable *h, int val) { 45 | int ind = hash(val) % h->size; 46 | int times = 1; 47 | while (check(h, ind) && h->data[ind].val != val) { 48 | ind += (times * times); 49 | ind %= h->size; 50 | } 51 | if (check(h, ind)) return ; 52 | set(h, ind, val); 53 | return ; 54 | } 55 | 56 | int query(HashTable *h, int val) { 57 | int ind = hash(val) % h->size; 58 | int times = 1; 59 | while (check(h, ind) && h->data[ind].val != val) { 60 | ind += (times * times); 61 | ind %= h->size; 62 | } 63 | if (check(h, ind)) return ind; 64 | return -1; 65 | } 66 | 67 | int add_once(HashTable *h, int val, int delta) { 68 | int ind = query(h, val); 69 | if (ind == -1) return -1; 70 | h->data[ind].cnt += delta; 71 | return h->data[ind].cnt; 72 | } 73 | 74 | void clear(HashTable *h) { 75 | if (h == NULL) return ; 76 | free(h->data); 77 | free(h->flag); 78 | free(h); 79 | return ; 80 | } 81 | 82 | 83 | bool containsNearbyDuplicate(int* nums, int numsSize, int k){ 84 | if (numsSize == 0 || k == 0) return false; 85 | HashTable *h = init(3 * numsSize); 86 | for (int i = 0; i < numsSize; i++) { 87 | insert(h, nums[i]); 88 | } 89 | int cnt = 0; 90 | k = fmin(k + 1, numsSize); 91 | for (int i = 0; i < k; i++) { 92 | cnt += (add_once(h, nums[i], 1) == 1); 93 | } 94 | if (cnt != k) return true; 95 | for (int i = k; i < numsSize; i++) { 96 | cnt += (add_once(h, nums[i], 1) == 1); 97 | cnt -= (add_once(h, nums[i - k], -1) == 0); 98 | if (cnt != k) return true; 99 | } 100 | clear(h); 101 | return false; 102 | } -------------------------------------------------------------------------------- /第5章:排序与查找/7、演示代码(三)/4、Leetcode-349.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 349.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 六 5/11 16:27:47 2019 7 | ************************************************************************/ 8 | 9 | typedef struct Data { 10 | int val, cnt; 11 | } Data; 12 | 13 | typedef struct HashTable { 14 | Data *data; 15 | int *flag; 16 | int size; 17 | } HashTable; 18 | 19 | HashTable *init(int n) { 20 | HashTable *h = (HashTable *)malloc(sizeof(HashTable)); 21 | h->data = (Data *)malloc(sizeof(Data) * n); 22 | h->flag = (int *)calloc(sizeof(int), (n / 31 + 1)); 23 | h->size = n; 24 | return h; 25 | } 26 | 27 | int hash(int val) { 28 | return val & 0x7fffffff; 29 | } 30 | 31 | int check(HashTable *h, int ind) { 32 | int x = ind / 31, y = ind % 31; 33 | return h->flag[x] & (1 << y); 34 | } 35 | 36 | void set(HashTable *h, int ind, int val) { 37 | int x = ind / 31, y = ind % 31; 38 | h->flag[x] |= (1 << y); 39 | h->data[ind].val = val; 40 | h->data[ind].cnt = 0; 41 | return ; 42 | } 43 | 44 | void insert(HashTable *h, int val) { 45 | int ind = hash(val) % h->size; 46 | int times = 1; 47 | while (check(h, ind) && h->data[ind].val != val) { 48 | ind += (times * times); 49 | ind %= h->size; 50 | times += 1; 51 | } 52 | if (check(h, ind)) return ; 53 | set(h, ind, val); 54 | return ; 55 | } 56 | 57 | int query(HashTable *h, int val) { 58 | int ind = hash(val) % h->size; 59 | int times = 1; 60 | while (check(h, ind) && h->data[ind].val != val) { 61 | ind += (times * times); 62 | ind %= h->size; 63 | times += 1; 64 | } 65 | if (check(h, ind)) return ind; 66 | return -1; 67 | } 68 | 69 | int add_once(HashTable *h, int val, int delta) { 70 | int ind = query(h, val); 71 | if (ind == -1) return -1; 72 | h->data[ind].cnt += delta; 73 | return h->data[ind].cnt; 74 | } 75 | 76 | void clear(HashTable *h) { 77 | if (h == NULL) return ; 78 | free(h->data); 79 | free(h->flag); 80 | free(h); 81 | return ; 82 | } 83 | 84 | /** 85 | * Note: The returned array must be malloced, assume caller calls free(). 86 | */ 87 | int* intersection(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize){ 88 | HashTable *h = init(nums1Size * 3 + 1); 89 | for (int i = 0; i < nums1Size; i++) { 90 | insert(h, nums1[i]); 91 | } 92 | int cnt = 0; 93 | int *ret = (int *)malloc(sizeof(int) * (nums1Size + 1)); 94 | for (int i = 0; i < nums2Size; i++) { 95 | if (add_once(h, nums2[i], 1) == 1) { 96 | ret[cnt++] = nums2[i]; 97 | } 98 | } 99 | clear(h); 100 | returnSize[0] = cnt; 101 | return ret; 102 | } -------------------------------------------------------------------------------- /第5章:排序与查找/8、演示代码(四)/1、Leetcode-350.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 350.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 六 5/11 16:38:47 2019 7 | ************************************************************************/ 8 | 9 | typedef struct Data { 10 | int val, cnt; 11 | } Data; 12 | 13 | typedef struct HashTable { 14 | Data *data; 15 | int *flag; 16 | int size; 17 | } HashTable; 18 | 19 | HashTable *init(int n) { 20 | HashTable *h = (HashTable *)malloc(sizeof(HashTable)); 21 | h->data = (Data *)malloc(sizeof(Data) * n); 22 | h->flag = (int *)calloc(sizeof(int), (n / 31 + 1)); 23 | h->size = n; 24 | return h; 25 | } 26 | 27 | int hash(int val) { 28 | return val & 0x7fffffff; 29 | } 30 | 31 | int check(HashTable *h, int ind) { 32 | int x = ind / 31, y = ind % 31; 33 | return h->flag[x] & (1 << y); 34 | } 35 | 36 | void set(HashTable *h, int ind, int val) { 37 | int x = ind / 31, y = ind % 31; 38 | h->flag[x] |= (1 << y); 39 | h->data[ind].val = val; 40 | h->data[ind].cnt = 0; 41 | return ; 42 | } 43 | 44 | void insert(HashTable *h, int val) { 45 | int ind = hash(val) % h->size; 46 | int times = 1; 47 | while (check(h, ind) && h->data[ind].val != val) { 48 | ind += (times * times); 49 | ind %= h->size; 50 | times += 1; 51 | } 52 | if (check(h, ind)) return ; 53 | set(h, ind, val); 54 | return ; 55 | } 56 | 57 | int query(HashTable *h, int val) { 58 | int ind = hash(val) % h->size; 59 | int times = 1; 60 | while (check(h, ind) && h->data[ind].val != val) { 61 | ind += (times * times); 62 | ind %= h->size; 63 | times += 1; 64 | } 65 | if (check(h, ind)) return ind; 66 | return -1; 67 | } 68 | 69 | int add_once(HashTable *h, int val, int delta) { 70 | int ind = query(h, val); 71 | if (ind == -1) return -1; 72 | h->data[ind].cnt += delta; 73 | return h->data[ind].cnt; 74 | } 75 | 76 | void clear(HashTable *h) { 77 | if (h == NULL) return ; 78 | free(h->data); 79 | free(h->flag); 80 | free(h); 81 | return ; 82 | } 83 | 84 | /** 85 | * Note: The returned array must be malloced, assume caller calls free(). 86 | */ 87 | int* intersect(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize){ 88 | HashTable *h = init(3 * nums1Size + 1); 89 | for (int i = 0; i < nums1Size; i++) { 90 | insert(h, nums1[i]); 91 | } 92 | for (int i = 0; i < nums1Size; i++) { 93 | add_once(h, nums1[i], 1); 94 | } 95 | int cnt = 0; 96 | int *ret = (int *)malloc(sizeof(int) * (nums1Size + 1)); 97 | for (int i = 0; i < nums2Size; i++) { 98 | if (add_once(h, nums2[i], -1) >= 0) { 99 | ret[cnt++] = nums2[i]; 100 | } 101 | } 102 | returnSize[0] = cnt; 103 | return ret; 104 | } -------------------------------------------------------------------------------- /第8章:字符串匹配算法(3)/2、AC 自动机--内容扩展/2、AC 自动机的线索化.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | 6 | const int SIZE = 26; 7 | const char BASE = 'a'; 8 | const int MAX_SIZE = 200000; 9 | const int MAX_LEN = 200000; 10 | char str_buffer[200005]; 11 | 12 | typedef struct TrieNode { 13 | int count; 14 | struct TrieNode** childs; 15 | struct TrieNode *fail; 16 | } TrieNode, *Trie; 17 | 18 | TrieNode* new_node() { 19 | TrieNode *p = (TrieNode *)calloc(sizeof(TrieNode), 1); 20 | p->childs = (TrieNode **)malloc(sizeof(TrieNode *) * SIZE); 21 | for (int i = 0; i < SIZE; i++) { 22 | p->childs[i] = NULL; 23 | } 24 | p->count = 0; 25 | return p; 26 | } 27 | 28 | void clear(TrieNode *node) { 29 | if (node == NULL) return ; 30 | for (int i = 0; i < SIZE; i++) { 31 | if (node->childs[i] == NULL) continue; 32 | clear(node->childs[i]); 33 | } 34 | free(node->childs); 35 | free(node); 36 | return ; 37 | } 38 | 39 | void insert(TrieNode *trie, const char *buffer) { 40 | TrieNode *p = trie; 41 | for (int i = 0; i < strlen(buffer); i++) { 42 | if (p->childs[buffer[i] - BASE] == NULL) { 43 | p->childs[buffer[i] - BASE] = new_node(); 44 | } 45 | p = p->childs[buffer[i] - BASE]; 46 | } 47 | p->count++; 48 | return ; 49 | } 50 | 51 | void build_automaton(TrieNode *node) { 52 | TrieNode **queue = (TrieNode **)malloc(sizeof(TrieNode *) * (MAX_SIZE + 5)); 53 | int head = 0, tail = 0; 54 | queue[tail++] = node; 55 | while (head < tail) { 56 | TrieNode *now = queue[head++]; 57 | for (int i = 0; i < SIZE; i++) { 58 | if (now->childs[i] == NULL) { 59 | if (now != node) now->childs[i] = now->fail->childs[i]; 60 | continue; 61 | } 62 | TrieNode *p = (now->fail ? now->fail->childs[i] : node); 63 | if (p == NULL) p = node; 64 | now->childs[i]->fail = p; 65 | queue[tail++] = now->childs[i]; 66 | } 67 | } 68 | free(queue); 69 | return ; 70 | } 71 | 72 | int match_count(TrieNode *ac_tree, const char *str) { 73 | int ret = 0; 74 | TrieNode *p = ac_tree, *q; 75 | while (str[0]) { 76 | p = p->childs[str[0] - 'a']; 77 | q = p; 78 | while (q) ret += q->count, q = q->fail; 79 | if (p == NULL) p = ac_tree; 80 | str++; 81 | } 82 | return ret; 83 | } 84 | int main() { 85 | Trie root = new_node(); 86 | int n; 87 | scanf("%d", &n); 88 | for (int i = 0; i < n; ++i) { 89 | char pattern[MAX_LEN]; 90 | scanf("%s", pattern); 91 | insert(root, pattern); 92 | } 93 | printf("insert done\n"); 94 | fflush(stdout); 95 | build_automaton(root); 96 | scanf("%s", str_buffer); 97 | printf("%d\n", match_count(root, str_buffer)); 98 | //clear(root); 99 | return 0; 100 | } -------------------------------------------------------------------------------- /第2章:栈和队列/4、演示代码(栈&队列)/3、Leetcode-232.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 232.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 四 4/11 18:58:05 2019 7 | ************************************************************************/ 8 | 9 | typedef struct { 10 | int *data; 11 | int top; 12 | } MyStack; 13 | 14 | MyStack* myStackCreate(int maxSize) { 15 | MyStack *s = (MyStack *)malloc(sizeof(MyStack)); 16 | s->data = (int *)malloc(sizeof(int) * maxSize); 17 | s->top = -1; 18 | return s; 19 | } 20 | 21 | /** Push element x to the back of queue. */ 22 | void myStackPush(MyStack* obj, int x) { 23 | obj->data[++(obj->top)] = x; 24 | } 25 | 26 | /** Removes the element from in front of queue and returns that element. */ 27 | int myStackPop(MyStack* obj) { 28 | return obj->data[(obj->top)--]; 29 | } 30 | 31 | /** Get the front element. */ 32 | int myStackTop(MyStack* obj) { 33 | return obj->data[obj->top]; 34 | } 35 | 36 | /** Returns whether the queue is empty. */ 37 | bool myStackEmpty(MyStack* obj) { 38 | return obj->top == -1; 39 | } 40 | 41 | void myStackFree(MyStack* obj) { 42 | free(obj->data); 43 | free(obj); 44 | } 45 | 46 | 47 | typedef struct { 48 | MyStack *s1, *s2; 49 | } MyQueue; 50 | 51 | /** Initialize your data structure here. */ 52 | MyQueue* myQueueCreate(int maxSize) { 53 | MyQueue *q = (MyQueue *)malloc(sizeof(MyQueue)); 54 | q->s1 = myStackCreate(maxSize); 55 | q->s2 = myStackCreate(maxSize); 56 | return q; 57 | } 58 | 59 | /** Push element x to the back of queue. */ 60 | void myQueuePush(MyQueue* obj, int x) { 61 | myStackPush(obj->s1, x); 62 | } 63 | 64 | /** Removes the element from in front of queue and returns that element. */ 65 | int myQueuePop(MyQueue* obj) { 66 | if (myStackEmpty(obj->s2)) { 67 | while (!myStackEmpty(obj->s1)) { 68 | myStackPush(obj->s2, myStackPop(obj->s1)); 69 | } 70 | } 71 | return myStackPop(obj->s2); 72 | } 73 | 74 | /** Get the front element. */ 75 | int myQueuePeek(MyQueue* obj) { 76 | if (myStackEmpty(obj->s2)) { 77 | while (!myStackEmpty(obj->s1)) { 78 | myStackPush(obj->s2, myStackPop(obj->s1)); 79 | } 80 | } 81 | return myStackTop(obj->s2); 82 | } 83 | 84 | /** Returns whether the queue is empty. */ 85 | bool myQueueEmpty(MyQueue* obj) { 86 | return myStackEmpty(obj->s1) && myStackEmpty(obj->s2); 87 | } 88 | 89 | void myQueueFree(MyQueue* obj) { 90 | myStackFree(obj->s1); 91 | myStackFree(obj->s2); 92 | free(obj); 93 | return ; 94 | } 95 | 96 | /** 97 | * Your MyQueue struct will be instantiated and called as such: 98 | * struct MyQueue* obj = myQueueCreate(maxSize); 99 | * myQueuePush(obj, x); 100 | * int param_2 = myQueuePop(obj); 101 | * int param_3 = myQueuePeek(obj); 102 | * bool param_4 = myQueueEmpty(obj); 103 | * myQueueFree(obj); 104 | */ -------------------------------------------------------------------------------- /第3章:树与二叉树/3、二叉树的线索化/1、ThreadBinaryTree.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 7.thread.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 三 8/ 7 18:33:37 2019 7 | ************************************************************************/ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | using namespace std; 18 | #define NORMAL 0 19 | #define THREAD 1 20 | 21 | typedef struct Node { 22 | int key; 23 | int ltag, rtag; 24 | struct Node *lchild, *rchild; 25 | } Node; 26 | 27 | Node *getNewNode(int key) { 28 | Node *p = (Node *)malloc(sizeof(Node)); 29 | p->lchild = p->rchild = NULL; 30 | p->key = key; 31 | p->ltag = p->rtag = NORMAL; 32 | return p; 33 | } 34 | 35 | Node *insert(Node *root, int key) { 36 | if (root == NULL) return getNewNode(key); 37 | if (root->key == key) return root; 38 | if (root->key < key) root->rchild = insert(root->rchild, key); 39 | else root->lchild = insert(root->lchild, key); 40 | return root; 41 | } 42 | 43 | void inorder(Node *root) { 44 | if (root == NULL) return ; 45 | if (root->ltag == NORMAL) inorder(root->lchild); 46 | printf("%d ", root->key); 47 | if (root->rtag == NORMAL) inorder(root->rchild); 48 | return ; 49 | } 50 | 51 | void build_thread(Node *root) { 52 | if (root == NULL) return ; 53 | static Node *pre = NULL; 54 | build_thread(root->lchild); 55 | if (root->lchild == NULL) { 56 | root->lchild = pre; 57 | root->ltag = THREAD; 58 | } 59 | if (pre != NULL && pre->rchild == NULL) { 60 | pre->rchild = root; 61 | pre->rtag = THREAD; 62 | } 63 | pre = root; 64 | build_thread(root->rchild); 65 | return ; 66 | } 67 | 68 | void clear(Node *root) { 69 | if (root == NULL) return ; 70 | if (root->ltag == NORMAL) clear(root->lchild); 71 | if (root->rtag == NORMAL) clear(root->rchild); 72 | free(root); 73 | return ; 74 | } 75 | 76 | Node *leftMost(Node *p) { 77 | while (p && p->ltag == NORMAL && p->lchild) p = p->lchild; 78 | return p; 79 | } 80 | 81 | void output(Node *root) { 82 | Node *p = leftMost(root); 83 | while (p) { 84 | printf("%d ", p->key); 85 | if (p->rtag == THREAD) { 86 | p = p->rchild; 87 | } else { 88 | p = leftMost(p->rchild); 89 | } 90 | } 91 | printf("\n"); 92 | return ; 93 | } 94 | 95 | int main() { 96 | srand(time(0)); 97 | #define MAX_OP 20 98 | Node *root = NULL; 99 | for (int i = 0; i < MAX_OP; i++) { 100 | int val = rand() % 100; 101 | root = insert(root, val); 102 | } 103 | build_thread(root); 104 | inorder(root), printf("\n"); 105 | output(root); 106 | clear(root); 107 | return 0; 108 | } -------------------------------------------------------------------------------- /第11章:树状数组与线段树/2、线段树结构基础/2、HZOJ-223-线段树模板(二).cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 223.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 六 8/24 20:14:12 2019 7 | ************************************************************************/ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | using namespace std; 18 | #define MAX_N 10000 19 | #define lc(ind) (tree[ind].lind) 20 | #define rc(ind) (tree[ind].rind) 21 | #define tag(ind) tree[ind].tag 22 | #define sum(ind) tree[ind].sum 23 | #define cnt(ind) tree[ind].cnt 24 | 25 | struct node { 26 | long long sum, tag, cnt; 27 | int lind, rind; 28 | } tree[(MAX_N << 1) + 5]; 29 | int root = 0, cnt = 1; 30 | long long arr[MAX_N + 5]; 31 | int getNode() { return cnt++; } 32 | 33 | void DOWN(int ind) { 34 | if (tag(ind)) { 35 | tag(lc(ind)) += tag(ind); 36 | tag(rc(ind)) += tag(ind); 37 | sum(lc(ind)) += tag(ind) * cnt(lc(ind)); 38 | sum(rc(ind)) += tag(ind) * cnt(rc(ind)); 39 | tag(ind) = 0; 40 | } 41 | return ; 42 | } 43 | 44 | void UP(int ind) { 45 | tree[ind].sum = tree[lc(ind)].sum + tree[rc(ind)].sum; 46 | } 47 | 48 | void build(int ind, int l, int r) { 49 | tree[ind].cnt = (r - l + 1); 50 | if (l == r) { 51 | tree[ind].sum = arr[l]; 52 | return ; 53 | } 54 | int mid = (l + r) >> 1; 55 | tree[ind].lind = getNode(); 56 | tree[ind].rind = getNode(); 57 | build(lc(ind), l, mid); 58 | build(rc(ind), mid + 1, r); 59 | UP(ind); 60 | return ; 61 | } 62 | 63 | void modify(int ind, int x, int y, long long d, int l, int r) { 64 | if (x <= l && r <= y) { 65 | tree[ind].tag += d; 66 | tree[ind].sum += d * tree[ind].cnt; 67 | return ; 68 | } 69 | DOWN(ind); 70 | int mid = (l + r) >> 1; 71 | if (x <= mid) modify(lc(ind), x, y, d, l, mid); 72 | if (y > mid) modify(rc(ind), x, y, d, mid + 1, r); 73 | UP(ind); 74 | return ; 75 | } 76 | 77 | long long query(int ind, int x, int y, int l, int r) { 78 | if (x <= l && r <= y) { 79 | return sum(ind); 80 | } 81 | DOWN(ind); 82 | int mid = (l + r) >> 1; 83 | long long ans = 0; 84 | if (x <= mid) ans += query(lc(ind), x, y, l, mid); 85 | if (y > mid) ans += query(rc(ind), x, y, mid + 1, r); 86 | return ans; 87 | } 88 | 89 | int main() { 90 | int n, m; 91 | cin >> n >> m; 92 | for (int i = 1; i <= n; i++) cin >> arr[i]; 93 | build(root, 1, n); 94 | for (int i = 0; i < m; i++) { 95 | long long a, b, c, d; 96 | cin >> a >> b >> c; 97 | if (a == 1) { 98 | cin >> d; 99 | modify(root, b, c, d, 1, n); 100 | } else { 101 | cout << query(root, b, c, 1, n) << endl; 102 | } 103 | } 104 | return 0; 105 | } -------------------------------------------------------------------------------- /第8章:字符串匹配算法(3)/2、AC 自动机--内容扩展/1、AC 自动机的递归建立.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | 6 | const int SIZE = 26; 7 | const char BASE = 'a'; 8 | const int MAX_SIZE = 200000; 9 | const int MAX_LEN = 200000; 10 | char str_buffer[200005]; 11 | 12 | typedef struct TrieNode { 13 | int count; 14 | struct TrieNode** childs; 15 | struct TrieNode* fail, *father; 16 | } TrieNode, *Trie; 17 | 18 | TrieNode* new_node() { 19 | TrieNode *p = (TrieNode *)malloc(sizeof(TrieNode)); 20 | p->childs = (TrieNode **)malloc(sizeof(TrieNode *) * SIZE); 21 | for (int i = 0; i < SIZE; i++) { 22 | p->childs[i] = NULL; 23 | } 24 | p->fail = NULL; 25 | p->count = 0; 26 | return p; 27 | } 28 | 29 | void clear(TrieNode *node) { 30 | if (node == NULL) return ; 31 | for (int i = 0; i < SIZE; i++) { 32 | if (node->childs[i] == NULL) continue; 33 | clear(node->childs[i]); 34 | } 35 | free(node->childs); 36 | free(node); 37 | return ; 38 | } 39 | 40 | void insert(TrieNode *trie, const char *buffer) { 41 | TrieNode *p = trie; 42 | for (int i = 0; i < strlen(buffer); i++) { 43 | if (p->childs[buffer[i] - BASE] == NULL) { 44 | p->childs[buffer[i] - BASE] = new_node(); 45 | p->childs[buffer[i] - BASE]->father = p; 46 | } 47 | p = p->childs[buffer[i] - BASE]; 48 | } 49 | p->count++; 50 | return ; 51 | } 52 | 53 | void build_automaton(TrieNode *node) { 54 | #define next childs 55 | #define Node TrieNode 56 | if (node == NULL) return ; 57 | if (node->fail == NULL) build_automaton(node->father); 58 | for (int i = 0; i < SIZE; i++) { 59 | if (node->next[i] == NULL) continue; 60 | if (node->next[i]->fail) continue; 61 | Node *p = node->fail, *pre_p = node; 62 | while (p && p->next[i] == NULL) { 63 | if (p->fail == NULL) build_automaton(p->father); 64 | pre_p = p; 65 | p = p->fail; 66 | } 67 | if (p == NULL) p = pre_p; 68 | else p = p->next[i]; 69 | node->next[i]->fail = p; 70 | build_automaton(node->next[i]); 71 | } 72 | return ; 73 | #undef next 74 | #undef Node 75 | } 76 | 77 | int match_count(TrieNode *ac_tree, const char *str) { 78 | int ret = 0; 79 | TrieNode *p = ac_tree, *q; 80 | while (str[0]) { 81 | while (p && p->childs[str[0] - 'a'] == NULL) p = p->fail; 82 | if (p == NULL) p = ac_tree; 83 | else p = p->childs[str[0] - 'a']; 84 | q = p; 85 | while (q) ret += q->count, q = q->fail; 86 | str++; 87 | } 88 | return ret; 89 | } 90 | 91 | int main() { 92 | Trie root = new_node(); 93 | int n; 94 | scanf("%d", &n); 95 | for (int i = 0; i < n; ++i) { 96 | char pattern[MAX_LEN]; 97 | scanf("%s", pattern); 98 | insert(root, pattern); 99 | } 100 | build_automaton(root); 101 | scanf("%s", str_buffer); 102 | printf("%d\n", match_count(root, str_buffer)); 103 | //clear(root); 104 | return 0; 105 | } -------------------------------------------------------------------------------- /第1章:顺序表与链表/1、顺序表/Vector.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 1.vector.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 日 6/30 15:18:05 2019 7 | ************************************************************************/ 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | typedef struct Vector { 14 | int *data; 15 | int size, length; 16 | } Vector; 17 | 18 | #define default_value(n, val) ((#n)[0] ? n + 0 : val) 19 | #define init(n) __init(default_value(n, 10)) 20 | 21 | Vector *__init(int n) { 22 | Vector *vec = (Vector *)malloc(sizeof(Vector)); 23 | vec->data = (int *)malloc(sizeof(int) * n); 24 | vec->size = n; 25 | vec->length = 0; 26 | return vec; 27 | } 28 | 29 | int expand(Vector *vec) { 30 | int new_size = vec->size * 2; 31 | int *p = (int *)realloc(vec->data, sizeof(int) * new_size); 32 | if (p == NULL) return 0; 33 | vec->size = new_size; 34 | vec->data = p; 35 | return 1; 36 | } 37 | 38 | int insert(Vector *vec, int ind, int val) { 39 | if (vec == NULL) return 0; 40 | if (vec->length == vec->size) { 41 | if (!expand(vec)) return 0; 42 | printf("expand vector size to %d success\n", vec->size); 43 | } 44 | if (ind < 0 || ind > vec->length) return 0; 45 | for (int i = vec->length; i > ind; i--) { 46 | vec->data[i] = vec->data[i - 1]; 47 | } 48 | vec->data[ind] = val; 49 | vec->length += 1; 50 | return 1; 51 | } 52 | 53 | int erase(Vector *vec, int ind) { 54 | if (vec == NULL) return 0; 55 | if (vec->length == 0) return 0; 56 | if (ind < 0 || ind >= vec->length) return 0; 57 | for (int i = ind + 1; i < vec->length; i++) { 58 | vec->data[i - 1] = vec->data[i]; 59 | } 60 | vec->length -= 1; 61 | return 1; 62 | } 63 | 64 | void clear(Vector *vec) { 65 | if (vec == NULL) return ; 66 | free(vec->data); 67 | free(vec); 68 | return ; 69 | } 70 | 71 | void output(Vector *vec) { 72 | printf("Vector(%d) = [", vec->length); 73 | for (int i = 0; i < vec->length; i++) { 74 | if (i != 0) printf(", "); 75 | printf("%d", vec->data[i]); 76 | } 77 | printf("]\n"); 78 | return ; 79 | } 80 | 81 | int main() { 82 | srand(time(0)); 83 | #define MAX_OP 20 84 | Vector *vec = init(); 85 | int op, ind, val; 86 | 87 | for (int i = 0; i < MAX_OP; i++) { 88 | op = rand() % 4; 89 | ind = rand() % (vec->length + 3); 90 | val = rand() % 100; 91 | switch (op) { 92 | case 2: 93 | case 3: 94 | case 0: { 95 | printf("insert %d at %d to vector = %d\n", 96 | val, ind, insert(vec, ind, val)); 97 | } break; 98 | case 1: { 99 | printf("erase item at %d from vector = %d\n", 100 | ind, erase(vec, ind)); 101 | } break; 102 | } 103 | output(vec); 104 | printf("\n"); 105 | } 106 | return 0; 107 | } -------------------------------------------------------------------------------- /第1章:顺序表与链表/2、链表/LinkList.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 2.linklist.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 日 6/30 19:01:23 2019 7 | ************************************************************************/ 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | typedef struct ListNode { 14 | int data; 15 | struct ListNode *next; 16 | } ListNode; 17 | 18 | typedef struct LinkList { 19 | ListNode head; 20 | int length; 21 | } LinkList; 22 | 23 | ListNode *init_listnode(int val) { 24 | ListNode *p = (ListNode *)malloc(sizeof(ListNode)); 25 | p->data = val; 26 | p->next = NULL; 27 | return p; 28 | } 29 | 30 | LinkList *init_linklist() { 31 | LinkList *l = (LinkList *)malloc(sizeof(LinkList)); 32 | l->head.next = NULL; 33 | l->length = 0; 34 | return l; 35 | } 36 | 37 | void clear_listnode(ListNode *node) { 38 | if (node == NULL) return ; 39 | free(node); 40 | return ; 41 | } 42 | 43 | void clear_linklist(LinkList *l) { 44 | if (l == NULL) return ; 45 | ListNode *p = l->head.next, *q; 46 | while (p) { 47 | q = p->next; 48 | clear_listnode(p); 49 | p = q; 50 | } 51 | free(l); 52 | return ; 53 | } 54 | 55 | int insert(LinkList *l, int ind, int val) { 56 | if (l == NULL) return 0; 57 | if (ind < 0 || ind > l->length) return 0; 58 | ListNode *p = &(l->head), *node = init_listnode(val); 59 | while (ind--) { 60 | p = p->next; 61 | } 62 | node->next = p->next; 63 | p->next = node; 64 | l->length += 1; 65 | return 1; 66 | } 67 | 68 | int erase(LinkList *l, int ind) { 69 | if (l == NULL) return 0; 70 | if (ind < 0 || ind >= l->length) return 0; 71 | ListNode *p = &(l->head), *q; 72 | while (ind--) { 73 | p = p->next; 74 | } 75 | q = p->next->next; 76 | clear_listnode(p->next); 77 | p->next = q; 78 | l->length -= 1; 79 | return 1; 80 | } 81 | 82 | void output(LinkList *l) { 83 | printf("LinkList(%d) : ", l->length); 84 | for (ListNode *p = l->head.next; p; p = p->next) { 85 | printf("%d -> ", p->data); 86 | } 87 | printf("NULL\n"); 88 | return ; 89 | } 90 | 91 | #define MAX_OP 30 92 | 93 | int main() { 94 | srand(time(0)); 95 | LinkList *l = init_linklist(); 96 | for (int i = 0; i < MAX_OP; i++) { 97 | int op = rand() % 3; 98 | int ind = rand() % (l->length + 1); 99 | int val = rand() % 100; 100 | switch (op) { 101 | case 0: 102 | case 1: { 103 | printf("insert %d at %d to LinkList = %d\n", 104 | val, ind, insert(l, ind, val)); 105 | } break; 106 | case 2: { 107 | printf("erase item at %d from LinkList = %d\n", 108 | ind, erase(l, ind)); 109 | } break; 110 | } 111 | output(l); 112 | printf("\n"); 113 | } 114 | clear_linklist(l); 115 | return 0; 116 | } 117 | -------------------------------------------------------------------------------- /第9章:递归函数转非递归函数/2、【程序演示】二叉树前序遍历(非递归).cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | > File Name: 14.binary_non_recursive.cpp 3 | > Author: hug 4 | > Mail: hug@haizeix.com 5 | > Created Time: 三 2/28 10:26:37 2018 6 | ************************************************************************/ 7 | 8 | #include 9 | #include 10 | #include "15.any_stack.h" 11 | 12 | typedef struct Node { 13 | int data; 14 | struct Node *lchild, *rchild; 15 | } Node; 16 | 17 | Node *getNewNode(int data) { 18 | Node *p = (Node *)malloc(sizeof(Node) * 1); 19 | p->data = data; 20 | p->lchild = p->rchild= NULL; 21 | return p; 22 | } 23 | 24 | Node *init_binary_tree() { 25 | Node *root = getNewNode(1); 26 | root->lchild = getNewNode(3); 27 | root->rchild = getNewNode(6); 28 | root->lchild->rchild = getNewNode(9); 29 | root->rchild->rchild = getNewNode(11); 30 | root->rchild->lchild = getNewNode(14); 31 | root->lchild->rchild->lchild = getNewNode(17); 32 | return root; 33 | } 34 | 35 | void __pre_order(Node *root) { 36 | // status = 0 37 | if (root == NULL) return ; // status = 100 38 | printf("%d\n", root->data); // status = 1 39 | __pre_order(root->lchild); // status = 2 40 | __pre_order(root->rchild); // status = 3 41 | return ; // status = 100 42 | } 43 | 44 | typedef struct PreOrderArgs { 45 | Node *root; 46 | int status; 47 | } PreOrderArgs; 48 | 49 | PreOrderArgs *getNewArgs(Node *root) { 50 | PreOrderArgs *p = (PreOrderArgs *)malloc(sizeof(PreOrderArgs) * 1); 51 | p->root = root; 52 | p->status = 0; 53 | return p; 54 | } 55 | 56 | void pre_order(Node *root) { 57 | Stack *s = init_stack(100, PreOrderArgs); 58 | PreOrderArgs *temp_args = getNewArgs(root), *p_args; 59 | push_stack(s, temp_args); 60 | while (!empty_stack(s)) { 61 | p_args = top_stack(s, PreOrderArgs); 62 | switch (p_args->status) { 63 | case 0: { 64 | if (p_args->root == NULL) { 65 | p_args->status = 100; 66 | } else { 67 | p_args->status = 1; 68 | } 69 | } break; 70 | case 1: { 71 | printf("%d\n", p_args->root->data); 72 | p_args->status = 2; 73 | } break; 74 | case 2: { 75 | temp_args->root = p_args->root->lchild; 76 | temp_args->status = 0; 77 | push_stack(s, temp_args); 78 | p_args->status = 3; 79 | } break; 80 | case 3: { 81 | temp_args->root = p_args->root->rchild; 82 | temp_args->status = 0; 83 | push_stack(s, temp_args); 84 | p_args->status = 100; 85 | } break; 86 | case 100: { 87 | pop_stack(s); 88 | } break; 89 | } 90 | } 91 | free(temp_args); 92 | clear_stack(s); 93 | return ; 94 | } 95 | 96 | 97 | 98 | int main() { 99 | Node *root = init_binary_tree(); 100 | pre_order(root); 101 | __pre_order(root); 102 | return 0; 103 | } -------------------------------------------------------------------------------- /第3章:树与二叉树/2、哈夫曼编码/1、haffman.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 6.haffman.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 日 7/21 20:30:55 2019 7 | ************************************************************************/ 8 | 9 | #include 10 | #include 11 | #include 12 | #define MAX_N 1000 13 | #define swap(a, b) { \ 14 | __typeof(a) temp = a; \ 15 | a = b, b = temp; \ 16 | } 17 | 18 | typedef struct Node { 19 | char ch; 20 | double p; 21 | struct Node *next[2]; 22 | } Node; 23 | 24 | typedef struct Code { 25 | char ch; 26 | char *str; 27 | } Code; 28 | 29 | typedef struct HaffmanTree { 30 | Node *root; 31 | int n; 32 | Code *codes; 33 | } HaffmanTree; 34 | 35 | typedef struct Data { 36 | char ch; 37 | double p; 38 | } Data; 39 | 40 | Data arr[MAX_N + 5]; 41 | 42 | Node *getNewNode(Data *obj) { 43 | Node *p = (Node *)malloc(sizeof(Node)); 44 | p->ch = (obj ? obj->ch : 0); 45 | p->p = (obj ? obj->p : 0); 46 | p->next[0] = p->next[1] = NULL; 47 | return p; 48 | } 49 | 50 | HaffmanTree *getNewTree(int n) { 51 | HaffmanTree *tree = (HaffmanTree *)malloc(sizeof(HaffmanTree)); 52 | tree->codes = (Code *)malloc(sizeof(Code) * n); 53 | tree->root = NULL; 54 | tree->n = n; 55 | return tree; 56 | } 57 | 58 | void insertOnce(Node **arr, int n) { 59 | for (int j = n; j >= 1; j--) { 60 | if (arr[j]->p > arr[j - 1]->p) { 61 | swap(arr[j], arr[j - 1]); 62 | continue; 63 | } 64 | break; 65 | } 66 | return ; 67 | } 68 | 69 | int extractCodes(Node *root, Code *arr, int k, int l, char *buff) { 70 | buff[l] = 0; 71 | if (root->next[0] == NULL && root->next[1] == NULL) { 72 | arr[k].ch = root->ch; 73 | arr[k].str = strdup(buff); 74 | return 1; 75 | } 76 | int delta = 0; 77 | buff[l] = '0'; 78 | delta += extractCodes(root->next[0], arr, k + delta, l + 1, buff); 79 | buff[l] = '1'; 80 | delta += extractCodes(root->next[1], arr, k + delta, l + 1, buff); 81 | return delta; 82 | } 83 | 84 | HaffmanTree *build(Data *arr, int n) { 85 | Node **nodes = (Node **)malloc(sizeof(Node *) * n); 86 | for (int i = 0; i < n; i++) { 87 | nodes[i] = getNewNode(arr + i); 88 | } 89 | for (int i = 1; i < n; i++) { 90 | insertOnce(nodes, i); 91 | } 92 | for (int i = n - 1; i >= 1; i--) { 93 | Node *p = getNewNode(NULL); 94 | p->next[0] = nodes[i - 1]; 95 | p->next[1] = nodes[i]; 96 | p->p = p->next[0]->p + p->next[1]->p; 97 | nodes[i - 1] = p; 98 | insertOnce(nodes, i - 1); 99 | } 100 | char *buff = (char *)malloc(sizeof(char) * n); 101 | HaffmanTree *tree = getNewTree(n); 102 | tree->root = nodes[0]; 103 | extractCodes(tree->root, tree->codes, 0, 0, buff); 104 | free(nodes); 105 | free(buff); 106 | return tree; 107 | } 108 | 109 | int main() { 110 | int n; 111 | char str[10]; 112 | scanf("%d", &n); 113 | for (int i = 0; i < n; i++) { 114 | scanf("%s%lf", str, &arr[i].p); 115 | arr[i].ch = str[0]; 116 | } 117 | HaffmanTree *tree = build(arr, n); 118 | for (int i = 0; i < tree->n; i++) { 119 | printf("%c : %s\n", tree->codes[i].ch, tree->codes[i].str); 120 | } 121 | return 0; 122 | } -------------------------------------------------------------------------------- /第11章:树状数组与线段树/3、HZOJ-333-最大子段和/1、HZOJ-333-最大子段和.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 333.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 六 8/24 20:52:55 2019 7 | ************************************************************************/ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | using namespace std; 18 | #define MAX_N 500000 19 | #define lc(ind) (tree[ind].lind) 20 | #define rc(ind) (tree[ind].rind) 21 | #define SUM(ind) tree[ind].sum 22 | #define MAX(ind) tree[ind].m 23 | #define LMAX(ind) tree[ind].lm 24 | #define RMAX(ind) tree[ind].rm 25 | 26 | struct node { 27 | int sum, m, lm, rm; 28 | int lind, rind; 29 | } tree[(MAX_N << 1) + 5]; 30 | int root = 3, cnt = 4, ans = 0, temp = 1; 31 | int arr[MAX_N + 5]; 32 | inline int getNode() { return cnt++; } 33 | 34 | void UP(int a, int b, int c) { 35 | SUM(a) = SUM(b) + SUM(c); 36 | LMAX(a) = max(LMAX(b), SUM(b) + LMAX(c)); 37 | RMAX(a) = max(RMAX(c), SUM(c) + RMAX(b)); 38 | MAX(a) = max(MAX(b), MAX(c)); 39 | MAX(a) = max(MAX(a), RMAX(b) + LMAX(c)); 40 | return ; 41 | } 42 | 43 | void UP(int ind) { 44 | UP(ind, lc(ind), rc(ind)); 45 | } 46 | 47 | void build(int ind, int l, int r) { 48 | if (l == r) { 49 | SUM(ind) = MAX(ind) = LMAX(ind) = RMAX(ind) = arr[l]; 50 | return ; 51 | } 52 | int mid = (l + r) >> 1; 53 | lc(ind) = getNode(); 54 | rc(ind) = getNode(); 55 | build(lc(ind), l, mid); 56 | build(rc(ind), mid + 1, r); 57 | UP(ind); 58 | return ; 59 | } 60 | 61 | void modify(int ind, int x, int y, int l, int r) { 62 | if (l == r) { 63 | SUM(ind) = MAX(ind) = LMAX(ind) = RMAX(ind) = y; 64 | 65 | return ; 66 | } 67 | int mid = (l + r) >> 1; 68 | if (x <= mid) modify(lc(ind), x, y, l, mid); 69 | else modify(rc(ind), x, y, mid + 1, r); 70 | UP(ind); 71 | return ; 72 | } 73 | 74 | void query(int ind, int x, int y, int l, int r) { 75 | if (x <= l && r <= y) { 76 | if (x == l) tree[ans] = tree[ind]; 77 | else { 78 | UP(temp, ans, ind); 79 | swap(temp, ans); 80 | } 81 | return ; 82 | } 83 | int mid = (l + r) >> 1; 84 | if (x <= mid) query(lc(ind), x, y, l, mid); 85 | if (y > mid) query(rc(ind), x, y, mid + 1, r); 86 | return ; 87 | } 88 | 89 | ostream &operator<<(ostream &out, node &a) { 90 | out << (&a - tree) << " : " << a.sum << " " << a.m << " " << a.lm << " " << a.rm; 91 | out << "(" << a.lind << "," << a.rind << ")"; 92 | return out; 93 | } 94 | 95 | void output(int n) { 96 | for (int i = root; i < root + 2 * n - 1; i++) { 97 | cout << tree[i] << endl; 98 | } 99 | cout << "---------" << endl; 100 | } 101 | 102 | int main() { 103 | int n, m; 104 | cin >> n >> m; 105 | for (int i = 1; i <= n; i++) cin >> arr[i]; 106 | build(root, 1, n); 107 | for (int i = 0; i < m; i++) { 108 | int a, b, c; 109 | cin >> a >> b >> c; 110 | if (a == 1) { 111 | if (b > c) swap(b, c); 112 | query(root, b, c, 1, n); 113 | cout << MAX(ans) << endl; 114 | } else { 115 | modify(root, b, c, 1, n); 116 | } 117 | //output(n); 118 | } 119 | return 0; 120 | } -------------------------------------------------------------------------------- /第10章:森林与并查集/7、演示代码(四)/4、Leetcode-685.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 685.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 四 5/23 19:49:43 2019 7 | ************************************************************************/ 8 | 9 | /** 10 | * Return an array of size *returnSize. 11 | * Note: The returned array must be malloced, assume caller calls free(). 12 | */ 13 | 14 | typedef struct UnionSet { 15 | int *fa; 16 | int *size; 17 | int n; 18 | int cnt; 19 | } UnionSet; 20 | 21 | UnionSet *init(int n) { 22 | UnionSet *u = (UnionSet *)malloc(sizeof(UnionSet)); 23 | u->fa = (int *)malloc(sizeof(int) * n); 24 | u->size = (int *)malloc(sizeof(int) * n); 25 | u->n = n; 26 | u->cnt = n; 27 | for (int i = 0; i < n; i++) { 28 | u->fa[i] = i; 29 | u->size[i] = 1; 30 | } 31 | return u; 32 | } 33 | 34 | int find(UnionSet *u, int x) { 35 | if (u->fa[x] == x) return x; 36 | return (u->fa[x] = find(u, u->fa[x])); 37 | } 38 | 39 | int merge(UnionSet *u, int a, int b) { 40 | int f[2] = { find(u, a), find(u, b) }; 41 | if (f[1] == f[0]) return 0; 42 | int flag = (u->size[f[0]] > u->size[f[1]]); 43 | u->fa[f[flag]] = f[!flag]; 44 | u->size[f[!flag]] += u->size[f[flag]]; 45 | u->cnt -= 1; 46 | return 1; 47 | } 48 | 49 | void clear(UnionSet *u) { 50 | if (u == NULL) return ; 51 | free(u->fa); 52 | free(u->size); 53 | free(u); 54 | return ; 55 | } 56 | 57 | int* findRedundantDirectedConnection(int** edges, int n, int m, int* returnSize) { 58 | int *ret = (int *)calloc(sizeof(int), 2); 59 | *returnSize = 2; 60 | int *indeg = (int *)calloc(sizeof(int), n + 1); 61 | int *outdeg = (int *)calloc(sizeof(int), n + 1); 62 | int *father = (int *)calloc(sizeof(int), n + 1); 63 | int *queue = (int *)calloc(sizeof(int), n + 1); 64 | int head = 0, tail = 0; 65 | for (int i = 0; i < n; i++) { 66 | indeg[edges[i][1]] += 1; 67 | outdeg[edges[i][0]] += 1; 68 | father[edges[i][1]] = edges[i][0]; 69 | } 70 | int flag = 0; 71 | for (int i = 1; i <= n; i++) { 72 | flag = (indeg[i] == 2); 73 | if (flag) { flag = i; break; } 74 | } 75 | if (flag) { 76 | for (int i = n - 1; i >= 0; --i) { 77 | if (edges[i][1] - flag) continue; 78 | UnionSet *u = init(n + 1); 79 | for (int j = 0; j < n; j++) { 80 | if (i == j) continue; 81 | merge(u, edges[j][0], edges[j][1]); 82 | } 83 | if (u->cnt != 2) { 84 | clear(u); 85 | continue; 86 | } 87 | ret[0] = edges[i][0]; 88 | ret[1] = edges[i][1]; 89 | clear(u); 90 | break; 91 | } 92 | } else { 93 | for (int i = 1; i <= n; i++) { 94 | if (outdeg[i]) continue; 95 | queue[tail++] = i; 96 | } 97 | while (head < tail) { 98 | int ind = queue[head++]; 99 | if (!(--outdeg[father[ind]])) queue[tail++] = father[ind]; 100 | } 101 | for (int i = n - 1; i >= 0; i--) { 102 | if (outdeg[edges[i][0]] && outdeg[edges[i][1]]) { 103 | ret[0] = edges[i][0]; 104 | ret[1] = edges[i][1]; 105 | break; 106 | } 107 | } 108 | } 109 | return ret; 110 | } -------------------------------------------------------------------------------- /第8章:字符串匹配算法(3)/1、AC 自动机/1、基于字典树的 AC 自动机.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 19.ac.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 日 1/13 20:43:58 2019 7 | ************************************************************************/ 8 | 9 | #include 10 | #include 11 | #include 12 | #define BASE 26 13 | #define BEGIN_LETTER 'a' 14 | 15 | typedef struct Node { 16 | int flag; 17 | struct Node *next[BASE], *fail; 18 | } Node; 19 | 20 | typedef struct Queue { 21 | Node **data; 22 | int head, tail, size; 23 | } Queue; 24 | 25 | Queue *init_queue(int n) { 26 | Queue *q = (Queue *)calloc(sizeof(Queue), 1); 27 | q->data = (Node **)malloc(sizeof(Node *) * n); 28 | q->tail = q->head = 0; 29 | return q; 30 | } 31 | 32 | Node *front(Queue *q) { 33 | return q->data[q->head]; 34 | } 35 | 36 | int empty(Queue *q) { 37 | return q->head == q->tail; 38 | } 39 | 40 | void push(Queue *q, Node *node) { 41 | q->data[q->tail++] = node; 42 | return ; 43 | } 44 | 45 | void pop(Queue *q) { 46 | if (empty(q)) return ; 47 | q->head++; 48 | } 49 | 50 | void clear_queue(Queue *q) { 51 | if (q == NULL) return ; 52 | free(q->data); 53 | free(q); 54 | return ; 55 | } 56 | 57 | Node *getNewNode() { 58 | Node *p = (Node *)calloc(sizeof(Node), 1); 59 | return p; 60 | } 61 | 62 | int insert(Node *root, const char *str) { 63 | int cnt = 0; 64 | Node *p = root; 65 | for (int i = 0; str[i]; i++) { 66 | int ind = str[i] - BEGIN_LETTER; 67 | if (p->next[ind] == NULL) p->next[ind] = getNewNode(), ++cnt; 68 | p = p->next[ind]; 69 | } 70 | p->flag = 1; 71 | return cnt; 72 | } 73 | 74 | void clear(Node *node) { 75 | if (node == NULL) return ; 76 | for (int i = 0; i < BASE; i++) { 77 | clear(node->next[i]); 78 | } 79 | free(node); 80 | return ; 81 | } 82 | 83 | void build_ac(Node *root, int n) { 84 | Queue *q = init_queue(n + 10); 85 | root->fail = NULL; 86 | push(q, root); 87 | while (!empty(q)) { 88 | Node *now_node = front(q); 89 | pop(q); 90 | for (int i = 0; i < BASE; i++) { 91 | if (now_node->next[i] == NULL) continue; 92 | Node *p = now_node->fail; 93 | while (p && p->next[i] == NULL) p = p->fail; 94 | if (p == NULL) now_node->next[i]->fail = root; 95 | else now_node->next[i]->fail = p->next[i]; 96 | push(q, now_node->next[i]); 97 | } 98 | } 99 | return ; 100 | } 101 | 102 | int match(Node *root, const char *str) { 103 | int cnt = 0; 104 | Node *p = root; 105 | for (int i = 0; str[i]; i++) { 106 | int ind = str[i] - BEGIN_LETTER; 107 | while (p && p->next[ind] == NULL) p = p->fail; 108 | if (p == NULL) p = root; 109 | else p = p->next[ind]; 110 | Node *q = p; 111 | while (q) cnt += q->flag, q = q->fail; 112 | } 113 | return cnt; 114 | } 115 | 116 | int main() { 117 | Node *root = getNewNode(); 118 | int n, cnt = 0; 119 | char str[1000]; 120 | scanf("%d", &n); 121 | for (int i = 0; i < n; i++) { 122 | scanf("%s", str); 123 | cnt += insert(root, str); 124 | } 125 | // build ac 126 | build_ac(root, cnt); 127 | scanf("%s", str); 128 | // match ac 129 | printf("match word cnt : %d\n", match(root, str)); 130 | return 0; 131 | } -------------------------------------------------------------------------------- /第10章:森林与并查集/6、演示代码(三)/2、Leetcode-128.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 128.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 四 5/23 18:48:22 2019 7 | ************************************************************************/ 8 | #define MC(T, n) (T *)malloc(sizeof(T) * (n)) 9 | #define CC(T, n) (T *)calloc(sizeof(T), (n)) 10 | 11 | typedef struct Node { 12 | int val, ind; 13 | } Node; 14 | 15 | typedef struct HashTable { 16 | Node *data; 17 | int *flag; 18 | int n; 19 | } HashTable; 20 | 21 | typedef struct UnionSet { 22 | int *fa; 23 | int *size; 24 | int n; 25 | } UnionSet; 26 | 27 | UnionSet *init_UnionSet(int n) { 28 | UnionSet *u = MC(UnionSet, 1); 29 | u->fa = MC(int, n); 30 | u->size = MC(int, n); 31 | for (int i = 0; i < n; i++) u->fa[i] = i, u->size[i] = 1; 32 | u->n = n; 33 | return u; 34 | } 35 | 36 | void clear_UnionSet(UnionSet *u) { 37 | if (u == NULL) return ; 38 | free(u->fa); 39 | free(u->size); 40 | free(u); 41 | return ; 42 | } 43 | 44 | HashTable *init_HashTable(int n) { 45 | HashTable *h = MC(HashTable, 1); 46 | h->data = MC(Node, n); 47 | h->flag = CC(int, n / 31 + 1); 48 | h->n = n; 49 | return h; 50 | } 51 | 52 | void clear_HashTable(HashTable *h) { 53 | if (h == NULL) return ; 54 | free(h->data); 55 | free(h->flag); 56 | free(h); 57 | return ; 58 | } 59 | 60 | int get(UnionSet *u, int x) { 61 | if (u->fa[x] == x) return x; 62 | return u->fa[x] = get(u, u->fa[x]); 63 | } 64 | 65 | void merge(UnionSet *u, int a, int b) { 66 | int aa = get(u, a), bb = get(u, b); 67 | if (aa == bb) return ; 68 | u->fa[aa] = bb; 69 | u->size[bb] += u->size[aa]; 70 | return ; 71 | } 72 | 73 | int hash(int val) { 74 | return val & 0x7fffffff; 75 | } 76 | 77 | int check(HashTable *h, int ind) { 78 | int x = ind / 31, y = ind % 31; 79 | return h->flag[x] & (1 << y); 80 | } 81 | 82 | void set_HashTable(HashTable *h, int now, int val, int ind) { 83 | int x = now / 31, y = now % 31; 84 | h->flag[x] |= (1 << y); 85 | h->data[now].val = val; 86 | h->data[now].ind = ind; 87 | return ; 88 | } 89 | 90 | int insert(HashTable *h, int val, int ind) { 91 | int now = hash(val) % h->n; 92 | int time = 1; 93 | while (check(h, now) && h->data[now].val != val) { 94 | now += (time * time); 95 | now %= h->n; 96 | time++; 97 | } 98 | if (check(h, now)) return 0; 99 | set_HashTable(h, now, val, ind); 100 | return 1; 101 | } 102 | 103 | int query(HashTable *h, int val) { 104 | int now = hash(val) % h->n; 105 | int time = 1; 106 | while (check(h, now) && h->data[now].val != val) { 107 | now += (time * time); 108 | now %= h->n; 109 | time++; 110 | } 111 | if (check(h, now)) return h->data[now].ind; 112 | return -1; 113 | } 114 | 115 | int longestConsecutive(int* nums, int n) { 116 | HashTable *h = init_HashTable(n * 3); 117 | UnionSet *u = init_UnionSet(n); 118 | for (int i = 0; i < n; i++) { 119 | if (!insert(h, nums[i], i)) continue; 120 | int ind1 = query(h, nums[i] + 1); 121 | int ind2 = query(h, nums[i] - 1); 122 | if (ind1 != -1) merge(u, i, ind1); 123 | if (ind2 != -1) merge(u, i, ind2); 124 | } 125 | int ans = 0; 126 | for (int i = 0; i < n; i++) { 127 | if (u->size[i] > ans) ans = u->size[i]; 128 | } 129 | clear_UnionSet(u); 130 | clear_HashTable(h); 131 | return ans; 132 | } -------------------------------------------------------------------------------- /第4章:堆与优先队列/3、演示代码(一)/2、Leetcode-295.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 295.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 六 4/27 21:20:04 2019 7 | ************************************************************************/ 8 | 9 | 10 | 11 | typedef struct Heap { 12 | int *data; 13 | int n, size; 14 | } Heap; 15 | 16 | void expandHeap(Heap *h) { 17 | h->data = realloc(h->data, 2 * h->size * sizeof(int)); 18 | h->size *= 2; 19 | return ; 20 | } 21 | 22 | #define swap(a, b) { \ 23 | __typeof(a) __temp = a; \ 24 | a = b, b = __temp; \ 25 | } 26 | 27 | #define pushHeap(h, val, comp) { \ 28 | if (h->size == h->n + 1) { \ 29 | expandHeap(h); \ 30 | } \ 31 | h->data[++(h->n)] = val; \ 32 | int ind = h->n; \ 33 | while (ind != 1 && h->data[ind] comp h->data[ind >> 1]) { \ 34 | swap(h->data[ind], h->data[ind >> 1]); \ 35 | ind >>= 1; \ 36 | } \ 37 | } 38 | 39 | #define popHeap(h, comp) do { \ 40 | if (h->n == 0) break; \ 41 | h->data[1] = h->data[(h->n)--]; \ 42 | int ind = 1; \ 43 | while (ind << 1 <= h->n) { \ 44 | int temp = ind, l = ind << 1, r = ind << 1 | 1; \ 45 | if (h->data[l] comp h->data[temp]) temp = l; \ 46 | if (r <= h->n && h->data[r] comp h->data[temp]) temp = r; \ 47 | if (temp == ind) break; \ 48 | swap(h->data[temp], h->data[ind]); \ 49 | ind = temp; \ 50 | } \ 51 | } while(0); 52 | 53 | Heap *creatHeap() { 54 | Heap *h = (Heap *)malloc(sizeof(Heap)); 55 | h->size = 100; 56 | h->data = (int *)malloc(sizeof(int) * h->size); 57 | h->n = 0; 58 | return h; 59 | } 60 | 61 | void clearHeap(Heap *h) { 62 | if (h == NULL) return ; 63 | free(h->data); 64 | free(h); 65 | return ; 66 | } 67 | 68 | typedef struct { 69 | Heap *min_heap, *max_heap; 70 | } MedianFinder; 71 | 72 | /** initialize your data structure here. */ 73 | 74 | MedianFinder* medianFinderCreate() { 75 | MedianFinder* m = (MedianFinder*)malloc(sizeof(MedianFinder)); 76 | m->min_heap = creatHeap(); 77 | m->max_heap = creatHeap(); 78 | return m; 79 | } 80 | 81 | void medianFinderAddNum(MedianFinder* m, int num) { 82 | if (m->min_heap->n == 0 || num >= m->min_heap->data[1]) { 83 | pushHeap(m->min_heap, num, <); 84 | } else { 85 | pushHeap(m->max_heap, num, >); 86 | } 87 | if (m->min_heap->n - m->max_heap->n == 2) { 88 | pushHeap(m->max_heap, m->min_heap->data[1], >); 89 | popHeap(m->min_heap, <); 90 | } 91 | if (m->max_heap->n - m->min_heap->n == 2) { 92 | pushHeap(m->min_heap, m->max_heap->data[1], <); 93 | popHeap(m->max_heap, >); 94 | } 95 | return ; 96 | } 97 | 98 | double medianFinderFindMedian(MedianFinder* m) { 99 | switch (m->min_heap->n - m->max_heap->n) { 100 | case -1: return m->max_heap->data[1]; 101 | case 0: return 1.0 * (m->min_heap->data[1] + m->max_heap->data[1]) / 2.0; 102 | case 1: return m->min_heap->data[1]; 103 | } 104 | return 0.0; 105 | } 106 | 107 | void medianFinderFree(MedianFinder* obj) { 108 | if (obj == NULL) return ; 109 | clearHeap(obj->min_heap); 110 | clearHeap(obj->max_heap); 111 | free(obj); 112 | return ; 113 | } 114 | 115 | /** 116 | * Your MedianFinder struct will be instantiated and called as such: 117 | * MedianFinder* obj = medianFinderCreate(); 118 | * medianFinderAddNum(obj, num); 119 | 120 | * double param_2 = medianFinderFindMedian(obj); 121 | 122 | * medianFinderFree(obj); 123 | */ -------------------------------------------------------------------------------- /第3章:树与二叉树/1、树与二叉树/1、binary_tree.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 5.binary_tree.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 日 7/21 15:48:09 2019 7 | ************************************************************************/ 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | typedef struct Node { 14 | int val; 15 | struct Node *lchild, *rchild; 16 | } Node; 17 | 18 | typedef struct Tree { 19 | Node *root; 20 | int n; 21 | } Tree; 22 | 23 | Node *getNewNode(int val) { 24 | Node *p = (Node *)malloc(sizeof(Node)); 25 | p->val = val; 26 | p->lchild = p->rchild = NULL; 27 | return p; 28 | } 29 | 30 | Tree *getNewTree() { 31 | Tree *tree = (Tree *)malloc(sizeof(Tree)); 32 | tree->n = 0; 33 | tree->root = NULL; 34 | return tree; 35 | } 36 | 37 | Node *insertNode(Node *root, int val, int *ret) { 38 | if (root == NULL) { 39 | *ret = 1; 40 | return getNewNode(val); 41 | } 42 | if (root->val == val) return root; 43 | if (root->val > val) root->lchild = insertNode(root->lchild, val, ret); 44 | else root->rchild = insertNode(root->rchild, val, ret); 45 | return root; 46 | } 47 | 48 | void insert(Tree *tree, int val) { 49 | int flag = 0; 50 | tree->root = insertNode(tree->root, val, &flag); 51 | tree->n += flag; 52 | return ; 53 | } 54 | 55 | void clearNode(Node *node) { 56 | if (node == NULL) return ; 57 | clearNode(node->lchild); 58 | clearNode(node->rchild); 59 | free(node); 60 | return ; 61 | } 62 | 63 | void clearTree(Tree *tree) { 64 | clearNode(tree->root); 65 | free(tree); 66 | return ; 67 | } 68 | 69 | void outputNode(Node *root) { 70 | if (root == NULL) return ; 71 | printf("%d", root->val); 72 | if (root->lchild == NULL && root->rchild == NULL) return ; 73 | printf("("); 74 | outputNode(root->lchild); 75 | printf(","); 76 | outputNode(root->rchild); 77 | printf(")"); 78 | return ; 79 | } 80 | 81 | void outputTree(Tree *tree) { 82 | printf("tree(%d) = ", tree->n); 83 | outputNode(tree->root); 84 | printf("\n"); 85 | return ; 86 | } 87 | 88 | 89 | void preorderNode(Node *node) { 90 | if (node == NULL) return ; 91 | printf(" %d", node->val); 92 | preorderNode(node->lchild); 93 | preorderNode(node->rchild); 94 | return ; 95 | } 96 | 97 | void preorder(Tree *tree) { 98 | printf("pre order : "); 99 | preorderNode(tree->root); 100 | printf("\n"); 101 | return ; 102 | } 103 | 104 | void inorderNode(Node *node) { 105 | if (node == NULL) return ; 106 | inorderNode(node->lchild); 107 | printf(" %d", node->val); 108 | inorderNode(node->rchild); 109 | return ; 110 | } 111 | 112 | void inorder(Tree *tree) { 113 | printf("in order : "); 114 | inorderNode(tree->root); 115 | printf("\n"); 116 | return ; 117 | } 118 | 119 | void postorderNode(Node *node) { 120 | if (node == NULL) return ; 121 | postorderNode(node->lchild); 122 | postorderNode(node->rchild); 123 | printf(" %d", node->val); 124 | return ; 125 | } 126 | 127 | void postorder(Tree *tree) { 128 | printf("post order : "); 129 | postorderNode(tree->root); 130 | printf("\n"); 131 | return ; 132 | } 133 | 134 | int main() { 135 | srand(time(0)); 136 | Tree *tree = getNewTree(); 137 | for (int i = 0; i < 10; i++) { 138 | int val = rand() % 100; 139 | insert(tree, val); 140 | outputTree(tree); 141 | } 142 | preorder(tree); 143 | inorder(tree); 144 | postorder(tree); 145 | clearTree(tree); 146 | return 0; 147 | } -------------------------------------------------------------------------------- /第2章:栈和队列/4、演示代码(栈&队列)/2、Leetcode-225.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 225.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 三 7/17 19:50:12 2019 7 | ************************************************************************/ 8 | 9 | typedef struct { 10 | int *data; 11 | int head, tail; 12 | int size, cnt; 13 | } MyQueue; 14 | 15 | MyQueue* myQueueCreate(int size) { 16 | MyQueue *q = (MyQueue *)malloc(sizeof(MyQueue)); 17 | q->data = (int *)malloc(sizeof(int) * size); 18 | q->size = size; 19 | q->cnt = 0; 20 | q->head = q->tail = 0; 21 | return q; 22 | } 23 | 24 | /** Push element x onto stack. */ 25 | void myQueuePush(MyQueue* obj, int x) { 26 | if (obj == NULL) return ; 27 | if (obj->cnt == obj->size) return ; 28 | obj->data[obj->tail++] = x; 29 | if (obj->tail == obj->size) obj->tail -= obj->size; 30 | obj->cnt += 1; 31 | return ; 32 | } 33 | 34 | /** Removes the element on top of the stack and returns that element. */ 35 | int myQueuePop(MyQueue* obj) { 36 | if (obj == NULL) return 0; 37 | if (obj->cnt == 0) return 0; 38 | obj->head += 1; 39 | if (obj->head == obj->size) obj->head -= obj->size; 40 | obj->cnt -= 1; 41 | return 1; 42 | } 43 | 44 | /** Get the top element. */ 45 | int myQueueFront(MyQueue* obj) { 46 | return obj->data[obj->head]; 47 | } 48 | 49 | /** Returns whether the stack is empty. */ 50 | bool myQueueEmpty(MyQueue* obj) { 51 | return obj->cnt == 0; 52 | } 53 | 54 | void myQueueFree(MyQueue* obj) { 55 | if (obj == NULL) return ; 56 | free(obj->data); 57 | free(obj); 58 | return ; 59 | } 60 | 61 | typedef struct { 62 | MyQueue *q1, *q2; 63 | } MyStack; 64 | 65 | /** Initialize your data structure here. */ 66 | 67 | MyStack* myStackCreate() { 68 | MyStack *s = (MyStack *)malloc(sizeof(MyStack)); 69 | s->q1 = myQueueCreate(100); 70 | s->q2 = myQueueCreate(100); 71 | return s; 72 | } 73 | 74 | /** Push element x onto stack. */ 75 | void myStackPush(MyStack* obj, int x) { 76 | if (!myQueueEmpty(obj->q1)) { 77 | myQueuePush(obj->q1, x); 78 | } else { 79 | myQueuePush(obj->q2, x); 80 | } 81 | return ; 82 | } 83 | 84 | /** Removes the element on top of the stack and returns that element. */ 85 | int myStackPop(MyStack* obj) { 86 | MyQueue *p = myQueueEmpty(obj->q1) ? obj->q2 : obj->q1; 87 | MyQueue *q = myQueueEmpty(obj->q1) ? obj->q1 : obj->q2; 88 | int element = myQueueFront(p); 89 | myQueuePop(p); 90 | while (!myQueueEmpty(p)) { 91 | myQueuePush(q, element); 92 | element = myQueueFront(p); 93 | myQueuePop(p); 94 | } 95 | return element; 96 | } 97 | 98 | /** Get the top element. */ 99 | int myStackTop(MyStack* obj) { 100 | MyQueue *p = myQueueEmpty(obj->q1) ? obj->q2 : obj->q1; 101 | MyQueue *q = myQueueEmpty(obj->q1) ? obj->q1 : obj->q2; 102 | int element; 103 | while (!myQueueEmpty(p)) { 104 | element = myQueueFront(p); 105 | myQueuePop(p); 106 | myQueuePush(q, element); 107 | } 108 | return element; 109 | } 110 | 111 | /** Returns whether the stack is empty. */ 112 | bool myStackEmpty(MyStack* obj) { 113 | return myQueueEmpty(obj->q1) && myQueueEmpty(obj->q2); 114 | } 115 | 116 | void myStackFree(MyStack* obj) { 117 | if (obj == NULL) return ; 118 | myQueueFree(obj->q1); 119 | myQueueFree(obj->q2); 120 | free(obj); 121 | return ; 122 | } 123 | 124 | /** 125 | * Your MyStack struct will be instantiated and called as such: 126 | * MyStack* obj = myStackCreate(); 127 | * myStackPush(obj, x); 128 | 129 | * int param_2 = myStackPop(obj); 130 | 131 | * int param_3 = myStackTop(obj); 132 | 133 | * bool param_4 = myStackEmpty(obj); 134 | 135 | * myStackFree(obj); 136 | */ -------------------------------------------------------------------------------- /第7章:字符串匹配算法(2)/2、双数组字典树/1、DATrie.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 12.double_array_trie.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 三 8/21 14:14:38 2019 7 | ************************************************************************/ 8 | 9 | #include 10 | #include 11 | #include 12 | #define BASE 26 13 | #define BEGIN_LETTER 'a' 14 | 15 | typedef struct Node { 16 | int flag; 17 | struct Node *next[BASE]; 18 | } Node; 19 | 20 | typedef struct DATrie { 21 | int *base, *check; 22 | int root, size; 23 | } DATrie; 24 | 25 | DATrie *getDATrie(int n) { 26 | DATrie *tree = (DATrie *)calloc(sizeof(DATrie), 1); 27 | tree->root = 1; 28 | tree->size = n; 29 | tree->base = (int *)calloc(sizeof(int), n); 30 | tree->check = (int *)calloc(sizeof(int), n); 31 | tree->check[tree->root] = 1; 32 | return tree; 33 | } 34 | 35 | Node *getNewNode() { 36 | Node *p = (Node *)calloc(sizeof(Node), 1); 37 | return p; 38 | } 39 | 40 | int insert(Node *root, const char *str) { 41 | int cnt = 0; 42 | Node *p = root; 43 | for (int i = 0; str[i]; i++) { 44 | int ind = str[i] - BEGIN_LETTER; 45 | if (p->next[ind] == NULL) p->next[ind] = getNewNode(), cnt += 1; 46 | p = p->next[ind]; 47 | } 48 | p->flag = 1; 49 | return cnt; 50 | } 51 | 52 | void clear(Node *root) { 53 | if (root == NULL) return ; 54 | for (int i = 0; i < BASE; i++) { 55 | clear(root->next[i]); 56 | } 57 | free(root); 58 | return ; 59 | } 60 | 61 | int getBaseValue(Node *root, DATrie *tree) { 62 | int base = 0, flag; 63 | do { 64 | flag = 1; 65 | base += 1; 66 | for (int i = 0; i < BASE; i++) { 67 | if (root->next[i] == NULL) continue; 68 | if (tree->check[base + i] == 0) continue; 69 | flag = 0; 70 | break; 71 | } 72 | } while (!flag); 73 | return base; 74 | } 75 | 76 | int buildDATrie(int ind, Node *root, DATrie *tree) { 77 | int base = tree->base[ind] = getBaseValue(root, tree); 78 | int ans = ind; 79 | for (int i = 0; i < BASE; i++) { 80 | if (root->next[i] == NULL) continue; 81 | tree->check[base + i] = ind; 82 | } 83 | for (int i = 0; i < BASE; i++) { 84 | if (root->next[i] == NULL) continue; 85 | int temp = buildDATrie(base + i, root->next[i], tree); 86 | if (temp > ans) ans = temp; 87 | } 88 | if (root->flag) tree->check[ind] = -tree->check[ind]; 89 | return ans; 90 | } 91 | 92 | int query(DATrie *tree, const char *str) { 93 | int p = tree->root; 94 | for (int i = 0; str[i]; i++) { 95 | int ind = str[i] - BEGIN_LETTER; 96 | if (abs(tree->check[tree->base[p] + ind]) != p) return 0; 97 | p = tree->base[p] + ind; 98 | } 99 | return tree->check[p] < 0; 100 | } 101 | 102 | void clearDA(DATrie *tree) { 103 | if (tree == NULL) return ; 104 | free(tree->base); 105 | free(tree->check); 106 | free(tree); 107 | return ; 108 | } 109 | 110 | int main() { 111 | int n, cnt1 = 1, cnt2; 112 | char str[100]; 113 | scanf("%d", &n); 114 | Node *root = getNewNode(); 115 | while (n--) { 116 | scanf("%s", str); 117 | cnt1 += insert(root, str); 118 | } 119 | DATrie *tree = getDATrie(cnt1 * BASE + 5); 120 | cnt2 = buildDATrie(tree->root, root, tree) + 1; 121 | while (~scanf("%s", str)) { 122 | printf("search %s, result = %s\n", str, query(tree, str) ? "YES" : "NO"); 123 | } 124 | int mem1 = cnt1 * sizeof(Node), mem2 = cnt2 * sizeof(int) * 2 + sizeof(int) * 2; 125 | printf("Trie memory : %d Bytes\n", mem1); 126 | printf("Double Array Trie memory : %d Bytes\n", mem2); 127 | printf("memory rate : %.4lf%%\n", 1.0 * mem2 / mem1 * 100); 128 | clearDA(tree); 129 | clear(root); 130 | return 0; 131 | } -------------------------------------------------------------------------------- /第12章:平衡二叉查找树/2、平衡二叉排序树/1、AVL.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 14.AVL.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 四 9/19 18:28:02 2019 7 | ************************************************************************/ 8 | 9 | #include 10 | #include 11 | 12 | typedef struct Node { 13 | int key, h; 14 | struct Node *lchild, *rchild; 15 | } Node; 16 | 17 | Node _NIL, *NIL = &_NIL; 18 | 19 | __attribute__((constructor)) 20 | void init_NIL() { 21 | NIL->key = 0; 22 | NIL->h = 0; 23 | NIL->lchild = NIL->rchild = NIL; 24 | return ; 25 | } 26 | 27 | Node *getNewNode(int key) { 28 | Node *p = (Node *)malloc(sizeof(Node)); 29 | p->key = key; 30 | p->lchild = p->rchild = NIL; 31 | p->h = 1; 32 | return p; 33 | } 34 | 35 | void UpdateHeight(Node *root) { 36 | int h1 = root->lchild->h; 37 | int h2 = root->rchild->h; 38 | root->h = (h1 > h2 ? h1 : h2) + 1; 39 | return ; 40 | } 41 | 42 | Node *left_rotate(Node *root) { 43 | Node *temp = root->rchild; 44 | root->rchild = temp->lchild; 45 | temp->lchild = root; 46 | UpdateHeight(root); 47 | UpdateHeight(temp); 48 | return temp; 49 | } 50 | 51 | Node *right_rotate(Node *root) { 52 | Node *temp = root->lchild; 53 | root->lchild = temp->rchild; 54 | temp->rchild = root; 55 | UpdateHeight(root); 56 | UpdateHeight(temp); 57 | return temp; 58 | } 59 | 60 | Node *maintain(Node *root) { 61 | if (abs(root->lchild->h - root->rchild->h) <= 1) return root; 62 | if (root->lchild->h > root->rchild->h) { 63 | if (root->lchild->rchild->h > root->lchild->lchild->h) { 64 | root->lchild = left_rotate(root->lchild); 65 | } 66 | root = right_rotate(root); 67 | } else { 68 | if (root->rchild->lchild->h > root->rchild->rchild->h) { 69 | root->rchild = right_rotate(root->rchild); 70 | } 71 | root = left_rotate(root); 72 | } 73 | return root; 74 | } 75 | 76 | Node *insert(Node *root, int key) { 77 | if (root == NIL) return getNewNode(key); 78 | if (root->key == key) return root; 79 | if (root->key > key) root->lchild = insert(root->lchild, key); 80 | else root->rchild = insert(root->rchild, key); 81 | UpdateHeight(root); 82 | return maintain(root); 83 | } 84 | 85 | Node *predeccessor(Node *root) { 86 | Node *temp = root->lchild; 87 | while (temp->rchild != NIL) temp = temp->rchild; 88 | return temp; 89 | } 90 | 91 | Node *erase(Node *root, int key) { 92 | if (root == NIL) return root; 93 | if (root->key > key) root->lchild = erase(root->lchild, key); 94 | else if (root->key < key) root->rchild = erase(root->rchild, key); 95 | else { 96 | if (root->lchild == NIL || root->rchild == NIL) { 97 | Node *temp = (root->lchild == NIL ? root->rchild : root->lchild); 98 | free(root); 99 | return temp; 100 | } else { 101 | Node *temp = predeccessor(root); 102 | root->key = temp->key; 103 | root->lchild = erase(root->lchild, temp->key); 104 | } 105 | } 106 | UpdateHeight(root); 107 | return maintain(root); 108 | } 109 | 110 | void clear(Node *root) { 111 | if (root == NIL) return ; 112 | clear(root->lchild); 113 | clear(root->rchild); 114 | free(root); 115 | return ; 116 | } 117 | 118 | void output(Node *root) { 119 | if (root == NIL) return ; 120 | output(root->lchild); 121 | printf("%d [%d, %d]\n", root->key, root->lchild->key, root->rchild->key); 122 | output(root->rchild); 123 | return ; 124 | } 125 | 126 | int main() { 127 | int val, op; 128 | Node *root = NIL; 129 | while (~scanf("%d%d", &op, &val)) { 130 | switch (op) { 131 | case 1: root = insert(root, val); break; 132 | case 2: root = erase(root, val); break; 133 | } 134 | output(root); 135 | } 136 | return 0; 137 | } -------------------------------------------------------------------------------- /第8章:字符串匹配算法(3)/1、AC 自动机/2、基于双数组字典树的 AC 自动机.cpp: -------------------------------------------------------------------------------- 1 | 2 | /************************************************************************* 3 | > File Name: 15.Double_Array_Trie.cpp 4 | > Author: hug 5 | > Mail: hug@haizeix.com 6 | > Created Time: 六 8/ 4 15:28:36 2018 7 | ************************************************************************/ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #define BASE 26 15 | #define BEGIN_LETTER 'a' 16 | #define max(a, b) ((a) > (b) ? (a) : (b)) 17 | #define has_child(data, ind, i) (abs(data[data[ind].base + i].check) == ind) 18 | 19 | typedef struct DANode { 20 | int base, check, fail; 21 | char *str; 22 | } DANode; 23 | 24 | typedef struct Node { 25 | int flag; 26 | char *str; 27 | struct Node *next[BASE]; 28 | } Node, *Trie; 29 | 30 | int node_cnt = 0; 31 | 32 | Node *get_new_node() { 33 | Node *p = (Node *)calloc(sizeof(Node), 1); 34 | node_cnt += 1; 35 | return p; 36 | } 37 | 38 | void clear(Trie root) { 39 | if (root == NULL) return ; 40 | for (int i = 0; i < BASE; i++) { 41 | clear(root->next[i]); 42 | } 43 | if (root->flag) free(root->str); 44 | free(root); 45 | return ; 46 | } 47 | 48 | Node *insert(Trie root, const char *str) { 49 | if (root == NULL) root = get_new_node(); 50 | Node *p = root; 51 | for (int i = 0; str[i]; i++) { 52 | int ind = str[i] - BEGIN_LETTER; 53 | if (p->next[ind] == NULL) p->next[ind] = get_new_node(); 54 | p = p->next[ind]; 55 | } 56 | p->flag = 1; 57 | p->str = strdup(str); 58 | return root; 59 | } 60 | 61 | int get_base(Node *node, DANode *data) { 62 | int base = 2, flag = 0; 63 | while (!flag) { 64 | flag = 1; 65 | for (int i = 0; i < BASE; i++) { 66 | if (node->next[i] == NULL) continue; 67 | if (data[base + i].check == 0) continue; 68 | flag = 0; 69 | break; 70 | } 71 | base += (!flag); 72 | } 73 | return base; 74 | } 75 | 76 | int build(Node *node, DANode *data, int ind) { 77 | if (node == NULL) return 0; 78 | if (node->flag) data[ind].check = -data[ind].check, data[ind].str = node->str; 79 | int max_ind = ind; 80 | data[ind].base = get_base(node, data); 81 | for (int i = 0; i < BASE; i++) { 82 | if (node->next[i] == NULL) continue; 83 | data[data[ind].base + i].check = ind; 84 | } 85 | for (int i = 0; i < BASE; i++) { 86 | if (node->next[i] == NULL) continue; 87 | int temp = build(node->next[i], data, data[ind].base + i); 88 | max_ind = max(max_ind, temp); 89 | } 90 | return max_ind; 91 | } 92 | 93 | void build_ac(DANode *data) { 94 | #define MAX_N 100000 95 | int *queue = (int *)malloc(sizeof(int) * MAX_N); 96 | int head = 0, tail = 0; 97 | data[1].fail = 0; 98 | queue[tail++] = 1; 99 | while (head < tail) { 100 | int ind = queue[head++]; 101 | for (int i = 0; i < BASE; i++) { 102 | if (!has_child(data, ind, i)) continue; 103 | int p = data[ind].fail; 104 | while (p && !has_child(data, p, i)) p = data[p].fail; 105 | if (p == 0) p = 1; 106 | else p = data[p].base + i; 107 | data[data[ind].base + i].fail = p; 108 | queue[tail++] = data[ind].base + i; 109 | } 110 | } 111 | return ; 112 | #undef MAX_N 113 | } 114 | 115 | void search_ac(DANode *data, const char *str) { 116 | int p = 1; 117 | for (int i = 0; str[i]; i++) { 118 | while (p && !has_child(data, p, str[i] - BEGIN_LETTER)) p = data[p].fail; 119 | if (p == 0) p = 1; 120 | else p = data[p].base + str[i] - BEGIN_LETTER; 121 | int q = p; 122 | while (q) { 123 | if (data[q].check < 0) printf("find string : %s\n", data[q].str); 124 | q = data[q].fail; 125 | } 126 | } 127 | return ; 128 | } 129 | 130 | void output_da(DANode *data, int n) { 131 | for (int i = 1; i <= n; i++) { 132 | if (i - 1 && i % 5 == 1) printf("\n"); 133 | printf("(%2d %2d %3d) ", i, data[i].base, data[i].check); 134 | } 135 | printf("\n"); 136 | return ; 137 | } 138 | 139 | int main() { 140 | Trie root = NULL; 141 | #define INSERT_CNT 5 142 | root = insert(root, "hai"); 143 | root = insert(root, "zei"); 144 | root = insert(root, "ha"); 145 | root = insert(root, "ab"); 146 | root = insert(root, "ehz"); 147 | DANode *data = (DANode *)calloc(sizeof(DANode), (INSERT_CNT * 100)); 148 | int da_cnt = build(root, data, 1); 149 | build_ac(data); 150 | output_da(data, da_cnt); 151 | search_ac(data, "sasherhs"); 152 | #undef INSERT_CNT 153 | return 0; 154 | } -------------------------------------------------------------------------------- /第9章:递归函数转非递归函数/3、【程序演示】快速排序(非递归).cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | 3 | > File Name: 快速排序(非递归) 4 | 5 | > Author: hug 6 | 7 | > Mail: hug@haizeix.com 8 | 9 | > Created Time: 五 8/18 08:18:42 2017 10 | 11 | ************************************************************************/ 12 | 13 | 14 | 15 | #include 16 | 17 | #include 18 | 19 | #include 20 | 21 | 22 | 23 | #define MC(T, n) ((T *)malloc(sizeof(T) * n)) 24 | 25 | #define init_stack(s, n, T) (__init_stack(s, n, sizeof(T))) 26 | 27 | #define push_stack(s, value) ({ \ 28 | 29 | __typeof(value) __temp = (value); \ 30 | 31 | __push_stack(s, (const char *)(&(__temp))); \ 32 | 33 | }) 34 | 35 | #define empty_stack(s) (__empty_stack(s)) 36 | 37 | #define pop_stack(s) (__pop_stack(s)) 38 | 39 | #define top_stack(s, T) (*((T *)__top_stack(s))) 40 | 41 | #define clear_stack(s) (__clear_stack(s)) 42 | 43 | #define swap(a, b) { \ 44 | 45 | __typeof(a) __temp = (a); \ 46 | 47 | (a) = (b); (b) = (__temp); \ 48 | 49 | } 50 | 51 | 52 | 53 | #define ERROR 0 54 | 55 | #define OK 1 56 | 57 | 58 | 59 | typedef struct Stack { 60 | 61 | char *data; 62 | 63 | int top, size; 64 | 65 | int value_size; 66 | 67 | } Stack; 68 | 69 | 70 | 71 | void __init_stack(Stack *s, int n, int value_size); 72 | 73 | int __push_stack(Stack *s, const char *value); 74 | 75 | int __empty_stack(Stack *s); 76 | 77 | int __pop_stack(Stack *s); 78 | 79 | char *__top_stack(Stack *s); 80 | 81 | void __clear_stack(Stack *s); 82 | 83 | 84 | 85 | typedef struct Node { 86 | 87 | int val; 88 | 89 | struct Node *lchild, *rchild; 90 | 91 | } Node; 92 | 93 | 94 | 95 | Node *init(int val) { 96 | 97 | Node *p = MC(Node, 1); 98 | 99 | p->val = val; 100 | 101 | p->lchild = p->rchild = NULL; 102 | 103 | return p; 104 | 105 | } 106 | 107 | 108 | 109 | typedef struct QuickSortArgs { 110 | 111 | int *arr; 112 | 113 | int l, r; 114 | 115 | int x; 116 | 117 | int status; 118 | 119 | } QuickSortArgs; 120 | 121 | 122 | 123 | int __quick_sort(int *arr, int l, int r) { 124 | 125 | // 0 : if (r <= l) return ; 126 | 127 | int x, y, z; 128 | 129 | x = l, y = r, z = arr[l]; 130 | 131 | while (x < y) { 132 | 133 | while (x < y && arr[y] >= z) --y; 134 | 135 | if (x < y) arr[x++] = arr[y]; 136 | 137 | while (x < y && arr[x] <= z) ++x; 138 | 139 | if (x < y) arr[y--] = arr[x]; 140 | 141 | } 142 | 143 | arr[x] = z; 144 | 145 | return x; 146 | 147 | // 2: quick_sort(arr, l, x - 1); 148 | 149 | // 3 : quick_sort(arr, x + 1, r); 150 | 151 | // 4 : return ; 152 | 153 | } 154 | 155 | 156 | 157 | void init_quick_sort_args(QuickSortArgs *qsa, int *arr, int l, int r, int status) { 158 | 159 | qsa->arr = arr; 160 | 161 | qsa->l = l; 162 | 163 | qsa->r = r; 164 | 165 | qsa->status = 0; 166 | 167 | return ; 168 | 169 | } 170 | 171 | 172 | 173 | void quick_sort(int *arr, int n) { 174 | 175 | Stack *s = MC(Stack, 1); 176 | 177 | init_stack(s, 1000, QuickSortArgs); 178 | 179 | QuickSortArgs qsa; 180 | 181 | init_quick_sort_args(&qsa, arr, 0, n - 1, 0); 182 | 183 | push_stack(s, qsa); 184 | 185 | while (!empty_stack(s)) { 186 | 187 | QuickSortArgs *tqsa = &top_stack(s, QuickSortArgs); 188 | 189 | switch (tqsa->status) { 190 | 191 | case 0: 192 | 193 | if (tqsa->r <= tqsa->l) { 194 | 195 | tqsa->status = 4; 196 | 197 | } else { 198 | 199 | tqsa->status = 1; 200 | 201 | } 202 | 203 | break; 204 | 205 | case 1: 206 | 207 | tqsa->x = __quick_sort(tqsa->arr, tqsa->l, tqsa->r); 208 | 209 | tqsa->status = 2; 210 | 211 | break; 212 | 213 | case 2: 214 | 215 | init_quick_sort_args(&qsa, arr, tqsa->l, tqsa->x - 1, 0); 216 | 217 | push_stack(s, qsa); 218 | 219 | tqsa->status = 3; 220 | 221 | break; 222 | 223 | case 3: 224 | 225 | init_quick_sort_args(&qsa, arr, tqsa->x + 1, tqsa->r, 0); 226 | 227 | push_stack(s, qsa); 228 | 229 | tqsa->status = 4; 230 | 231 | break; 232 | 233 | case 4: 234 | 235 | pop_stack(s); 236 | 237 | break; 238 | 239 | default: 240 | 241 | printf("ERROR\n"); 242 | 243 | break; 244 | 245 | } 246 | 247 | } 248 | 249 | return ; 250 | 251 | } 252 | 253 | 254 | 255 | int main() { 256 | 257 | int arr[10] = {9, 7, 5, 4, 2 ,1 ,3, 10, 6, 8}; 258 | 259 | quick_sort(arr, 10); 260 | 261 | for (int i = 0; i < 10; i++) { 262 | 263 | printf("%d ", arr[i]); 264 | 265 | } 266 | 267 | printf("\n"); 268 | 269 | return 0; 270 | 271 | } 272 | 273 | 274 | 275 | void __init_stack(Stack *s, int n, int value_size) { 276 | 277 | s->data = (char *)malloc(value_size * n); 278 | 279 | s->top = -1; 280 | 281 | s->size = n; 282 | 283 | s->value_size = value_size; 284 | 285 | return ; 286 | 287 | } 288 | 289 | 290 | 291 | int __push_stack(Stack *s, const char *value) { 292 | 293 | if (s->top == s->size - 1) { 294 | 295 | return ERROR; 296 | 297 | } 298 | 299 | ++(s->top); 300 | 301 | memcpy(s->data + s->top * s->value_size, value, s->value_size); 302 | 303 | return OK; 304 | 305 | } 306 | 307 | 308 | 309 | int __empty_stack(Stack *s) { 310 | 311 | return s->top == -1; 312 | 313 | } 314 | 315 | 316 | 317 | int __pop_stack(Stack *s) { 318 | 319 | if (__empty_stack(s)) { 320 | 321 | return ERROR; 322 | 323 | } 324 | 325 | --(s->top); 326 | 327 | return OK; 328 | 329 | } 330 | 331 | 332 | 333 | char *__top_stack(Stack *s) { 334 | 335 | if (__empty_stack(s)) { 336 | 337 | return NULL; 338 | 339 | } 340 | 341 | return s->data + s->top * s->value_size; 342 | 343 | } 344 | 345 | 346 | 347 | void __clear_stack(Stack *s) { 348 | 349 | free(s->data); 350 | 351 | free(s); 352 | 353 | return ; 354 | 355 | } --------------------------------------------------------------------------------