├── AVLTree ├── BSTree ├── BSTreeKV ├── BenchMark.cpp ├── C++ & EasyX实现双人对弈五子棋 ├── C++11 ├── CentralControlCache.cpp ├── CentralControlCache.h ├── CommonResource.h ├── Date ├── HashLinearDetection ├── MemoryManagement.h ├── ModuleTest.h ├── PageCache.cpp ├── PageCache.h ├── PageMap.h ├── QuickSort.txt ├── RBTree ├── RBTreeIterator ├── ThreadCache.cpp ├── ThreadCache.h ├── WuZiQi ├── a.out ├── list ├── list_iterator ├── lock&thread ├── main.cpp ├── map └── map_set ├── mystring ├── priority_queue ├── simpleMemoryPool ├── sort ├── test ├── test.c ├── vector └── 高并发内存池项目完整代码 ├── Benchmark.cpp ├── CentralControlCache.cpp ├── CentralControlCache.h ├── Common.h ├── ConCurrmentMemoryPoolProject.vcxproj ├── ConCurrmentMemoryPoolProject.vcxproj.filters ├── MemoryManagment.h ├── PageCache.cpp ├── PageCache.h ├── PageMap.h ├── Release ├── Benchmark.obj ├── CentralControlCache.obj ├── ConCurrm.8F226646.tlog │ ├── CL.read.1.tlog │ ├── CL.write.1.tlog │ ├── ConCurrmentMemoryPoolProject.lastbuildstate │ ├── cl.command.1.tlog │ ├── link.command.1.tlog │ ├── link.read.1.tlog │ └── link.write.1.tlog ├── ConCurrmentMemoryPoolProject.log ├── PageCache.obj ├── ThreadCache.obj ├── UnitTest.obj └── vc120.pdb ├── ThreadCache.cpp ├── ThreadCache.h └── UnitTest.cpp /AVLTree: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | using namespace std; 7 | 8 | //节点定义 9 | template 10 | struct AVLTreeNode 11 | { 12 | pair _val;//节点,键值对 13 | int _bf;//平衡因子 14 | AVLTreeNode* _left;//左子树 15 | AVLTreeNode* _right;//右子树 16 | AVLTreeNode* _parent;//双亲节点 17 | 18 | AVLTreeNode(const pair& val) 19 | :_val(val),_bf(0) 20 | ,_left(nullptr),_right(nullptr),_parent(nullptr) 21 | {} 22 | }; 23 | 24 | template 25 | class AVLTree 26 | { 27 | typedef AVLTreeNode Node; 28 | private: 29 | Node* root = nullptr;//根节点 30 | public: 31 | //构造函数 32 | //析构函数 33 | //插入--返回一个键值对,键值对的第一个值是插入节点的指针第二个值是bool值表示是否插入成功 34 | pair insert(const pair& val) 35 | { //1.找到该节点并插入 36 | Node* newNode = new Node(val); 37 | //如果是一颗空树,新插入节点就为跟节点 38 | if(root == nullptr) 39 | { 40 | root = newNode; 41 | return make_pair(root,true); 42 | } 43 | //找到插入位置 44 | Node* parent = nullptr;//当前节点的父节点 45 | Node* cur = root; 46 | while(cur) 47 | { 48 | if((cur->_val).first < (newNode->_val).first) 49 | { 50 | //左走 51 | parent = cur; 52 | cur = cur->left; 53 | } 54 | else if((cur->_val).first > (newNode->_val).first) 55 | { 56 | //右走 57 | parent = cur; 58 | cur = cur->right; 59 | } 60 | else 61 | { 62 | //找到了,不需要插入,直接返回 63 | return make_pair(cur,false); 64 | } 65 | } 66 | //插入节点 67 | if((parent->_val).first > (newNode->_val).first) 68 | { 69 | //插入到parent的左孩子节点处 parent->right = newNode; 70 | newNode->_parent = parent; 71 | } 72 | //2.调整平衡因子 73 | /*基本思路 74 | * 从该节点的父节点开始调整,如果父节点的平衡因子变成了0,则停止调整 75 | * 如果该节点的父节点的平衡因子不是0,则继续向上调整,直到某个节点的 76 | * 平衡因子变成0或者调整到了根节点 77 | * 调整平衡因子的策略是,如果插入的节点是该节点的左孩子节点则平衡因子-1 78 | * 如果是该节点的右孩子节点,则平衡因子+1 79 | */ 80 | cur = newNode; 81 | while(parent) 82 | { 83 | if(cur == parent->left) 84 | { 85 | //parent的平衡因子-1 86 | parent->_bf--; 87 | } 88 | else 89 | { 90 | //parent的平衡因子+1 91 | parent->_bf++; 92 | } 93 | //判断parent的平衡因子是否为0 94 | if(parent->_bf == 0) 95 | { 96 | //调整完成 97 | break; 98 | } 99 | else if(parent->bf == -1 || parent->bf == 1) 100 | { //继续向上调整 101 | cur = parent; 102 | parent = parent->_parent; 103 | } 104 | else 105 | { 106 | //已经不再是一颗AVL树,需要进行旋转 107 | if(parent->_bf == -2) 108 | { 109 | if(parent->_left->_bf == -1) 110 | { 111 | //新插入的节点是较高的左子树的左孩子节点---右单旋 112 | RotateR(parent); 113 | } 114 | else 115 | { 116 | //左右单旋 117 | RotateLR(parent); 118 | } 119 | } 120 | else if(parent->_bf == 2) 121 | { 122 | if(parent->_right->_bf == 1) 123 | { 124 | //左单旋 125 | RotateL(parent); 126 | } 127 | else 128 | { 129 | //右左单旋 130 | RotateRL(parent); 131 | } 132 | } 133 | } 134 | } return make_pair(cur,false); 135 | } 136 | //右单旋 137 | void RotateR(Node* parent) 138 | { 139 | Node* parentL = parent->_left;//parent的左孩节点 140 | Node* subR = parentL->_right;//parent的左孩子节点的右孩子节点 141 | 142 | Node* parentParent = parent->parent; 143 | //parent的左孩子节点指向parentL的右孩子节点 144 | parentL = subR; 145 | if(subR) 146 | subR->_parent = parent; 147 | //parent变成parentL的右孩子节点 148 | subR = parent; 149 | //parent的父节点变成parent的左孩子节点 150 | parent->_parent = parentL; 151 | //parent是根节点 152 | if(parent == root) 153 | { 154 | root = parentL; 155 | root->_parent = nullptr; 156 | } 157 | else 158 | { 159 | if(parent == parentParent->_left) 160 | { 161 | parentParent->_left = parentL; 162 | parentL->_parent = parentParent; 163 | } 164 | else 165 | { 166 | parentParent->_right = parentL; 167 | parentL->_parent = parentParent; 168 | } } 169 | parent->_bf = parentL->_bf = 0; 170 | } 171 | //左单旋 172 | void RotateL(Node* parent) 173 | { 174 | Node* parentR = parent->_right;//parent的右孩子节点 175 | Node* subRL = parentR->_left;//parent的右孩子的左孩子节点 176 | 177 | Node* parentParent = parent->_parent; 178 | //parent的右孩子节点指向parent的右孩子节点的左孩子节点 179 | parentR = subRL; 180 | if(subRL) 181 | subRL->_parent = parentR; 182 | //parent的右孩子节点的左孩子节点指向parent节点 183 | subRL = parent; 184 | //parent的父节点指向parent的右孩子节点 185 | parent->_parent = parentR; 186 | if(parent == root) 187 | { 188 | root = parentR; 189 | root->_parent = nullptr; 190 | } 191 | else 192 | { 193 | if(parentParent->_left == parent) 194 | { 195 | parentParent->_left = parent; 196 | } 197 | else 198 | { 199 | parentParent->_right = parent; 200 | } parent->_parent = parentParent; 201 | } 202 | parent->_bf = parentR->_bf = 0; 203 | } 204 | //左右单旋 205 | void RotateLR(Node* parent) 206 | { 207 | Node* parentL = parent->_left; 208 | Node* subLR = parentL->_right; 209 | int subLRBf = subLR->_bf; 210 | //左孩子节点进行左单旋 211 | RotateL(parent->_left); 212 | RotateR(parent); 213 | //调整平衡因子 214 | if(subLRBf == 1) 215 | { 216 | parent->_bf = subLR->_bf = 0; 217 | parentL->_bf = -1; 218 | } 219 | else if(subLRBf == -1) 220 | { 221 | subLR->_bf = parentL->_bf = 0; 222 | parent->_bf = -1; 223 | } 224 | else 225 | { 226 | parent->_bf = parentL->_bf = subLR->_bf = 0; 227 | } 228 | } 229 | //右左单旋 230 | void RotateRL(Node* parent) 231 | { 232 | Node* parentR = parent->_right; 233 | Node* subRL = parentR->_left; 234 | int subRLBf = subRL->_bf; 235 | //该节点的右孩子进行右旋转 236 | RotateR(parent->_right); 237 | //该节点进行左旋转 238 | RotateL(parent); 239 | 240 | //调整平衡因子 241 | if(subRLBf == 1) 242 | { 243 | parentR->_bf = subRL->_bf = 0; 244 | parent->_bf = -1; 245 | } 246 | else if(subRLBf == -1) 247 | { 248 | parentR->_bf = subRL->_bf = 0; 249 | parent->_bf = 1; 250 | } 251 | else 252 | { 253 | parentR->_bf = subRL->_bf = parent->_bf = 0; 254 | } 255 | } 256 | //中序遍历AVL树 257 | static void BSTreeInOrder(Node* node,vector>& inOrder) 258 | { 259 | //inOrder是输出型参数,将遍历结果保存到该数组中 260 | if(node == nullptr) 261 | return; 262 | BSTreeInOrder(node->_left,inOrder); 263 | inOrder.push_back(node->_val); 264 | BSTreeInOrder(node->_right,inOrder); 265 | } 266 | bool isBSTree() 267 | { 268 | vector> inOrder; BSTreeInOrder(root,inOrder); 269 | if(inOrder.empty()) 270 | return true; 271 | //遍历,检查是否有序 272 | pair tmp = inOrder[0]; 273 | for(int i = 1;i < inOrder.size();i++) 274 | { 275 | if(tmp.first < inOrder[i].first) 276 | { 277 | tmp = inOrder[i]; 278 | } 279 | else 280 | return false; 281 | } 282 | } 283 | //二叉树的高度 284 | static int BSTreeHeight(Node* node) 285 | { 286 | if(node == nullptr) 287 | return 0; 288 | int left = BSTreeHeight(node->_left); 289 | int right = BSTreeHeight(node->_right); 290 | 291 | return left>right?(left+1):(right+1); 292 | } 293 | //判断是否平衡 294 | static bool _isBalance(Node* root) 295 | { 296 | //求左右子树的高度 297 | int left = BSTreeHeight(root->_left); 298 | int right = BSTreeHeight(root->_right); 299 | if(abs(left-right) <= 1) 300 | { 301 | return _isBalance(root->_left) && _isBalance(root->_right); } 302 | else 303 | return false; 304 | } 305 | //验证AVL树 306 | bool isBalance() 307 | { 308 | if(root == nullptr) 309 | return true; 310 | if(isBSTree() && _isBalance()) 311 | return true; 312 | return false; 313 | } 314 | } 315 | -------------------------------------------------------------------------------- /BSTree: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | template 5 | struct BSTNode 6 | { 7 | k value; 8 | struct BSTNode* left; 9 | struct BSTNode* right; 10 | 11 | BSTNode(const k& val) 12 | :value(val), left(nullptr), right(nullptr) 13 | {} 14 | }; 15 | 16 | template 17 | class BSTree 18 | { 19 | typedef BSTNode Node; 20 | public: 21 | bool Insert(const k& val) 22 | { 23 | //根节点为空格,直接插入 24 | if (root == nullptr) 25 | { 26 | root = new Node(val); 27 | return true; 28 | } 29 | 30 | //根节点不为空,先找到合适的位置,在插入 31 | Node* parent = root; 32 | Node* cur = root; 33 | while (cur) 34 | { 35 | //如果找到相同节点,则不需要插入 36 | if (cur->value == val) 37 | { 38 | return false; 39 | } 40 | else if (cur->value < val) 41 | { 42 | parent = cur; 43 | cur = cur->right; 44 | } 45 | else 46 | { 47 | parent = cur; 48 | cur = cur->left; 49 | } 50 | } 51 | //找到了,创建节点进行插入 52 | Node* tmp = new Node(val); 53 | if (parent->value < val) 54 | { 55 | parent->right = tmp; 56 | } 57 | else 58 | { 59 | parent->left = tmp; 60 | } 61 | 62 | return true; 63 | } 64 | 65 | const Node* find(const k& val) 66 | { 67 | Node* cur = root; 68 | while (cur) 69 | { 70 | if (cur->value == val) 71 | { 72 | return cur; 73 | } 74 | else if (cur->value < val) 75 | { 76 | cur = cur->right; 77 | } 78 | else 79 | { 80 | cur = cur->left; 81 | } 82 | } 83 | return nullptr; 84 | } 85 | 86 | bool Erase(const k& val) 87 | { 88 | //查找 89 | Node* parent = nullptr; 90 | Node* cur = root; 91 | while (cur) 92 | { 93 | if (cur->value > val) 94 | { 95 | //在左子树 96 | parent = cur; 97 | cur = cur->left; 98 | } 99 | else if (cur->value < val) 100 | { 101 | //在右子树找 102 | parent = cur; 103 | cur = cur->right; 104 | } 105 | else 106 | { 107 | //找到了,删除 108 | //左子树为空 109 | if (cur->left == nullptr) 110 | { 111 | if (cur == root) 112 | root = cur->right; 113 | //父节点指向右子树 114 | else 115 | { 116 | if (cur == parent->left) 117 | { 118 | parent->left = cur->right; 119 | } 120 | else 121 | { 122 | parent->right = cur->right; 123 | } 124 | } 125 | } 126 | else if (cur->right == nullptr) 127 | { 128 | if (cur == root) 129 | root = cur->left; 130 | else 131 | { 132 | if (cur == parent->left) 133 | parent->left = cur->left; 134 | else 135 | parent->right = cur->left; 136 | } 137 | } 138 | else 139 | { 140 | //左右子树都不为空,找右树的最小节点 141 | Node* minNode = cur->right; 142 | Node* minNodeParent = cur; 143 | while (minNode->left) 144 | { 145 | minNodeParent = minNode; 146 | minNode = minNode->left; 147 | } 148 | 149 | //将要删除的节点和该节点交换 150 | cur->value = minNode->value; 151 | //删除交换后的节点 152 | if (minNodeParent->left == minNode) 153 | minNodeParent->left = minNode->right; 154 | else 155 | minNodeParent->right = minNode->right; 156 | 157 | //删除节点 158 | delete minNode; 159 | } 160 | return true; 161 | } 162 | } 163 | return false; 164 | } 165 | public: 166 | Node* root = nullptr; 167 | }; 168 | -------------------------------------------------------------------------------- /BSTreeKV: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | 6 | template 7 | struct Node 8 | { 9 | K key; 10 | V value; 11 | Node* left; 12 | Node* right; 13 | 14 | //构造函数,通过指定的key和value值创建节点 15 | Node(const K& _key, const V& _val) 16 | :key(_key), value(_val) 17 | , left(nullptr), right(nullptr) 18 | {} 19 | }; 20 | 21 | template 22 | class BSTreeKV 23 | { 24 | typedef Node Node; 25 | public: 26 | //默认构造一个空的,只有当插入节点时才创建root节点 27 | //插入一个节点 28 | void insert(const K& key, const V& value) 29 | { 30 | Node* newNode = new Node(key, value); 31 | //如果根节点为空,直接插入 32 | if (root == nullptr) 33 | root = newNode; 34 | else 35 | { 36 | //找到一个合适的插入位置,进行插入 37 | Node* cur = root; 38 | while (cur->left || cur->right) 39 | { 40 | if (cur->key > newNode->key) 41 | { 42 | if (cur->left == nullptr) 43 | break; 44 | cur = cur->left; 45 | } 46 | else if (cur->key < newNode->key) 47 | { 48 | if (cur->right == nullptr) 49 | break; 50 | cur = cur->right; 51 | } 52 | else 53 | { 54 | //已经存在该节点, 不重复插入 55 | return; 56 | } 57 | } 58 | //判断prev和cur的关系,将newNode插入 59 | if (cur->key > newNode->key) 60 | { 61 | cur->left = newNode; 62 | } 63 | else 64 | { 65 | cur->right = newNode; 66 | } 67 | } 68 | } 69 | 70 | //查找 71 | void find(const K& k) 72 | { 73 | Node* cur = root; 74 | while (cur) 75 | { 76 | if (cur->key > k) 77 | { 78 | cur = cur->left; 79 | } 80 | else if (cur->key < k) 81 | { 82 | cur = cur->right; 83 | } 84 | else 85 | { 86 | std::cout << k << "->"<value<key > k) 104 | { 105 | parent = cur; 106 | cur = cur->left; 107 | } 108 | else if (cur->key < k) 109 | { 110 | parent = cur; 111 | cur = cur->right; 112 | } 113 | else 114 | { 115 | //找到了要删除的节点 116 | //左子树为或者右子树为空,根节点指向cur的;另一个孩子节点 117 | if (cur->left == nullptr) 118 | { 119 | if (parent->left == cur) 120 | { 121 | parent->left = cur->right; 122 | } 123 | else 124 | parent->right = cur->right; 125 | } 126 | else if (cur->right == nullptr) 127 | { 128 | if (parent->left == cur) 129 | { 130 | parent->left = cur->left; 131 | } 132 | else 133 | parent->right = cur->left; 134 | } 135 | //左右子树都不为空,找最左节点进行替换 136 | else 137 | { 138 | Node* tmp = cur; 139 | while (tmp->left) 140 | { 141 | parent = tmp; 142 | tmp = tmp->left; 143 | } 144 | //交换cur和tmp 145 | cur->key = tmp->key; 146 | cur->value = tmp->value; 147 | if (tmp->right) 148 | { 149 | parent->left = tmp->right; 150 | } 151 | else 152 | parent->left = nullptr; 153 | delete tmp; 154 | } 155 | //删除成功 156 | std::cout << "删除成功" << std::endl; 157 | break; 158 | } 159 | } 160 | if (cur == nullptr) 161 | { 162 | std::cout << "没有找到要删除的节点"< st; 170 | Node* cur = root; 171 | while (cur || !st.empty()) 172 | { 173 | //打印并将左路节点入栈 174 | while (cur) 175 | { 176 | st.push(cur); 177 | std::cout << "<" << cur->key << "," << cur->value << ">" << " "; 178 | cur = cur->left; 179 | } 180 | //左路节点出栈并将右孩子节点入栈 181 | Node* tmp = st.top(); 182 | st.pop(); 183 | cur = tmp->right; 184 | } 185 | std::cout << std::endl; 186 | } 187 | private: 188 | Node* root = nullptr; 189 | }; 190 | 191 | 192 | -------------------------------------------------------------------------------- /BenchMark.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MouCoder/cpp_Code/6f6868685562996c866f5aa8f82ef914eada3b0e/BenchMark.cpp -------------------------------------------------------------------------------- /C++ & EasyX实现双人对弈五子棋: -------------------------------------------------------------------------------- 1 | void Menu::Display() 2 | { 3 | //初始化绘图窗口 4 | initgraph(416, 624, SHOWCONSOLE); 5 | 6 | /*设置背景图*/ 7 | IMAGE img; 8 | //缩放因子,例如设置宽度为100的单元格,实际的绘制宽度为(100*缩放因子) 9 | setaspectratio(1.1, 1); 10 | //从图片文件获取图像(图像的image指针,图像名,资源名称,图片的拉伸宽度、高度,是否自适应图片大小) 11 | loadimage(&img, "begin.jpg", 377, 624, 1); 12 | putimage(0, 0, &img); 13 | 14 | /*控制鼠标移动操作*/ 15 | MOUSEMSG m;//鼠标操作 16 | while (true) 17 | { 18 | m = GetMouseMsg();//获取鼠标消息 19 | //左键按下:WM_LBUTTONDOWN 20 | if (m.uMsg == WM_LBUTTONDOWN && (m.x >= 72 && m.x <= 307 && m.y >= 340 && m.y <= 400 21 | || m.x >= 72 && m.x <= 307 && m.y >= 420 && m.y <= 480)) 22 | { 23 | //uMsg鼠标信息 WM_MOUSEMOVE鼠标移动消息 x y表示鼠标位置坐标 24 | //当鼠标在"人机对战、双人对战"上时,显示红色边框 25 | if (m.x >= 72 && m.x <= 307 && m.y >= 340 && m.y <= 400) 26 | { 27 | setlinecolor(YELLOW); 28 | setlinestyle(PS_SOLID | PS_JOIN_ROUND, 2); 29 | //空心矩形框 30 | rectangle(72, 340, 300, 400); 31 | } 32 | else if (m.x >= 72 && m.x <= 307 && m.y >= 420 && m.y <= 480) 33 | { 34 | setlinecolor(YELLOW); 35 | //空心矩形框 36 | rectangle(72, 420, 300, 480); 37 | } 38 | Sleep(500); 39 | //清除屏幕内容 40 | cleardevice(); 41 | //休眠五秒 42 | Sleep(300); 43 | //关闭窗口 44 | closegraph(); 45 | //使用匿名对象打开棋盘界面 46 | Menu().ChessBoard(m); 47 | break; 48 | } 49 | } 50 | } 51 | 52 | void Menu::ChessBoard(MOUSEMSG m) 53 | { 54 | //初始化绘图窗口 55 | initgraph(665,490, SHOWCONSOLE); 56 | 57 | /*设置棋盘背景背景图*/ 58 | IMAGE img; 59 | //缩放因子,例如设置宽度为100的单元格,实际的绘制宽度为(100*缩放因子) 60 | //setaspectratio(1.1, 1); 61 | //从图片文件获取图像(图像的image指针,图像名,资源名称,图片的拉伸宽度、高度,是否自适应图片大小) 62 | loadimage(&img, "chessBoard.jpg", 665,490); 63 | putimage(0, 0, &img); 64 | 65 | //绘制棋盘 66 | while (true) 67 | { 68 | for (int i = 20; i <= 470; i+=30) 69 | { 70 | setlinecolor(WHITE); 71 | line(20,i,470,i); 72 | line(i,20,i,470); 73 | } 74 | //如果左键双人,跳入双人游戏 75 | if (m.uMsg == WM_LBUTTONDOWN && m.x >= 72 && m.x <= 307 && m.y >= 420 && m.y <= 480) 76 | { 77 | Play().TwoPlayerGame(m); 78 | } 79 | else 80 | { 81 | Play().ComputerUserGame(m); 82 | } 83 | } 84 | } 85 | 86 | void Play::buttonRingth(MOUSEMSG m,MOUSEMSG ms, int win) 87 | { 88 | if (ms.x >= 500 && ms.x <= 655 && ms.y >= 30 && ms.y <= 80) 89 | { 90 | memset(a, 0, sizeof(a)); 91 | //重新开始 92 | setlinecolor(RED); 93 | //空心矩形框 94 | rectangle(500, 30, 655, 80); 95 | Sleep(300); 96 | Menu().ChessBoard(m); 97 | } 98 | else if (ms.x >= 500 && ms.x <= 655 && ms.y >= 115 && ms.y <= 165) 99 | { 100 | memset(a, 0, sizeof(a)); 101 | //返回菜单 102 | setlinecolor(RED); 103 | //空心矩形框 104 | rectangle(500, 115, 655, 165); 105 | Sleep(300); 106 | Menu().Display(); 107 | } 108 | else if (win == 0 && ms.x >= 500 && ms.x <= 655 && ms.y >= 200 && ms.y <= 250) 109 | { 110 | //悔棋 111 | setlinecolor(RED); 112 | //空心矩形框 113 | rectangle(500, 200, 655, 250); 114 | } 115 | } 116 | 117 | void Play::displayWin(int n1,int n2) 118 | { 119 | memset(a,0,sizeof(a)); 120 | //显示哪一方赢了,n1为0表示双人为1表示人机,n2为0表示黑、人为1表示白、机 121 | IMAGE img; 122 | // 读取图片至绘图窗口 123 | if (n1 == 0 && n2 == 0) 124 | loadimage(&img, "blackWin.jpg",306,141); 125 | if (n1 == 0 && n2 == 1) 126 | loadimage(&img, "whiteWin.jpg", 306, 141); 127 | if (n1 == 1 && n2 == 0) 128 | loadimage(&img, "youWin.jpg", 306, 141); 129 | if (n1 == 1 && n2 == 1) 130 | loadimage(&img, "computerWin.jpg", 306, 141); 131 | putimage(100, 200, &img); 132 | 133 | MOUSEMSG m;//鼠标操作 134 | while (1) 135 | { 136 | m = GetMouseMsg(); 137 | if (m.uMsg == WM_LBUTTONDOWN && m.x >= 215 && m.x <= 270 && m.y >= 285 && m.y <= 320) 138 | { 139 | setlinecolor(YELLOW); 140 | //空心矩形框 141 | rectangle(215, 285, 270, 320); 142 | Sleep(300); 143 | Menu().Display(); 144 | break; 145 | } 146 | else if (m.uMsg == WM_LBUTTONDOWN) 147 | exit(0); 148 | } 149 | } 150 | 151 | void Play::TwoPlayerGame(MOUSEMSG m) 152 | { 153 | int win = 0; 154 | int play1 = 1, play2 = 0; 155 | MOUSEMSG ms; 156 | ////一直获取鼠标信息,判断操做 157 | while (win == 0) 158 | { 159 | //判断是否点击右侧工具栏或者棋盘 160 | ms = GetMouseMsg(); 161 | if (ms.uMsg == WM_LBUTTONDOWN) 162 | { 163 | //判断是否点击右侧工具栏 164 | buttonRingth(m,ms,win); 165 | //判断是否点击棋盘 166 | for (int lie = 20; lie <= 490; lie += 30) 167 | { 168 | if (ms.x <= lie + 15 && ms.x >= lie - 15) 169 | { 170 | for (int hang = 20; hang <= 490; hang += 30) 171 | { 172 | if (ms.y <= hang + 15 && ms.y >= hang - 15) 173 | { 174 | if (play1 == 1 && a[hang / 30 - 1][lie / 30 - 1] == 0) 175 | { 176 | setfillcolor(BLACK); 177 | solidcircle(lie, hang, 12); 178 | a[hang / 30 - 1][lie / 30 - 1] = 1; 179 | play1 = 0; 180 | break; 181 | } 182 | if (play1 == 0 && a[hang / 30 - 1][lie / 30 - 1] == 0) 183 | { 184 | setfillcolor(WHITE); 185 | solidcircle(lie, hang, 12); 186 | a[hang / 30 - 1][lie / 30 - 1] = 2; 187 | play1 = 1; 188 | break; 189 | } 190 | } 191 | } 192 | } 193 | } 194 | //判断玩家是否赢 195 | win = Play().Win(); 196 | if (win == 1) 197 | { 198 | //黑棋赢 199 | displayWin(0,0); 200 | break; 201 | } 202 | else if (win == 2) 203 | { 204 | //白棋赢 205 | displayWin(0,1); 206 | break; 207 | } 208 | } 209 | } 210 | } 211 | 212 | void Play::ComputerUserGame(MOUSEMSG m) 213 | { 214 | int win = 0; 215 | int play1 = 1, play2 = 0;//play1表示玩家,play2表示电脑,每次玩家先落子 216 | 217 | MOUSEMSG ms; 218 | ////一直获取鼠标信息,判断操做 219 | while (win == 0) 220 | { 221 | //判断是否点击右侧工具栏或者棋盘 222 | ms = GetMouseMsg(); 223 | if (ms.uMsg == WM_LBUTTONDOWN) 224 | { 225 | //判断是否点击右侧工具栏 226 | buttonRingth(m, ms, win); 227 | //判断是否点击棋盘并且判断是否该玩家落子 228 | PlayGame(ms,&play1,&play2); 229 | //判断玩家是否赢 230 | win = Play().Win(); 231 | if (win == 1) 232 | { 233 | //人赢 234 | displayWin(1, 0); 235 | break; 236 | } 237 | else if (win == 2) 238 | { 239 | //电脑赢 240 | displayWin(1, 1); 241 | break; 242 | } 243 | } 244 | } 245 | } 246 | 247 | 248 | 249 | int Play::Win() 250 | { 251 | int win = 0; 252 | //判断是否赢 253 | for (int j = 0; j<16 && (win == 0); j++) 254 | { 255 | for (int i = 0; i<16; i++) 256 | { 257 | 258 | if ((a[j][i] == 1 && a[j][i + 1] == 1 && a[j][i + 2] == 1 && a[j][i + 3] == 1 && a[j][i + 4] == 1) 259 | || (a[i][j] == 1 && a[i + 1][j] == 1 && a[i + 2][j] == 1 && a[i + 3][j] == 1 && a[i + 4][j] == 1))//横纵是5个子play1 win 260 | { 261 | win = 1; 262 | Sleep(100); 263 | break; 264 | } 265 | if ((a[j][i] == 2 && a[j][i + 1] == 2 && a[j][i + 2] == 2 && a[j][i + 3] == 2 && a[j][i + 4] == 2) 266 | || (a[i][j] == 2 && a[i + 1][j] == 2 && a[i + 2][j] == 2 && a[i + 3][j] == 2 && a[i + 4][j] == 2))//横纵是5个子play2 win 267 | { 268 | win = 2; 269 | Sleep(100); 270 | break; 271 | } 272 | } 273 | } 274 | for (int j = 0; j<12 && (win == 0); j++) 275 | { 276 | for (int i = 0; i<12; i++) 277 | { 278 | if (a[j][i] == 1 && a[j + 1][i + 1] == 1 && a[j + 2][i + 2] == 1 && a[j + 3][i + 3] == 1 && a[j + 4][i + 4] == 1)//向右倾斜时候play1 win 279 | { 280 | win = 1; 281 | Sleep(100); 282 | break; 283 | 284 | } 285 | if (a[j][i] == 2 && a[j + 1][i + 1] == 2 && a[j + 2][i + 2] == 2 && a[j + 3][i + 3] == 2 && a[j + 4][i + 4] == 2)//向右倾斜时候play2 win 286 | { 287 | win = 2; 288 | Sleep(100); 289 | break; 290 | } 291 | } 292 | for (int i = 4; i<16 && (win == 0); i++) 293 | { 294 | if (a[j][i] == 1 && a[j + 1][i - 1] == 1 && a[j + 2][i - 2] == 1 && a[j + 3][i - 3] == 1 && a[j + 4][i - 4] == 1)//向左倾斜时候play1 win 295 | { 296 | win = 1; 297 | Sleep(100); 298 | break; 299 | } 300 | if (a[j][i] == 2 && a[j + 1][i - 1] == 2 && a[j + 2][i - 2] == 2 && a[j + 3][i - 3] == 2 && a[j + 4][i - 4] == 2)//向左倾斜时候play2 win 301 | { 302 | win = 2; 303 | Sleep(100); 304 | break; 305 | } 306 | } 307 | } 308 | return win; 309 | } 310 | -------------------------------------------------------------------------------- /C++11: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | 8 | //int main() 9 | //{ 10 | // 内置类型的列表初始化 11 | // int x1 = { 10 }; 12 | // int x2{ 10 }; 13 | // int x3 = { 2 + 5 }; 14 | // int x4{ 2 + 5 }; 15 | // char等其他内置类型也是如此 16 | // char ch1 = { 'c' }; 17 | // char ch2{ 'c' }; 18 | // 19 | // 数组---静态数组 20 | // int arry1[] = {1,2,3,4,5}; 21 | // int arry2[]{1,2,3,4,5}; 22 | // int arry3[5]{1, 2, 3, 4, 5}; 23 | // 24 | // 数组---动态数组 25 | // int* array = new int[]{1, 2, 3, 4, 5}; 26 | // 27 | // STL容器 28 | // vector v{ 1, 2, 3, 4, 5 }; 29 | // map mp{ {1,1}, {2,2}, {3,3} }; 30 | // return 0; 31 | //} 32 | 33 | 34 | //class test 35 | //{ 36 | //private: 37 | // int a; 38 | // int b; 39 | //public: 40 | // test(int _a, int _b) :a(_a), b(_b) 41 | // {} 42 | //}; 43 | // 44 | //int main() 45 | //{ 46 | // //和使用()调用构造函数没啥区别 47 | // test t{ 1, 2 }; 48 | // return 0; 49 | //} 50 | 51 | //#include 52 | // 53 | //template 54 | //class Vector { 55 | //public: 56 | // // ... 57 | // Vector(initializer_list l) : _capacity(l.size()), _size(0) 58 | // { 59 | // _array = new T[_capacity]; 60 | // for (auto e : l) 61 | // _array[_size++] = e; 62 | // } 63 | // Vector& operator=(initializer_list l) { 64 | // delete[] _array; 65 | // size_t i = 0; 66 | // for (auto e : l) 67 | // _array[i++] = e; 68 | // return *this; 69 | // } 70 | // // ... 71 | //private: 72 | // T* _array; 73 | // size_t _capacity; 74 | // size_t _size; 75 | //}; 76 | // 77 | //int main() 78 | //{ 79 | // return 0; 80 | // //我们自己实现的类,也可以支持可变参数个数的构造了 81 | // Vector v{1,2,3,4,5}; 82 | //} 83 | 84 | 85 | //int main() 86 | //{ 87 | // vector v{1,2,3,4,5}; 88 | // return 0; 89 | //} 90 | 91 | //#include 92 | //#include 93 | //int main() 94 | //{ 95 | // short a = 32670; 96 | // short b = 32670; 97 | // // c如果给成short,会造成数据丢失,如果能够让编译器根据a+b的结果推导c的实际类型,就不会存在问题 98 | // short c = a + b; 99 | // std::map m{ { "apple", "苹果" }, { "banana", "香蕉" } }; 100 | // // 使用迭代器遍历容器, 迭代器类型太繁琐 101 | // std::map::iterator it = m.begin(); 102 | // while (it != m.end()) 103 | // { 104 | // cout << it->first << " " << it->second << endl; 105 | // ++it; 106 | // } 107 | // return 0; 108 | //} 109 | 110 | 111 | 112 | 113 | //int main() 114 | //{ 115 | // auto a = 10; 116 | // //自动推导出是int类型 117 | // cout << sizeof(a) << endl; 118 | // 119 | // map mp; 120 | // map::iterator it1; 121 | // auto it2 = mp.begin();//使用auto定义变量声明和初始化不能分离 122 | // return 0; 123 | //} 124 | 125 | // 126 | //int main() 127 | //{ 128 | // int a = 10; 129 | // int b = 20; 130 | // // 用decltype推演a+b的实际类型,作为定义c的类型 131 | // decltype(a + b) c; 132 | // //达因变量的类型 133 | // cout << typeid(c).name() << endl; 134 | // return 0; 135 | //} 136 | 137 | //void* GetMemory(size_t size) 138 | //{ 139 | // return malloc(size); 140 | //} 141 | //int main() 142 | //{ 143 | // // 如果没有带参数,推导函数的类型 144 | // cout << typeid(decltype(GetMemory)).name() << endl; 145 | // // 如果带参数列表,推导的是函数返回值的类型,注意:此处只是推演,不会执行函数 146 | // cout << typeid(decltype(GetMemory(0))).name() << endl; 147 | // return 0; 148 | //} 149 | 150 | //#include 151 | //template 152 | //class Vector 153 | //{ 154 | //public: 155 | // typedef int* iterator; 156 | // iterator begin() 157 | // { 158 | // return a; 159 | // } 160 | // iterator end() 161 | // { 162 | // //为了方便特殊处理了一下 163 | // return a+5; 164 | // } 165 | // Vector(initializer_list _a) 166 | // { 167 | // a = new T[_a.size()]; 168 | // int i = 0; 169 | // for (auto e : _a) 170 | // { 171 | // a[i] = e; 172 | // i++; 173 | // } 174 | // } 175 | //private: 176 | // int *a; 177 | //}; 178 | // 179 | //int main() 180 | //{ 181 | // Vector v{1,2,3,4,5}; 182 | // for (auto e : v) 183 | // cout << e << endl; 184 | // return 0; 185 | //} 186 | 187 | //#include 188 | //int main() 189 | //{ 190 | // //定义一个含有10个int类型的静态数组 191 | // array a; 192 | // return 0; 193 | //} 194 | 195 | 196 | 197 | //class A 198 | //{ 199 | //public: 200 | // A(int a) : _a(a) 201 | // {} 202 | // // 禁止编译器生成默认的拷贝构造函数以及赋值运算符重载 203 | // A(const A&) = delete; 204 | // A& operator(const A&) = delete; 205 | //private: 206 | // int _a; 207 | //}; 208 | //int main() 209 | //{ 210 | // A a1(10); 211 | // // 编译失败,因为该类没有拷贝构造函数 212 | // //A a2(a1); 213 | // // 编译失败,因为该类没有赋值运算符重载 214 | // A a3(20); 215 | // a3 = a2; 216 | // return 0; 217 | //} 218 | 219 | //int main() 220 | //{ 221 | // //普通的lambda表达式 222 | // [](int a, int b)->int{ 223 | // return a + b; 224 | // }; 225 | // //省略参数和返回值类型,返回值类型有编译器推导,使用捕捉列表捕捉a,b 226 | // int a = 10; 227 | // int b = 2; 228 | // [a,b]{ 229 | // return a + b; 230 | // }; 231 | // 232 | // //省略参数和返回值,无返回值 233 | // [a, b]{ 234 | // cout << a << " " << b << endl; 235 | // }; 236 | // 237 | // //省略参数和返回值类型,无返回值;捕捉列表传引用 238 | // //捕捉列表捕捉到的是变量的拷贝,不能直接修改,修改需要使用引用 239 | // [&a, &b]{ 240 | // int c = a; 241 | // a = b; 242 | // b = c; 243 | // }; 244 | // int c = 30; 245 | // //捕捉该函数中的所有边量 246 | // [=]{ 247 | // cout << a << " " << b << " " << c << endl; 248 | // }; 249 | // 250 | // //定义“函数变量”进行调用 251 | // auto add = [](int a, int b)->int{ 252 | // return a + b; 253 | // }; 254 | // 255 | // cout << add(1, 2) << endl; 256 | // 257 | // cout << a << " " << b << endl; 258 | // auto test = [&a,&b]{ 259 | // int c = a; 260 | // a = b; 261 | // b = c; 262 | // }; 263 | // //不调用不会执行 264 | // test(); 265 | // 266 | // cout << a<<" "<提示找不到operator=() 278 | // // 允许使用一个lambda表达式拷贝构造一个新的副本 279 | // auto f3(f2); 280 | // f3(); 281 | // // 可以将lambda表达式赋值给相同类型的函数指针 282 | // PF = f2; 283 | // PF(); 284 | // return 0; 285 | //} 286 | 287 | 288 | class Rate 289 | { 290 | public: 291 | Rate(double rate) : _rate(rate) 292 | {} 293 | double operator()(double money, int year) 294 | { 295 | return money * _rate * year; 296 | } 297 | private: 298 | double _rate; 299 | }; 300 | int main() 301 | { 302 | // 函数对象 303 | double rate = 0.49; 304 | Rate r1(rate); 305 | r1(10000, 2); 306 | // lamber 307 | auto r2 = [=](double monty, int year)->double{return monty*rate*year; }; 308 | r2(10000, 2); 309 | return 0; 310 | } 311 | -------------------------------------------------------------------------------- /CentralControlCache.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MouCoder/cpp_Code/6f6868685562996c866f5aa8f82ef914eada3b0e/CentralControlCache.cpp -------------------------------------------------------------------------------- /CentralControlCache.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MouCoder/cpp_Code/6f6868685562996c866f5aa8f82ef914eada3b0e/CentralControlCache.h -------------------------------------------------------------------------------- /CommonResource.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MouCoder/cpp_Code/6f6868685562996c866f5aa8f82ef914eada3b0e/CommonResource.h -------------------------------------------------------------------------------- /Date: -------------------------------------------------------------------------------- 1 | //Date.cpp 2 | void Date::displayInfo() 3 | { 4 | cout << _year << "-" << _month << "-" << _day << endl; 5 | } 6 | 7 | // 获取某年某月的天数 8 | int Date::GetMonthDay(int year, int month) 9 | { 10 | int date[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31}; 11 | if (month == 2) 12 | { 13 | //判断如果是闰年返回29,平年返回28 14 | if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) 15 | return 29; 16 | else 17 | return date[2]; 18 | } 19 | return date[month]; 20 | } 21 | 22 | //全省参数的构造函数,声明时定义了,定义时就不需要定义 23 | Date::Date(int year, int month, int day) 24 | { 25 | _year = year; 26 | _month = month; 27 | _day = day; 28 | 29 | //判断日期是否合法 30 | if (!(_year > 0 && 31 | _month > 0 && _month <= 12 && 32 | day <= this->GetMonthDay(_year, _month) && day > 0)) 33 | cout << "日期非法" << endl; 34 | } 35 | 36 | // 拷贝构造函数 37 | // d2(d1) 38 | Date::Date(const Date& d) 39 | { 40 | _year = d._year; 41 | _month = d._month; 42 | _day = d._day; 43 | } 44 | 45 | // 赋值运算符重载 46 | // d2 = d3 -> d2.operator=(&d2, d3) 47 | Date& Date::operator=(const Date& d) 48 | { 49 | _year = d._year; 50 | _month = d._month; 51 | _day = d._day; 52 | 53 | return *this; 54 | } 55 | 56 | // 日期+=天数 57 | Date& Date::operator+=(int day) 58 | { 59 | if (day < 0) 60 | { 61 | //+=负数等于-=负数的绝对值 62 | return *this -= day; 63 | } 64 | 65 | _day += day; 66 | //将日期调整合法 67 | while(_day > this->GetMonthDay(_year, _month)) 68 | { 69 | _day -= this->GetMonthDay(_year,_month); 70 | _month++; 71 | if (_month > 12) 72 | { 73 | _month = _month % 12; 74 | _year++; 75 | } 76 | } 77 | 78 | return *this; 79 | } 80 | 81 | // 日期+天数 82 | Date Date::operator+(int day) 83 | { 84 | //重新实例化一个和this相同的对象,对该对象进行+=操作 85 | Date ret(*this); 86 | 87 | ret += day; 88 | return ret; 89 | } 90 | 91 | // 日期-天数 92 | Date Date::operator-(int day) 93 | { 94 | Date ret(*this); 95 | 96 | ret -= day; 97 | return ret; 98 | } 99 | 100 | // 日期-=天数 101 | Date& Date::operator-=(int day) 102 | { 103 | if (day < 0) 104 | { 105 | return *this += (-day); 106 | } 107 | 108 | _day -= day; 109 | while (_day <= 0) 110 | { 111 | _month--; 112 | if (_month == 0) 113 | { 114 | _month = 12; 115 | _year--; 116 | } 117 | _day += this->GetMonthDay(_year,_month); 118 | } 119 | 120 | return *this; 121 | } 122 | 123 | // 前置++ 124 | Date& Date::operator++() 125 | { 126 | //返回++后 127 | this->operator+=(1); 128 | 129 | return *this; 130 | } 131 | 132 | // 后置++ 133 | Date Date::operator++(int) 134 | { 135 | Date ret(*this); 136 | 137 | this->operator++(); 138 | return ret; 139 | } 140 | 141 | // 后置-- 142 | Date Date::operator--(int) 143 | { 144 | Date ret(*this); 145 | 146 | this->operator-=(1); 147 | return ret; 148 | } 149 | 150 | // 前置-- 151 | Date& Date::operator--() 152 | { 153 | this->operator-=(1); 154 | return *this; 155 | } 156 | 157 | // >运算符重载 158 | bool Date::operator>(const Date& d) 159 | { 160 | if (_year > d._year || 161 | (_year == d._year && _month > d._month)|| 162 | (_year == d._year && _month == d._month && _day > d._day)) 163 | return true; 164 | return false; 165 | } 166 | 167 | // ==运算符重载 168 | bool Date::operator==(const Date& d) 169 | { 170 | if (_year == d._year && _month == d._month && _day == d._day) 171 | return true; 172 | return false; 173 | } 174 | 175 | // >=运算符重载 176 | inline bool Date::operator >= (const Date& d) 177 | { 178 | return this->operator==(d) || this->operator>(d); 179 | } 180 | 181 | // <运算符重载 182 | bool Date::operator < (const Date& d) 183 | { 184 | return !(this->operator>=(d)); 185 | } 186 | 187 | // <=运算符重载 188 | bool Date::operator <= (const Date& d) 189 | { 190 | return this->operator<(d) || this->operator==(d); 191 | } 192 | 193 | // !=运算符重载 194 | bool Date::operator != (const Date& d) 195 | { 196 | return !(this->operator==(d)); 197 | } 198 | 199 | // 日期-日期 返回天数 200 | int Date::operator-(const Date& d) 201 | { 202 | Date max = *this, min = d; 203 | int flag = 1; 204 | if (*this < d) 205 | { 206 | max = d; 207 | min = *this; 208 | flag = -1; 209 | } 210 | 211 | int n = 0; 212 | while (min != max) 213 | { 214 | ++n; 215 | ++min; 216 | } 217 | 218 | return n*flag; 219 | } 220 | 221 | //Date.h 222 | class Date 223 | { 224 | public: 225 | 226 | //打印日期 227 | void displayInfo(); 228 | 229 | // 获取某年某月的天数 230 | int GetMonthDay(int year, int month); 231 | 232 | // 全缺省的构造函数 233 | Date(int year = 1900, int month = 1, int day = 1); 234 | 235 | // 拷贝构造函数 236 | // d2(d1) 237 | Date(const Date& d); 238 | 239 | // 赋值运算符重载 240 | // d2 = d3 -> d2.operator=(&d2, d3) 241 | Date& operator=(const Date& d); 242 | 243 | // 日期+=天数 244 | Date& operator+=(int day); 245 | 246 | // 日期+天数 247 | Date operator+(int day); 248 | 249 | // 日期-天数 250 | Date operator-(int day); 251 | 252 | // 日期-=天数 253 | Date& operator-=(int day); 254 | 255 | // 前置++ 256 | Date& operator++(); 257 | 258 | // 后置++ 259 | Date operator++(int); 260 | 261 | // 后置-- 262 | Date operator--(int); 263 | 264 | // 前置-- 265 | Date& operator--(); 266 | 267 | // >运算符重载 268 | bool operator>(const Date& d); 269 | 270 | // ==运算符重载 271 | bool operator==(const Date& d); 272 | 273 | // >=运算符重载 274 | inline bool operator >= (const Date& d); 275 | 276 | // <运算符重载 277 | bool operator < (const Date& d); 278 | 279 | // <=运算符重载 280 | bool operator <= (const Date& d); 281 | 282 | // !=运算符重载 283 | bool operator != (const Date& d); 284 | 285 | // 日期-日期 返回天数 286 | int operator-(const Date& d); 287 | 288 | private: 289 | int _year; 290 | int _month; 291 | int _day; 292 | }; 293 | -------------------------------------------------------------------------------- /HashLinearDetection: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | enum Stat 6 | { 7 | EMPTY, 8 | EXIST, 9 | DELETE 10 | }; 11 | 12 | template 13 | struct HashNode 14 | { 15 | T _val; 16 | Stat _st = EMPTY;//该位置的状态,默认为空 17 | }; 18 | 19 | 20 | static size_t GetNextPrime(size_t prime) 21 | { 22 | static const int PRIMECOUNT = 28; 23 | static const size_t primeList[PRIMECOUNT] = 24 | { 25 | 53ul, 97ul, 193ul, 389ul, 769ul, 26 | 1543ul, 3079ul, 6151ul, 12289ul, 24593ul, 27 | 49157ul, 98317ul, 196613ul, 393241ul, 786433ul, 28 | 1572869ul, 3145739ul, 6291469ul, 12582917ul, 25165843ul, 29 | 50331653ul, 100663319ul, 201326611ul, 402653189ul, 805306457ul, 30 | 1610612741ul, 3221225473ul, 4294967291ul 31 | }; 32 | 33 | size_t i = 0; 34 | for (; i < PRIMECOUNT; ++i) 35 | { 36 | if (primeList[i] > prime) 37 | return primeList[i]; 38 | } 39 | 40 | return primeList[i]; 41 | } 42 | 43 | template 44 | struct Hash 45 | { 46 | size_t operator()(const K& key) 47 | { 48 | return key; 49 | } 50 | }; 51 | 52 | template<> 53 | struct Hash < string >//模板特化 54 | { 55 | size_t operator()(const string& s) 56 | { 57 | size_t hash = 0; 58 | for (auto ch : s) 59 | { 60 | //hash += ch; 61 | hash = hash * 131 + ch; 62 | } 63 | 64 | return hash; 65 | } 66 | }; 67 | 68 | template> 69 | class HashTable 70 | { 71 | public: 72 | bool insert(const T& key) 73 | { 74 | /*1、判断是否需要扩容: 75 | * ·哈希表为空时需要扩容 76 | * ·哈希表为满时需要扩容 77 | * ·扩容时需要注意的是:如果哈希表为空,该扩容为多少呢? 78 | * ·本质上说,这个值由我们自己定,但是研究表明当哈希函数的模数为质数时,效率较高 79 | * ·因此,这里扩容我们使用STL库中的扩容方法:调用GetNextPrime按照模数为质数的情况进行扩容 80 | * ·还有一个问题:如果哈希表满了,如何扩容? 81 | * ·如果直接扩容,不对之前插入的数据处理,会导致之前的数据的查找效率会变得非常的低 82 | * ·因此,在扩容时还需要将之前插入的数据在新的哈希表中进行重新插入。 83 | */ 84 | if (_htb.size() == 0 || _size*10 /_htb.size() >= 7) 85 | { 86 | size_t newSize = GetNextPrime(_htb.size()); 87 | //将旧的哈希表插入到新的哈希表中---构造一个哈希对象,调用该对象的额insert方法 88 | HashTable ht; 89 | ht._htb.resize(newSize);//对象中的哈希表的大小为newsize 90 | for (auto& e : _htb) 91 | { 92 | //将旧哈希表中的数据插入到对象中的新的大小为newsize的哈希表中 93 | ht.insert(e._val); 94 | } 95 | //交换两个哈希表,出了作用域对象会自动调用析构函数释放原来的空间 96 | _htb.swap(ht._htb); 97 | } 98 | 99 | /*需要注意的是,如果该值已经存在则不需要再进行插入*/ 100 | if (find(key) != nullptr) 101 | return false; 102 | 103 | /*2、使用hash函数计算出插入位置 104 | * ·这里的哈希函数使用除留余数法 105 | * ·需要注意的是,使用除留余数法对于int类型来说可以直接取模 106 | * ·对于string等其他类型不能直接取模,因此需要自定义取模方法 107 | * ·这里,我们对string的处理方式为:所有字符的ASCII求和在取模 108 | * ·因此,类模板参数中应该还有一个用来控制取模方法的仿函数 109 | */ 110 | HashFunc hf; 111 | int index = hf(key) % _htb.size(); 112 | 113 | /*3、解决哈希冲突 114 | * ·线性探测:查找空位置 115 | * ·这里需要注意的是,如果我们直接在哈希表中存储T类型的关键码 116 | * ·当一个元素从哈希表中删除后,它的位置实际上会变成随机值 117 | * ·那么在插入时,我们不知道这个位置是删除后的随机值还是没有插入的空值 118 | * ·或者说,这个位置就是我们存储的关键码。 119 | * ·因此,我们需要标记每一个位置,到底是empty还是delete或者是exist 120 | * ·因此,我们在哈希表中存储的是一个节点,这个节点中一个是值一个是状态,状态使用了一个枚举类型来表示 121 | */ 122 | if (_htb[index]._st == EXIST) 123 | { 124 | //存在哈希冲突,解决哈希冲突 125 | while (_htb[index]._st == EXIST) 126 | { 127 | index++; 128 | //为了防止数组越界,需要取模 129 | index %= _htb.size(); 130 | } 131 | } 132 | /*4、插入元素*/ 133 | _htb[index]._val = key; 134 | _htb[index]._st = EXIST; 135 | 136 | return true; 137 | } 138 | //查找 139 | HashNode* find(const T& key) 140 | { 141 | //取模找到位置 142 | HashFunc hf; 143 | int index = hf(key) % _htb.size(); 144 | //位置冲突,线性查找,找到第一个空位置停止查找 145 | if (_htb[index]._val != key) 146 | { 147 | while (_htb[index]._st != EMPTY && _htb[index]._val != key) 148 | { 149 | ++index; 150 | index %= _htb.size(); 151 | } 152 | 153 | } 154 | if (_htb[index]._st == EMPTY) 155 | return nullptr; 156 | return &_htb[index]; 157 | } 158 | bool erase(const T& key) 159 | { 160 | HashNode* ret = find(key); 161 | if (ret == false) 162 | { 163 | return false; 164 | } 165 | else 166 | { 167 | ret->_state = DELETE; 168 | return true; 169 | } 170 | } 171 | private: 172 | vector> _htb;//哈希表 173 | size_t _size;//实际存储元素的个数 174 | }; 175 | 176 | void TestHashTable() 177 | { 178 | HashTable ht; 179 | ht.insert(5); 180 | ht.insert(15); 181 | ht.insert(16); 182 | ht.insert(17); 183 | ht.insert(25); 184 | ht.insert(35); 185 | ht.insert(45); 186 | ht.insert(55); 187 | 188 | struct StrHash 189 | { 190 | size_t operator()(const string& s) 191 | { 192 | size_t hash = 0; 193 | for (auto ch : s) 194 | { 195 | hash += ch; 196 | } 197 | 198 | return hash; 199 | } 200 | }; 201 | 202 | //HashTable strht; 203 | HashTable strht; 204 | strht.insert("sort"); 205 | strht.insert("insert"); 206 | 207 | } 208 | 209 | -------------------------------------------------------------------------------- /MemoryManagement.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MouCoder/cpp_Code/6f6868685562996c866f5aa8f82ef914eada3b0e/MemoryManagement.h -------------------------------------------------------------------------------- /ModuleTest.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MouCoder/cpp_Code/6f6868685562996c866f5aa8f82ef914eada3b0e/ModuleTest.h -------------------------------------------------------------------------------- /PageCache.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MouCoder/cpp_Code/6f6868685562996c866f5aa8f82ef914eada3b0e/PageCache.cpp -------------------------------------------------------------------------------- /PageCache.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MouCoder/cpp_Code/6f6868685562996c866f5aa8f82ef914eada3b0e/PageCache.h -------------------------------------------------------------------------------- /PageMap.h: -------------------------------------------------------------------------------- 1 | #include"CommonResource.h" 2 | 3 | template 4 | class TCMalloc_PageMap2 { 5 | private: 6 | // Put 32 entries in the root and (2^BITS)/32 entries in each leaf. 7 | static const int ROOT_BITS = 5; 8 | static const int ROOT_LENGTH = 1 << ROOT_BITS; 9 | 10 | static const int LEAF_BITS = BITS - ROOT_BITS; 11 | static const int LEAF_LENGTH = 1 << LEAF_BITS; 12 | 13 | // Leaf node 14 | struct Leaf { 15 | Span* values[LEAF_LENGTH]; 16 | }; 17 | 18 | Leaf* root_[ROOT_LENGTH]; // Pointers to 32 child nodes 19 | 20 | public: 21 | typedef uintptr_t Number; 22 | 23 | explicit TCMalloc_PageMap2() { 24 | memset(root_, 0, sizeof(root_)); 25 | PreallocateMoreMemory(); 26 | } 27 | 28 | Span* get(Number k) const { 29 | const Number i1 = k >> LEAF_BITS; 30 | const Number i2 = k & (LEAF_LENGTH - 1); 31 | if ((k >> BITS) > 0 || root_[i1] == NULL) { 32 | return NULL; 33 | } 34 | return root_[i1]->values[i2]; 35 | } 36 | 37 | void set(Number k, Span* v) { 38 | const Number i1 = k >> LEAF_BITS; 39 | const Number i2 = k & (LEAF_LENGTH - 1); 40 | assert(i1 < ROOT_LENGTH); 41 | root_[i1]->values[i2] = v; 42 | } 43 | 44 | Span*& operator[](Number k) 45 | { 46 | const Number i1 = k >> LEAF_BITS; 47 | const Number i2 = k & (LEAF_LENGTH - 1); 48 | assert(i1 < ROOT_LENGTH); 49 | return root_[i1]->values[i2]; 50 | } 51 | 52 | void erase(Number k) 53 | { 54 | const Number i1 = k >> LEAF_BITS; 55 | const Number i2 = k & (LEAF_LENGTH - 1); 56 | assert(i1 < ROOT_LENGTH); 57 | root_[i1]->values[i2] = nullptr; 58 | } 59 | 60 | bool Ensure(Number start, size_t n) { 61 | for (Number key = start; key <= start + n - 1;) { 62 | const Number i1 = key >> LEAF_BITS; 63 | 64 | // Check for overflow 65 | if (i1 >= ROOT_LENGTH) 66 | return false; 67 | 68 | // Make 2nd level node if necessary 69 | if (root_[i1] == NULL) { 70 | Leaf* leaf = new Leaf; 71 | if (leaf == NULL) return false; 72 | memset(leaf, 0, sizeof(*leaf)); 73 | root_[i1] = leaf; 74 | } 75 | 76 | // Advance key past whatever is covered by this leaf node 77 | key = ((key >> LEAF_BITS) + 1) << LEAF_BITS; 78 | } 79 | return true; 80 | } 81 | 82 | void PreallocateMoreMemory() { 83 | // Allocate enough to keep track of all possible pages 84 | Ensure(0, 1 << BITS); 85 | } 86 | 87 | void* Next(Number k) const { 88 | while (k < (1 << BITS)) { 89 | const Number i1 = k >> LEAF_BITS; 90 | Leaf* leaf = root_[i1]; 91 | if (leaf != NULL) { 92 | // Scan forward in leaf 93 | for (Number i2 = k & (LEAF_LENGTH - 1); i2 < LEAF_LENGTH; i2++) { 94 | if (leaf->values[i2] != NULL) { 95 | return leaf->values[i2]; 96 | } 97 | } 98 | } 99 | // Skip to next top-level entry 100 | k = (i1 + 1) << LEAF_BITS; 101 | } 102 | return NULL; 103 | } 104 | }; -------------------------------------------------------------------------------- /QuickSort.txt: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | //左右指针 7 | int sort1(vector& v,int left,int right) 8 | { 9 | int key = right; 10 | while(left < right) 11 | { 12 | //无论排升序还是降序都必须是左边先走 13 | //也就是说,关键码在右边就左边先走,关键码在左边右边先走 14 | //左边先走找大 15 | while(left < right && v[left] <= v[key]) 16 | { 17 | left++; 18 | } 19 | //右边再走找小 20 | while(left < right && v[right] >= v[key]) 21 | { 22 | right--; 23 | } 24 | //左右交换 25 | swap(v[left],v[right]); 26 | } 27 | //交换 28 | swap(v[right],v[key]); 29 | 30 | return right; 31 | } 32 | 33 | //前后指针 34 | int sort2(vector& v,int left,int right) 35 | { 36 | //当cur小于key时prev++ 37 | //当cur大于key时,prev不变 38 | //cur再次小于key时,cur和prev交换 39 | //实际上,也就是让prev始终指向大的的时候就交换 40 | 41 | int cur = left; 42 | int prev = cur-1; 43 | 44 | while(cur <= right) 45 | { 46 | if(v[cur] <= v[right] && ++prev != cur) 47 | { 48 | swap(v[prev],v[cur]); 49 | } 50 | cur++; 51 | } 52 | 53 | return prev; 54 | } 55 | 56 | //挖坑法 57 | int sort3(vector& v,int left,int right) 58 | { 59 | int flag = v[right]; 60 | while(left < right) 61 | { 62 | //左边走找比坑的位置大的元素 63 | while(left < right && v[left] <= flag) 64 | { 65 | left++; 66 | } 67 | //将左边的大值填到右边的小坑,左边形成新的坑 68 | v[right] = v[left]; 69 | //右边走找比坑位置小的元素 70 | while(left < right && v[right] >= flag) 71 | { 72 | right--; 73 | } 74 | //将右边的小值填到左边的大坑 75 | v[left] = v[right]; 76 | } 77 | 78 | //将flag填到坑位置 79 | v[left] = flag; 80 | 81 | return left; 82 | } 83 | 84 | //递归实现 85 | void QuickSort(vector& v,int left,int right) 86 | { 87 | //左右指针 88 | /*if(left >= right) 89 | return; 90 | int index = sort1(v,left,right); 91 | QuickSort(v,left,index-1); 92 | QuickSort(v,index+1,right);*/ 93 | 94 | //前后指针 95 | if(left >= right) 96 | return ; 97 | 98 | /*int index = sort2(v,left,right); 99 | QuickSort(v,left,index-1); 100 | QuickSort(v,index+1,right);*/ 101 | 102 | int index = sort3(v,left,right); 103 | QuickSort(v,left,index-1); 104 | QuickSort(v,index+1,right); 105 | } 106 | 107 | //非递归实现 108 | void QuickSort1(vector& v) 109 | { 110 | //存储索引的栈 111 | stack> st; 112 | //begin和end入栈 113 | st.push(make_pair(0,v.size()-1)); 114 | 115 | //进行快排 116 | while(!st.empty()) 117 | { 118 | pair p = st.top(); 119 | st.pop(); 120 | int index = sort1(v,p.first,p.second); 121 | //左右部分索引继续入栈 122 | if(index - 1 > p.first) 123 | st.push(make_pair(p.first,index-1)); 124 | if(index + 1 < p.second) 125 | st.push(make_pair(index+1,p.second)); 126 | } 127 | } 128 | 129 | int main() 130 | { 131 | vector v(15); 132 | v = {1,9,2,4,0,6,8,2,5,3,4,6,8,34,25,8}; 133 | 134 | for(auto e:v) 135 | { 136 | cout< 3 | #include 4 | using namespace std; 5 | 6 | //节点颜色 7 | enum Color 8 | { 9 | RED, 10 | BLACK 11 | }; 12 | 13 | //节点定义 14 | template 15 | struct RBTreeNode 16 | { 17 | std::pair _val;//值 18 | RBTreeNode* _left;//左孩子 19 | RBTreeNode* _right;//右孩子 20 | RBTreeNode* _parent;//双亲节点 21 | Color _col;//颜色 22 | 23 | //构造函数 24 | RBTreeNode(const pair& kv) 25 | :_val(kv) 26 | , _left(nullptr), _right(nullptr), _parent(nullptr) 27 | , _col(RED) 28 | {} 29 | }; 30 | 31 | 32 | template 33 | class RBTree 34 | { 35 | typedef RBTreeNode Node; 36 | private: 37 | Node* _root = nullptr;//根节点 38 | public: 39 | //构造函数---使用默认即可 40 | //插入 41 | pair insert(const pair& node) 42 | { 43 | //申请节点 44 | Node* newNode = new Node(node); 45 | //如果根节点为空,直接插入为根节点 46 | if (_root == nullptr) 47 | { 48 | _root = newNode; 49 | _root->_col = BLACK; 50 | return make_pair(_root,true); 51 | } 52 | //找插入位置进行插入 53 | Node* cur = _root; 54 | Node* parent = nullptr; 55 | while (cur) 56 | { 57 | if (cur->_val.first > newNode->_val.first) 58 | { 59 | //插入的节点比cur小,左插 60 | parent = cur; 61 | cur = cur->_left; 62 | } 63 | else if (cur->_val.first < newNode->_val.first) 64 | { 65 | //插入的节点比cur大,右插 66 | parent = cur; 67 | cur = cur->_right; 68 | } 69 | else 70 | { 71 | //插入的节点存在,直接返回该节点的val 72 | return make_pair(cur,false); 73 | } 74 | } 75 | //找到了插入位置,进行插入 76 | if (parent->_val.first > newNode->_val.first) 77 | { 78 | //插入到parent的左边 79 | parent->_left = newNode; 80 | newNode->_parent = parent; 81 | } 82 | else 83 | { 84 | //插入到parent的右边 85 | parent->_right = newNode; 86 | newNode->_parent = parent; 87 | } 88 | //插入成功,对树进行调整 89 | cur = newNode; 90 | parent = cur->_parent; 91 | //新插入节点的父节点是红色的才需要调整---走到这里,新插入的节点父节点肯定存在 92 | while (parent && parent->_col == RED) 93 | { 94 | //走到这里grandParent节点必然是黑色的 95 | Node* grandParent = parent->_parent; 96 | Node* uncle = nullptr; 97 | if (grandParent->_left == parent) 98 | { 99 | uncle = grandParent->_right; 100 | } 101 | else 102 | { 103 | uncle = grandParent->_left; 104 | } 105 | //情况1:新插入节点的叔叔节点存在且为红 106 | if (uncle && uncle->_col == RED) 107 | { 108 | //将父节点和叔叔节点变成黑色,爷爷节点变成红色 109 | uncle->_col = BLACK; 110 | parent->_col = BLACK; 111 | grandParent->_col = RED; 112 | //继续迭代 113 | cur = grandParent; 114 | parent = cur->_parent; 115 | } 116 | else 117 | { 118 | //新插入节点的叔叔节点不存在或者新插入节点的叔叔节点为黑色 119 | if (grandParent->_left == parent) 120 | { 121 | if (parent->_left == cur) 122 | { 123 | //右单旋 124 | RotateR(grandParent); 125 | //调整颜色 126 | parent->_col = BLACK; 127 | grandParent->_col = RED; 128 | } 129 | else 130 | { 131 | //左右双旋 132 | RotateL(parent); 133 | RotateR(grandParent); 134 | //调整颜色 135 | cur->_col = BLACK; 136 | grandParent->_col = RED; 137 | } 138 | } 139 | else 140 | { 141 | if (parent->_right == cur) 142 | { 143 | //左单旋 144 | RotateL(grandParent); 145 | parent->_col = BLACK; 146 | grandParent->_col = RED; 147 | } 148 | else 149 | { 150 | //右左双旋 151 | RotateR(parent); 152 | RotateL(grandParent); 153 | //调整颜色 154 | cur->_col = BLACK; 155 | grandParent->_col = RED; 156 | } 157 | } 158 | break; 159 | } 160 | } 161 | 162 | //在调整过程中,有可能将根节点变成了红色节点,因此需要将根节点调整成黑色的 163 | _root->_col = BLACK; 164 | 165 | return make_pair(newNode,true); 166 | } 167 | 168 | //右单旋 169 | void RotateR(Node* parent) 170 | { 171 | Node* subL = parent->_left; 172 | Node* subLR = subL->_right; 173 | 174 | parent->_left = subLR; 175 | if (subLR) 176 | subLR->_parent = parent; 177 | 178 | Node* parentParent = parent->_parent; 179 | 180 | subL->_right = parent; 181 | parent->_parent = subL; 182 | 183 | if (parent == _root) 184 | { 185 | _root = subL; 186 | _root->_parent = nullptr; 187 | } 188 | else 189 | { 190 | if (parentParent->_left == parent) 191 | { 192 | parentParent->_left = subL; 193 | } 194 | else 195 | { 196 | parentParent->_right = subL; 197 | } 198 | 199 | subL->_parent = parentParent; 200 | } 201 | } 202 | //左单旋 203 | void RotateL(Node* parent) 204 | { 205 | Node* subR = parent->_right; 206 | Node* subRL = subR->_left; 207 | 208 | parent->_right = subRL; 209 | if (subRL) 210 | { 211 | subRL->_parent = parent; 212 | } 213 | 214 | subR->_left = parent; 215 | 216 | Node* parentParent = parent->_parent; 217 | parent->_parent = subR; 218 | 219 | if (_root == parent) 220 | { 221 | _root = subR; 222 | } 223 | else 224 | { 225 | if (parentParent->_left == parent) 226 | { 227 | parentParent->_left = subR; 228 | } 229 | else 230 | { 231 | parentParent->_right = subR; 232 | } 233 | } 234 | 235 | subR->_parent = parentParent; 236 | } 237 | 238 | static void _inOrder(Node* root) 239 | { 240 | if (root == nullptr) 241 | return; 242 | _inOrder(root->_left); 243 | std::cout << root->_val.first << " "; 244 | _inOrder(root->_right); 245 | } 246 | //中序遍历 247 | void inOrder() 248 | { 249 | _inOrder(_root); 250 | std::cout << endl; 251 | } 252 | 253 | bool RedNode(Node* root) 254 | { 255 | if (root == nullptr) 256 | { 257 | return true; 258 | } 259 | if (root->_col == RED) 260 | { 261 | //判断父节点是否为红色 262 | if (root->_parent && root->_parent->_col == RED) 263 | { 264 | return false; 265 | } 266 | } 267 | //判断左右子树 268 | return RedNode(root->_left) && RedNode(root->_right); 269 | } 270 | 271 | bool BlackNodeNum(Node* root,int blackNum,int num) 272 | { 273 | //检查是否每条路径上的黑色节点的个数都相同 274 | if (root == nullptr) 275 | { 276 | return blackNum == num; 277 | } 278 | 279 | if (root->_col == BLACK) 280 | { 281 | blackNum++; 282 | } 283 | 284 | return BlackNodeNum(root->_left, blackNum, num) && BlackNodeNum(root->_right, blackNum, num); 285 | } 286 | 287 | //检查红黑树 288 | bool check() 289 | { 290 | if (_root && _root->_col == RED) 291 | { 292 | return false; 293 | } 294 | 295 | //求出一条路径上黑色节点的个数 296 | int num = 0; 297 | Node* cur = _root; 298 | while (cur) 299 | { 300 | if (cur->_col == BLACK) 301 | { 302 | num++; 303 | } 304 | cur = cur->_left; 305 | } 306 | return RedNode(_root) && BlackNodeNum(_root, 0,num); 307 | } 308 | 309 | }; 310 | -------------------------------------------------------------------------------- /RBTreeIterator: -------------------------------------------------------------------------------- 1 | namespace Moua 2 | { 3 | //定义节点 4 | template 5 | struct RBTreeNode 6 | { 7 | typedef RBTreeNode Node; 8 | Color _col; 9 | Node* _parent; 10 | Node* _left; 11 | Node* _right; 12 | 13 | Value_Type _val; 14 | 15 | //构造函数 16 | RBTreeNode(const Value_Type& val) 17 | :_col(RED), 18 | _val(val), 19 | _parent(nullptr), _left(nullptr), _right(nullptr) 20 | {} 21 | 22 | }; 23 | 24 | //迭代器定义 25 | //template 26 | template 27 | struct RBTreeIterator 28 | { 29 | typedef RBTreeNode Node; 30 | typedef RBTreeIterator Self; 31 | Node* _node; 32 | //构造函数 33 | RBTreeIterator(Node* nd) 34 | :_node(nd) 35 | {} 36 | 37 | Ref operator*() 38 | { 39 | return _node->_val; 40 | } 41 | Ptr operator->() 42 | { 43 | return &(_node->_val); 44 | } 45 | 46 | //前置++ 47 | Self operator++() 48 | { 49 | if (_node->_right) 50 | { 51 | //找到右孩子节点的最左孩子节点 52 | Node* cur = _node->_right; 53 | while (cur->_left) 54 | { 55 | cur = cur->_left; 56 | } 57 | _node = cur; 58 | } 59 | else 60 | { 61 | //当前节点的右孩子节点为空 62 | Node* cur = _node; 63 | Node* parent = cur->_parent; 64 | 65 | //如果当前节点是父节点的右孩子节点 66 | while (parent && parent->_right == cur) 67 | { 68 | cur = parent; 69 | parent = parent->_parent; 70 | } 71 | _node = parent; 72 | } 73 | return *this; 74 | } 75 | //后置++ 76 | Self operator++(int) 77 | { 78 | Self ret = *this; 79 | //调用前置++ 80 | ++(*this); 81 | return ret; 82 | } 83 | //前置-- 84 | Self operator--() 85 | { 86 | //左子树存在 87 | if (_node->_left) 88 | { 89 | //找左子树的最右节点 90 | Node* cur = _node->_left; 91 | while (cur->_right) 92 | { 93 | cur = cur->_right; 94 | } 95 | } 96 | else 97 | { 98 | //左子树不存在,向上找 99 | Node* cur = _node; 100 | Node* parent = cur->_parent; 101 | 102 | //找不是父节点的左孩子节点的节点 103 | while (parent && parent->_left == cur) 104 | { 105 | cur = parent; 106 | parent = parent->_parent; 107 | } 108 | _node = parent; 109 | } 110 | } 111 | //后置-- 112 | Self operator--(int) 113 | { 114 | Self cur = this; 115 | --(*this); 116 | return cur; 117 | } 118 | //不等于 119 | bool operator!=(const Self s) const 120 | { 121 | return _node != s._node; 122 | } 123 | }; 124 | 125 | //红黑树 126 | template 127 | class RBTree 128 | { 129 | //注意:节点模板参数传T即可 130 | typedef RBTreeNode Node; 131 | private: 132 | Node* _root = nullptr;//根节点 133 | public: 134 | typedef RBTreeIterator iterator; 135 | typedef RBTreeIterator ConstIterator; 136 | 137 | iterator begin() 138 | { 139 | Node* cur = _root; 140 | //返回数的最左孩子节点 141 | while (cur && cur->_left) 142 | { 143 | cur = cur->_left; 144 | } 145 | 146 | return iterator(cur); 147 | } 148 | 149 | iterator end() 150 | { 151 | //直接返回一个空节点即可 152 | return iterator(nullptr); 153 | } 154 | 155 | //插入---插入的节点的值应该是T类型的 156 | pair insert(const T& val) 157 | { 158 | KeyOfT compare;//对仿函数进行实例化 159 | //申请节点 160 | Node* newNode = new Node(val); 161 | //如果根节点为空,直接插入为根节点 162 | if (_root == nullptr) 163 | { 164 | _root = newNode; 165 | _root->_col = BLACK; 166 | return make_pair(_root, true); 167 | } 168 | //找插入位置进行插入 169 | Node* cur = _root; 170 | Node* parent = nullptr; 171 | while (cur) 172 | { 173 | // 174 | 这里的比较直接使用仿函数进行比较(set和map的比较方式不� 175 | ��) 176 | if (compare(cur->_val) > compare(newNode->_val)) 177 | { 178 | //插入的节点比cur小,左插 179 | parent = cur; 180 | cur = cur->_left; 181 | } 182 | else if (compare(cur->_val) < compare(newNode->_val)) 183 | { 184 | //插入的节点比cur大,右插 185 | parent = cur; 186 | cur = cur->_right; 187 | } 188 | else 189 | { 190 | //插入的节点存在,直接返回该节点的val 191 | return make_pair(cur, false); 192 | } 193 | } 194 | //找到了插入位置,进行插入 195 | if (compare(parent->_val) > compare(newNode->_val)) 196 | { 197 | //插入到parent的左边 198 | parent->_left = newNode; 199 | newNode->_parent = parent; 200 | } 201 | else 202 | { 203 | //插入到parent的右边 204 | parent->_right = newNode; 205 | newNode->_parent = parent; 206 | } 207 | //插入成功,对树进行调整 208 | cur = newNode; 209 | parent = cur->_parent; 210 | //新插入节点的父节点是红色的才需要调整--- 211 | 走到这里,新插入的节点父节点肯定存在 212 | while (parent && parent->_col == RED) 213 | { 214 | //走到这里grandParent节点必然是黑色的 215 | Node* grandParent = parent->_parent; 216 | Node* uncle = nullptr; 217 | if (grandParent->_left == parent) 218 | { 219 | uncle = grandParent->_right; 220 | } 221 | else 222 | { 223 | uncle = grandParent->_left; 224 | } 225 | //情况1:新插入节点的叔叔节点存在且为红 226 | if (uncle && uncle->_col == RED) 227 | { 228 | //将父节点和叔叔节点变成黑色,爷爷节点变成红色 229 | uncle->_col = BLACK; 230 | parent->_col = BLACK; 231 | grandParent->_col = RED; 232 | //继续迭代 233 | cur = grandParent; 234 | parent = cur->_parent; 235 | } 236 | else 237 | { 238 | // 239 | 新插入节点的叔叔节点不存在或者新插入节点的叔叔节点为� 240 | ��色 241 | if (grandParent->_left == parent) 242 | { 243 | if (parent->_left == cur) 244 | { 245 | //右单旋 246 | RotateR(grandParent); 247 | //调整颜色 248 | parent->_col = BLACK; 249 | grandParent->_col = RED; 250 | } 251 | else 252 | { 253 | //左右双旋 254 | RotateL(parent); 255 | RotateR(grandParent); 256 | //调整颜色 257 | cur->_col = BLACK; 258 | grandParent->_col = RED; 259 | } 260 | } 261 | else 262 | { 263 | if (parent->_right == cur) 264 | { 265 | //左单旋 266 | RotateL(grandParent); 267 | parent->_col = BLACK; 268 | grandParent->_col = RED; 269 | } 270 | else 271 | { 272 | //右左双旋 273 | RotateR(parent); 274 | RotateL(grandParent); 275 | //调整颜色 276 | cur->_col = BLACK; 277 | grandParent->_col = RED; 278 | } 279 | } 280 | break; 281 | } 282 | } 283 | 284 | // 285 | 在调整过程中,有可能将根节点变成了红色节点,因此需要� 286 | ��根节点调整成黑色的 287 | _root->_col = BLACK; 288 | 289 | return make_pair(newNode, true); 290 | } 291 | 292 | //右单旋 293 | void RotateR(Node* parent) 294 | { 295 | Node* subL = parent->_left; 296 | Node* subLR = subL->_right; 297 | 298 | parent->_left = subLR; 299 | if (subLR) 300 | subLR->_parent = parent; 301 | 302 | Node* parentParent = parent->_parent; 303 | 304 | subL->_right = parent; 305 | parent->_parent = subL; 306 | 307 | if (parent == _root) 308 | { 309 | _root = subL; 310 | _root->_parent = nullptr; 311 | } 312 | else 313 | { 314 | if (parentParent->_left == parent) 315 | { 316 | parentParent->_left = subL; 317 | } 318 | else 319 | { 320 | parentParent->_right = subL; 321 | } 322 | 323 | subL->_parent = parentParent; 324 | } 325 | } 326 | //左单旋 327 | void RotateL(Node* parent) 328 | { 329 | Node* subR = parent->_right; 330 | Node* subRL = subR->_left; 331 | 332 | parent->_right = subRL; 333 | if (subRL) 334 | { 335 | subRL->_parent = parent; 336 | } 337 | 338 | subR->_left = parent; 339 | 340 | Node* parentParent = parent->_parent; 341 | parent->_parent = subR; 342 | 343 | if (_root == parent) 344 | { 345 | _root = subR; 346 | } 347 | else 348 | { 349 | if (parentParent->_left == parent) 350 | { 351 | parentParent->_left = subR; 352 | } 353 | else 354 | { 355 | parentParent->_right = subR; 356 | } 357 | } 358 | 359 | subR->_parent = parentParent; 360 | } 361 | 362 | static void _inOrder(Node* root) 363 | { 364 | KeyOfT compare;//对仿函数进行实例化 365 | if (root == nullptr) 366 | return; 367 | _inOrder(root->_left); 368 | std::cout << compare(root->_val) << " "; 369 | _inOrder(root->_right); 370 | } 371 | //中序遍历 372 | void inOrder() 373 | { 374 | _inOrder(_root); 375 | std::cout << endl; 376 | } 377 | 378 | bool RedNode(Node* root) 379 | { 380 | if (root == nullptr) 381 | { 382 | return true; 383 | } 384 | if (root->_col == RED) 385 | { 386 | //判断父节点是否为红色 387 | if (root->_parent && root->_parent->_col == RED) 388 | { 389 | return false; 390 | } 391 | } 392 | //判断左右子树 393 | return RedNode(root->_left) && RedNode(root->_right); 394 | } 395 | 396 | bool BlackNodeNum(Node* root, int blackNum, int num) 397 | { 398 | //检查是否每条路径上的黑色节点的个数都相同 399 | if (root == nullptr) 400 | { 401 | return blackNum == num; 402 | } 403 | 404 | if (root->_col == BLACK) 405 | { 406 | blackNum++; 407 | } 408 | 409 | return BlackNodeNum(root->_left, blackNum, num) && BlackNodeNum(root-> 410 | _right, blackNum, num); 411 | } 412 | 413 | //检查红黑树 414 | bool check() 415 | { 416 | if (_root && _root->_col == RED) 417 | { 418 | return false; 419 | } 420 | 421 | //求出一条路径上黑色节点的个数 422 | int num = 0; 423 | Node* cur = _root; 424 | while (cur) 425 | { 426 | if (cur->_col == BLACK) 427 | { 428 | num++; 429 | } 430 | cur = cur->_left; 431 | } 432 | return RedNode(_root) && BlackNodeNum(_root, 0, num); 433 | } 434 | }; 435 | } 436 | -------------------------------------------------------------------------------- /ThreadCache.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MouCoder/cpp_Code/6f6868685562996c866f5aa8f82ef914eada3b0e/ThreadCache.cpp -------------------------------------------------------------------------------- /ThreadCache.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MouCoder/cpp_Code/6f6868685562996c866f5aa8f82ef914eada3b0e/ThreadCache.h -------------------------------------------------------------------------------- /WuZiQi: -------------------------------------------------------------------------------- 1 | #define _CRT_SECURE_NO_WARNINGS 1 2 | #include"Goban.h" 3 | 4 | int a[16][16] = {0}; 5 | 6 | bool chongsi(int *play1) 7 | { 8 | //冲四---横纵、斜几个情况进行分析 9 | /*横向*/ 10 | for (int i = 0; i < 16; i++) 11 | { 12 | //判断当前行是否存在连续四个黑子,且该连续四个黑子的左侧或者右侧存在一个白子 13 | for (int j = 0; j < 16; j++) 14 | { 15 | if (j <= 12 && a[i][j] == 1) 16 | { 17 | //判断是否会从j开始出现连续四个 18 | if (a[i][j + 1] == 1 && a[i][j + 2] == 1 && a[i][j + 3] == 1) 19 | { 20 | //判断该四连的左右是否有白子或者左右已经到达边界 21 | if (j + 3 == 15 && a[i][j - 1] == 0) 22 | { 23 | a[i][j - 1] = 2; 24 | *play1 = 1; 25 | setfillcolor(WHITE); 26 | solidcircle(20 + (j - 1) * 30, 20 + i * 30, 12); 27 | return true;//赌成功了 28 | } 29 | else if (j == 0 && a[i][j + 4] == 0) 30 | { 31 | a[i][j + 4] = 2; 32 | *play1 = 1; 33 | setfillcolor(WHITE); 34 | solidcircle(20 + (j + 4) * 30, 20 + i * 30, 12); 35 | return true;//赌成功了 36 | } 37 | else if (j < 12 && a[i][j - 1] == 2 && a[i][j + 4] == 0) 38 | { 39 | a[i][j + 4] = 2; 40 | *play1 = 1; 41 | setfillcolor(WHITE); 42 | solidcircle(20 + (j + 4) * 30, 20 + i * 30, 12); 43 | return true;//赌成功了 44 | } 45 | else if (j > 0 && a[i][j + 4] == 2 && a[i][j - 1] == 0) 46 | { 47 | a[i][j - 1] = 2; 48 | *play1 = 1; 49 | setfillcolor(WHITE); 50 | solidcircle(20 + (j - 1) * 30, 20 + i * 30, 12); 51 | return true;//赌成功了 52 | } 53 | } 54 | } 55 | } 56 | } 57 | /*纵向*/ 58 | for (int i = 0; i < 16; i++) 59 | { 60 | //判断当前行是否存在连续四个黑子,且该连续四个黑子的左侧或者右侧存在一个白子 61 | for (int j = 0; j < 16; j++) 62 | { 63 | if (j <= 12 && a[j][i] == 1) 64 | { 65 | //判断是否会从j开始出现连续四个 66 | if (a[j + 1][i] == 1 && a[j + 2][i] == 1 && a[j + 3][i] == 1) 67 | { 68 | if (j == 0 && a[j + 4][i] == 0) 69 | { 70 | a[j + 4][i] = 2; 71 | *play1 = 1; 72 | setfillcolor(WHITE); 73 | solidcircle(20 + i * 30, 20 + (j + 4) * 30, 12); 74 | return true;//赌成功了 75 | } 76 | else if (j + 3 == 15 && a[j - 1][i] == 0) 77 | { 78 | a[j - 1][i] = 2; 79 | *play1 = 1; 80 | setfillcolor(WHITE); 81 | solidcircle(20 + i * 30, 20 + (j - 1) * 30, 12); 82 | return true;//赌成功了 83 | } 84 | else if (j > 0 && a[j + 4][i] == 2 && a[j - 1][i] == 0) 85 | { 86 | a[j - 1][i] = 2; 87 | *play1 = 1; 88 | setfillcolor(WHITE); 89 | solidcircle(20 + i * 30, 20 + (j - 1) * 30, 12); 90 | return true;//赌成功了 91 | } 92 | else if (j < 12 && a[j - 1][i] == 2 && a[j + 4][i] == 0) 93 | { 94 | a[j + 4][i] = 2; 95 | *play1 = 1; 96 | setfillcolor(WHITE); 97 | solidcircle(20 + i * 30, 20 + (j + 4) * 30, 12); 98 | return true;//赌成功了 99 | } 100 | } 101 | } 102 | } 103 | } 104 | /*左斜*/ 105 | for (int i = 0; i < 13; i++) 106 | { 107 | for (int j = 3; j < 16; j++) 108 | { 109 | if (!((i == 0 && j == 3) || (i == 12 && j == 15))) 110 | { 111 | if (a[i][j] == 1) 112 | { 113 | if (a[i + 1][j - 1] == 1 && a[i + 2][j - 2] == 1 && a[i + 3][j - 3] == 1) 114 | { 115 | if (i == 0 && a[i + 4][j - 4] == 0) 116 | { 117 | a[i + 4][j - 4] = 2; 118 | *play1 = 1; 119 | setfillcolor(WHITE); 120 | solidcircle(20 + (j - 4) * 30, 20 + (i + 4) * 30, 12); 121 | return true;//赌成功了 122 | } 123 | else if (i == 12 && a[i - 1][j + 1] == 0) 124 | { 125 | a[i - 1][j + 1] = 2; 126 | *play1 = 1; 127 | setfillcolor(WHITE); 128 | solidcircle(20 + (j + 1) * 30, 20 + (i - 1) * 30, 12); 129 | return true;//赌成功了 130 | } 131 | else if (j == 3 && a[i - 1][j + 1] == 0) 132 | { 133 | a[i - 1][j + 1] = 2; 134 | *play1 = 1; 135 | setfillcolor(WHITE); 136 | solidcircle(20 + (j + 1) * 30, 20 + (i - 1) * 30, 12); 137 | return true;//赌成功了 138 | } 139 | else if (j == 15 && a[i + 4][j - 4] == 0) 140 | { 141 | a[i + 4][j - 4] = 2; 142 | *play1 = 1; 143 | setfillcolor(WHITE); 144 | solidcircle(20 + (j - 4) * 30, 20 + (i + 4) * 30, 12); 145 | return true;//赌成功了 146 | } 147 | else if (i < 12 && a[i - 1][j + 1] == 2 && a[i + 4][j - 4] == 0) 148 | { 149 | a[i + 4][j - 4] = 2; 150 | *play1 = 1; 151 | setfillcolor(WHITE); 152 | solidcircle(20 + (j - 4) * 30, 20 + (i + 4) * 30, 12); 153 | return true;//赌成功了 154 | } 155 | else if (i > 0 && a[i + 4][j - 4] == 2 && a[i - 1][j + 1] == 0) 156 | { 157 | a[i - 1][j + 1] = 2; 158 | *play1 = 1; 159 | setfillcolor(WHITE); 160 | solidcircle(20 + (j + 1) * 30, 20 + (i - 1) * 30, 12); 161 | return true;//赌成功了 162 | } 163 | } 164 | } 165 | } 166 | } 167 | } 168 | /*右斜*/ 169 | for (int i = 0; i < 13; i++) 170 | { 171 | for (int j = 0; j < 13; j++) 172 | { 173 | if (!(i == 0 && j == 12) || (i == 12 && j == 0)) 174 | { 175 | if (a[i][j] == 1) 176 | { 177 | if (a[i + 1][j + 1] == 1 && a[i + 2][j + 2] == 1 && a[i + 3][j + 3] == 1) 178 | { 179 | if (i == 0 && a[i + 4][j + 4] == 0) 180 | { 181 | a[i + 4][j + 4] = 2; 182 | *play1 = 1; 183 | setfillcolor(WHITE); 184 | solidcircle(20 + (j + 4) * 30, 20 + (i + 4) * 30, 12); 185 | return true;//赌成功了 186 | } 187 | else if (i == 12 && a[i - 1][j - 1] == 0) 188 | { 189 | a[i - 1][j - 1] = 2; 190 | *play1 = 1; 191 | setfillcolor(WHITE); 192 | solidcircle(20 + (j - 1) * 30, 20 + (i - 1) * 30, 12); 193 | return true;//赌成功了 194 | } 195 | else if (j == 12 && a[i - 1][j - 1] == 0) 196 | { 197 | a[i - 1][j - 1] = 2; 198 | *play1 = 1; 199 | setfillcolor(WHITE); 200 | solidcircle(20 + (j - 1) * 30, 20 + (i - 1) * 30, 12); 201 | return true;//赌成功了 202 | } 203 | else if (j == 0 && a[i + 4][j + 4] == 0) 204 | { 205 | a[i + 4][j + 4] = 2; 206 | *play1 = 1; 207 | setfillcolor(WHITE); 208 | solidcircle(20 + (j + 4) * 30, 20 + (i + 4) * 30, 12); 209 | return true;//赌成功了 210 | } 211 | else if (j < 12 && a[i - 1][j - 1] == 2 && a[i + 4][j + 4] == 0) 212 | { 213 | a[i + 4][j + 4] = 2; 214 | *play1 = 1; 215 | setfillcolor(WHITE); 216 | solidcircle(20 + (j + 4) * 30, 20 + (i + 4) * 30, 12); 217 | return true;//赌成功了 218 | } 219 | else if (i > 0 && a[i + 4][j + 4] == 2 && a[i - 1][j - 1] == 0) 220 | { 221 | a[i - 1][j - 1] = 2; 222 | *play1 = 1; 223 | setfillcolor(WHITE); 224 | solidcircle(20 + (j - 1) * 30, 20 + (i - 1) * 30, 12); 225 | return true;//赌成功了 226 | } 227 | } 228 | } 229 | } 230 | } 231 | } 232 | return false; 233 | } 234 | 235 | //活三 236 | bool huosan(int* play1) 237 | { 238 | //三连两边都有空格 239 | /*横向*/ 240 | for (int i = 0; i < 16; i++) 241 | { 242 | for (int j = 1; j < 13; j++) 243 | { 244 | if (a[i][j] == 1) 245 | { 246 | if (a[i][j + 1] == 1 && a[i][j + 2] == 1) 247 | { 248 | if (a[i][j - 1] == 0 && a[i][j + 3] == 0) 249 | { 250 | if (j == 1 || j != 12) 251 | { 252 | //必然堵右边 253 | a[i][j + 3] = 2; 254 | *play1 = 1; 255 | setfillcolor(WHITE); 256 | solidcircle(20 + (j + 3) * 30, 20 + i * 30, 12); 257 | return true;//赌成功了 258 | } 259 | if (j == 12) 260 | { 261 | //必然堵左边 262 | a[i][j - 1] = 2; 263 | *play1 = 1; 264 | setfillcolor(WHITE); 265 | solidcircle(20 + (j - 1) * 30, 20 + i * 30, 12); 266 | return true;//赌成功了 267 | } 268 | } 269 | } 270 | } 271 | } 272 | } 273 | /*纵向*/ 274 | for (int j = 0; j < 16; j++) 275 | { 276 | for (int i = 1; i < 13; i++) 277 | { 278 | if (a[i][j] == 1) 279 | { 280 | if (a[i + 1][j] == 1 && a[i + 2][j] == 1) 281 | { 282 | if (a[i - 1][j] == 0 && a[i + 3][j] == 0) 283 | { 284 | if (i == 1 || i != 12) 285 | { 286 | a[i + 3][j] = 2; 287 | *play1 = 1; 288 | setfillcolor(WHITE); 289 | solidcircle(20 + j * 30, 20 + (i+3) * 30, 12); 290 | return true;//赌成功了 291 | } 292 | else if (i == 12) 293 | { 294 | a[i - 1][j] = 2; 295 | *play1 = 1; 296 | setfillcolor(WHITE); 297 | solidcircle(20 + j * 30, 20 + (i-1) * 30, 12); 298 | return true;//赌成功了 299 | } 300 | } 301 | } 302 | } 303 | } 304 | } 305 | /*左斜*/ 306 | for (int i = 1; i < 13; i++) 307 | { 308 | for (int j = 3; j < 15; j++) 309 | { 310 | if (a[i][j] == 1) 311 | { 312 | if (a[i + 1][j - 1] == 1 && a[i + 2][j - 2] == 1) 313 | { 314 | if (a[i - 1][j + 1] == 0 && a[i + 3][j - 3] == 0) 315 | { 316 | cout << i <<" "< 3) && (i == 15 || a[i+1][j] == 1)) 542 | { 543 | //只能向左判断 544 | if (a[i][j - 1] != 1 && a[i][j - 2] != 1 && a[i][j - 3] != 1 && a[i][j - 4] != 1) 545 | { 546 | for (int k = j - 1; k >= j - 4; k--) 547 | { 548 | if (a[i][k] == 0) 549 | { 550 | *play1 = 1; 551 | setfillcolor(WHITE); 552 | solidcircle(20 + k * 30, 20 + i * 30, 12); 553 | return true;//找成功了 554 | } 555 | } 556 | } 557 | } 558 | else 559 | { 560 | //左右都需要判断 561 | } 562 | } 563 | /*竖向*/ 564 | if (*play1 == 0) 565 | { 566 | } 567 | /*左斜*/ 568 | if (*play1 == 0) 569 | { 570 | } 571 | /*右斜*/ 572 | if (*play1 == 0) 573 | { 574 | } 575 | } 576 | } 577 | } 578 | return false; 579 | } 580 | void Play::PlayGame(MOUSEMSG ms, int* play1, int* play2) 581 | { 582 | //人走 583 | for (int lie = 20; lie <= 490; lie += 30) 584 | { 585 | if (ms.x <= lie + 15 && ms.x >= lie - 15) 586 | { 587 | for (int hang = 20; hang <= 490; hang += 30) 588 | { 589 | if (ms.y <= hang + 15 && ms.y >= hang - 15) 590 | { 591 | if (*play1 == 1 && a[hang / 30][lie / 30] == 0) 592 | { 593 | setfillcolor(BLACK); 594 | solidcircle(lie, hang, 12); 595 | a[hang / 30][lie / 30] = 1; 596 | cout << hang / 30 << " " << lie / 30 << endl; 597 | *play1 = 0; 598 | break; 599 | } 600 | } 601 | } 602 | } 603 | } 604 | //电脑走 605 | /*思路:遍历棋盘查找对方是否存在成功的可能,如果有堵住对方;如果没有,找自己即将能成功的位置落子*/ 606 | if (du(play1) == false) 607 | { 608 | //找自己可以成的位置,如果没有随机落子 609 | if (zhao(play1) == false) 610 | { 611 | cout << *play1 << endl; 612 | for (int i = 0; i < 16; i++) 613 | { 614 | for (int j = 0; j < 16; j++) 615 | { 616 | if (a[i][j] == 0) 617 | { 618 | a[i][j] = 2; 619 | *play1 = 1; 620 | setfillcolor(WHITE); 621 | solidcircle(20 + j * 30, 20 + i* 30, 12); 622 | return; 623 | } 624 | } 625 | } 626 | } 627 | } 628 | } 629 | void Menu::Display() 630 | { 631 | //初始化绘图窗口 632 | initgraph(416, 624, SHOWCONSOLE); 633 | /*设置背景图*/ 634 | IMAGE img; 635 | //缩放因子,例如设置宽度为100的单元格,实际的绘制宽度为(100*缩放因子) 636 | setaspectratio(1.1, 1); 637 | //从图片文件获取图像(图像的image指针,图像名,资源名称,图片的拉伸宽度、高度,是否自适应图片大小) 638 | loadimage(&img, "begin.jpg", 377, 624, 1); 639 | putimage(0, 0, &img); 640 | 641 | /*控制鼠标移动操作*/ 642 | MOUSEMSG m;//鼠标操作 643 | while (true) 644 | { 645 | m = GetMouseMsg();//获取鼠标消息 646 | //左键按下:WM_LBUTTONDOWN 647 | if (m.uMsg == WM_LBUTTONDOWN && (m.x >= 72 && m.x <= 307 && m.y >= 340 && m.y <= 400 648 | || m.x >= 72 && m.x <= 307 && m.y >= 420 && m.y <= 480)) 649 | { 650 | //uMsg鼠标信息 WM_MOUSEMOVE鼠标移动消息 x y表示鼠标位置坐标 651 | //当鼠标在"人机对战、双人对战"上时,显示红色边框 652 | if (m.x >= 72 && m.x <= 307 && m.y >= 340 && m.y <= 400) 653 | { 654 | setlinecolor(YELLOW); 655 | setlinestyle(PS_SOLID | PS_JOIN_ROUND, 2); 656 | //空心矩形框 657 | rectangle(72, 340, 300, 400); 658 | } 659 | else if (m.x >= 72 && m.x <= 307 && m.y >= 420 && m.y <= 480) 660 | { 661 | setlinecolor(YELLOW); 662 | //空心矩形框 663 | rectangle(72, 420, 300, 480); 664 | } 665 | Sleep(500); 666 | //清除屏幕内容 667 | cleardevice(); 668 | //休眠五秒 669 | Sleep(300); 670 | //关闭窗口 671 | closegraph(); 672 | //使用匿名对象打开棋盘界面 673 | Menu().ChessBoard(m); 674 | break; 675 | } 676 | } 677 | } 678 | 679 | void Menu::ChessBoard(MOUSEMSG m) 680 | { 681 | //初始化绘图窗口 682 | initgraph(665,490, SHOWCONSOLE); 683 | 684 | /*设置棋盘背景背景图*/ 685 | IMAGE img; 686 | //缩放因子,例如设置宽度为100的单元格,实际的绘制宽度为(100*缩放因子) 687 | //setaspectratio(1.1, 1); 688 | //从图片文件获取图像(图像的image指针,图像名,资源名称,图片的拉伸宽度、高度,是否自适应图片大小) 689 | loadimage(&img, "chessBoard.jpg", 665,490); 690 | putimage(0, 0, &img); 691 | 692 | //绘制棋盘 693 | while (true) 694 | { 695 | for (int i = 20; i <= 470; i+=30) 696 | { 697 | setlinecolor(WHITE); 698 | line(20,i,470,i); 699 | line(i,20,i,470); 700 | } 701 | //如果左键双人,跳入双人游戏 702 | if (m.uMsg == WM_LBUTTONDOWN && m.x >= 72 && m.x <= 307 && m.y >= 420 && m.y <= 480) 703 | { 704 | Play().TwoPlayerGame(m); 705 | } 706 | else 707 | { 708 | Play().ComputerUserGame(m); 709 | } 710 | } 711 | } 712 | 713 | void Play::buttonRingth(MOUSEMSG m,MOUSEMSG ms, int win) 714 | { 715 | if (ms.x >= 500 && ms.x <= 655 && ms.y >= 30 && ms.y <= 80) 716 | { 717 | memset(a, 0, sizeof(a)); 718 | //重新开始 719 | setlinecolor(RED); 720 | //空心矩形框 721 | rectangle(500, 30, 655, 80); 722 | Sleep(300); 723 | Menu().ChessBoard(m); 724 | } 725 | else if (ms.x >= 500 && ms.x <= 655 && ms.y >= 115 && ms.y <= 165) 726 | { 727 | memset(a, 0, sizeof(a)); 728 | //返回菜单 729 | setlinecolor(RED); 730 | //空心矩形框 731 | rectangle(500, 115, 655, 165); 732 | Sleep(300); 733 | Menu().Display(); 734 | } 735 | else if (win == 0 && ms.x >= 500 && ms.x <= 655 && ms.y >= 200 && ms.y <= 250) 736 | { 737 | //悔棋 738 | setlinecolor(RED); 739 | //空心矩形框 740 | rectangle(500, 200, 655, 250); 741 | } 742 | } 743 | 744 | void Play::displayWin(int n1,int n2) 745 | { 746 | memset(a,0,sizeof(a)); 747 | //显示哪一方赢了,n1为0表示双人为1表示人机,n2为0表示黑、人为1表示白、机 748 | IMAGE img; 749 | // 读取图片至绘图窗口 750 | if (n1 == 0 && n2 == 0) 751 | loadimage(&img, "blackWin.jpg",306,141); 752 | if (n1 == 0 && n2 == 1) 753 | loadimage(&img, "whiteWin.jpg", 306, 141); 754 | if (n1 == 1 && n2 == 0) 755 | loadimage(&img, "youWin.jpg", 306, 141); 756 | if (n1 == 1 && n2 == 1) 757 | loadimage(&img, "computerWin.jpg", 306, 141); 758 | putimage(100, 200, &img); 759 | 760 | MOUSEMSG m;//鼠标操作 761 | while (1) 762 | { 763 | m = GetMouseMsg(); 764 | if (m.uMsg == WM_LBUTTONDOWN && m.x >= 215 && m.x <= 270 && m.y >= 285 && m.y <= 320) 765 | { 766 | setlinecolor(YELLOW); 767 | //空心矩形框 768 | rectangle(215, 285, 270, 320); 769 | Sleep(300); 770 | Menu().Display(); 771 | break; 772 | } 773 | else if (m.uMsg == WM_LBUTTONDOWN) 774 | exit(0); 775 | } 776 | } 777 | 778 | void Play::TwoPlayerGame(MOUSEMSG m) 779 | { 780 | int win = 0; 781 | int play1 = 1, play2 = 0; 782 | MOUSEMSG ms; 783 | 一直获取鼠标信息,判断操做 784 | while (win == 0) 785 | { 786 | //判断是否点击右侧工具栏或者棋盘 787 | ms = GetMouseMsg(); 788 | if (ms.uMsg == WM_LBUTTONDOWN) 789 | { 790 | //判断是否点击右侧工具栏 791 | buttonRingth(m,ms,win); 792 | //判断是否点击棋盘 793 | for (int lie = 20; lie <= 490; lie += 30) 794 | { 795 | if (ms.x <= lie + 15 && ms.x >= lie - 15) 796 | { 797 | for (int hang = 20; hang <= 490; hang += 30) 798 | { 799 | if (ms.y <= hang + 15 && ms.y >= hang - 15) 800 | { 801 | if (play1 == 1 && a[hang / 30 - 1][lie / 30 - 1] == 0) 802 | { 803 | setfillcolor(BLACK); 804 | solidcircle(lie, hang, 12); 805 | a[hang / 30 - 1][lie / 30 - 1] = 1; 806 | play1 = 0; 807 | break; 808 | } 809 | if (play1 == 0 && a[hang / 30 - 1][lie / 30 - 1] == 0) 810 | { 811 | setfillcolor(WHITE); 812 | solidcircle(lie, hang, 12); 813 | a[hang / 30 - 1][lie / 30 - 1] = 2; 814 | play1 = 1; 815 | break; 816 | } 817 | } 818 | } 819 | } 820 | } 821 | //判断玩家是否赢 822 | win = Play().Win(); 823 | if (win == 1) 824 | { 825 | //黑棋赢 826 | displayWin(0,0); 827 | break; 828 | } 829 | else if (win == 2) 830 | { 831 | //白棋赢 832 | displayWin(0,1); 833 | break; 834 | } 835 | } 836 | } 837 | } 838 | 839 | void Play::ComputerUserGame(MOUSEMSG m) 840 | { 841 | int win = 0; 842 | int play1 = 1, play2 = 0;//play1表示玩家,play2表示电脑,每次玩家先落子 843 | 844 | MOUSEMSG ms; 845 | 一直获取鼠标信息,判断操做 846 | while (win == 0) 847 | { 848 | //判断是否点击右侧工具栏或者棋盘 849 | ms = GetMouseMsg(); 850 | if (ms.uMsg == WM_LBUTTONDOWN) 851 | { 852 | //判断是否点击右侧工具栏 853 | buttonRingth(m, ms, win); 854 | //判断是否点击棋盘并且判断是否该玩家落子 855 | PlayGame(ms,&play1,&play2); 856 | //判断玩家是否赢 857 | win = Play().Win(); 858 | if (win == 1) 859 | { 860 | //人赢 861 | displayWin(1, 0); 862 | break; 863 | } 864 | else if (win == 2) 865 | { 866 | //电脑赢 867 | displayWin(1, 1); 868 | break; 869 | } 870 | } 871 | } 872 | } 873 | 874 | 875 | 876 | int Play::Win() 877 | { 878 | int win = 0; 879 | //判断是否赢 880 | for (int j = 0; j<16 && (win == 0); j++) 881 | { 882 | for (int i = 0; i<16; i++) 883 | { 884 | 885 | if ((a[j][i] == 1 && a[j][i + 1] == 1 && a[j][i + 2] == 1 && a[j][i + 3] == 1 && a[j][i + 4] == 1) 886 | || (a[i][j] == 1 && a[i + 1][j] == 1 && a[i + 2][j] == 1 && a[i + 3][j] == 1 && a[i + 4][j] == 1))//横纵是5个子play1 win 887 | { 888 | win = 1; 889 | Sleep(100); 890 | break; 891 | } 892 | if ((a[j][i] == 2 && a[j][i + 1] == 2 && a[j][i + 2] == 2 && a[j][i + 3] == 2 && a[j][i + 4] == 2) 893 | || (a[i][j] == 2 && a[i + 1][j] == 2 && a[i + 2][j] == 2 && a[i + 3][j] == 2 && a[i + 4][j] == 2))//横纵是5个子play2 win 894 | { 895 | win = 2; 896 | Sleep(100); 897 | break; 898 | } 899 | } 900 | } 901 | for (int j = 0; j<12 && (win == 0); j++) 902 | { 903 | for (int i = 0; i<12; i++) 904 | { 905 | if (a[j][i] == 1 && a[j + 1][i + 1] == 1 && a[j + 2][i + 2] == 1 && a[j + 3][i + 3] == 1 && a[j + 4][i + 4] == 1)//向右倾斜时候play1 win 906 | { 907 | win = 1; 908 | Sleep(100); 909 | break; 910 | 911 | } 912 | if (a[j][i] == 2 && a[j + 1][i + 1] == 2 && a[j + 2][i + 2] == 2 && a[j + 3][i + 3] == 2 && a[j + 4][i + 4] == 2)//向右倾斜时候play2 win 913 | { 914 | win = 2; 915 | Sleep(100); 916 | break; 917 | } 918 | } 919 | for (int i = 4; i<16 && (win == 0); i++) 920 | { 921 | if (a[j][i] == 1 && a[j + 1][i - 1] == 1 && a[j + 2][i - 2] == 1 && a[j + 3][i - 3] == 1 && a[j + 4][i - 4] == 1)//向左倾斜时候play1 win 922 | { 923 | win = 1; 924 | Sleep(100); 925 | break; 926 | } 927 | if (a[j][i] == 2 && a[j + 1][i - 1] == 2 && a[j + 2][i - 2] == 2 && a[j + 3][i - 3] == 2 && a[j + 4][i - 4] == 2)//向左倾斜时候play2 win 928 | { 929 | win = 2; 930 | Sleep(100); 931 | break; 932 | } 933 | } 934 | } 935 | return win; 936 | } 937 | -------------------------------------------------------------------------------- /a.out: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MouCoder/cpp_Code/6f6868685562996c866f5aa8f82ef914eada3b0e/a.out -------------------------------------------------------------------------------- /list: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | namespace MyList 8 | { 9 | template 10 | //模板的使用_list_node 11 | struct __list_node 12 | { 13 | __list_node* prev;//指向后一个节点的指针 14 | __list_node* next;//指向前一个节点的指针 15 | T data;//数据域 16 | 17 | //node的默认构造函数,对成员变量进行初始化。T()表示调用默认构造函数,即x会调用默认构造函数 18 | __list_node(const T& x = T()) 19 | :prev(nullptr) 20 | , next(nullptr) 21 | , data(x) 22 | {} 23 | }; 24 | 25 | //list迭代器的实现 26 | //Ref->T& ptr->T* 27 | template 28 | struct __list_iterator 29 | { 30 | typedef __list_node node; 31 | typedef __list_iterator self; 32 | node* _node; 33 | 34 | //迭代器的作用不是创建节点而是指向原有节点,因此使用指针即可 35 | __list_iterator(node* node) 36 | :_node(node) 37 | {} 38 | //list迭代器中不用实现拷贝构造、赋值运算符重载、析构,因为迭代器的本质并不是创建节点,使用默认的进行值拷贝即可。 39 | bool operator!=(const self& s) const //不需要进行修改,设计成const无论是const和非const都可以调用 40 | { 41 | return _node != s._node; 42 | } 43 | bool operator==(const self& s) const 44 | { 45 | return _node == s._node; 46 | } 47 | //重载-> 48 | Ptr operator->() const 49 | { 50 | return &_node->data; 51 | } 52 | Ref operator*() const 53 | { 54 | return _node->data; 55 | } 56 | //前置++ 57 | self operator++() 58 | { 59 | _node = _node->next;//直接返回++后的结果 60 | return *this; 61 | } 62 | //后置++ 63 | self operator++(int) //参数只是为了和前置构成重载,并没有实际意义,因此只给类型就可以了 64 | { 65 | self tmp = *this; 66 | _node = _node->next; 67 | return tmp; 68 | } 69 | //前置-- 70 | self operator--() 71 | { 72 | _node = _node->prev; 73 | return *this; 74 | } 75 | //后置-- 76 | self operator--(int) 77 | { 78 | self tmp = *this; 79 | _node = _node->prev; 80 | return tmp; 81 | } 82 | }; 83 | 84 | template 85 | class list 86 | { 87 | typedef __list_node node; 88 | public: 89 | typedef __list_iterator iterator; 90 | typedef __list_iterator const_iterator; 91 | //迭代器 92 | iterator begin() 93 | { 94 | return iterator(head->next);//调用iterator的构造函数,将node*转换成iterator类型 95 | } 96 | iterator end() 97 | { 98 | return iterator(head); 99 | } 100 | const_iterator begin() const 101 | { 102 | return head->next; 103 | } 104 | const_iterator end() const 105 | { 106 | return head; 107 | } 108 | /*构造函数*/ 109 | //默认构造 110 | list() 111 | { 112 | head = new node; 113 | //下一个节点指针和前一个节点指针都指向自身的空链表 114 | head->next = head; 115 | head->prev = head; 116 | } 117 | template 118 | list(InputIterator first, InputIterator last) 119 | { 120 | head = new node; 121 | head->next =head; 122 | head->prev = head; 123 | 124 | //调用push_back插入first到last的节点 125 | while (first != last) 126 | { 127 | push_back(*first); 128 | ++first; 129 | } 130 | } 131 | list(const list& lt) 132 | { 133 | head = new node; 134 | head->next = head; 135 | head->prev = head; 136 | 137 | list tmp(lt.begin(), lt.end()); 138 | std::swap(head, tmp.head); 139 | } 140 | //lt1 = lt2 141 | list& operator=(list lt) 142 | { 143 | //传值会进行临时拷贝,lt就是一个新的list,将lt和this->head交换,函数结束释放空间就将this->head释放而新的this->head=lt.head 144 | std::swap(head, lt.head); 145 | return *this; 146 | } 147 | //析构函数 148 | ~list() 149 | { 150 | clear(); 151 | delete head; 152 | head = nullptr; 153 | } 154 | /*插入*/ 155 | //尾插 156 | void push_back(const T& x) 157 | { 158 | insert(end(),x); 159 | //node* newnode = new node(x); 160 | ////插入节点 161 | //node* tail = head->prev; 162 | //tail->next = newnode; 163 | //newnode->next = head; 164 | //newnode->prev = tail; 165 | //head->prev = newnode; 166 | } 167 | void push_front(const T& x) 168 | { 169 | insert(begin(),x); 170 | } 171 | iterator insert(iterator pos,const T& x) 172 | { 173 | node* newnode = new node(x); 174 | node* cur = pos._node; 175 | node* prev = cur->prev; 176 | newnode->next = cur; 177 | newnode->prev = prev; 178 | prev->next = newnode; 179 | cur->prev = newnode; 180 | 181 | return iterator(newnode); 182 | } 183 | /*删除*/ 184 | void clear() 185 | { 186 | iterator it = begin(); 187 | while (it != end()) 188 | { 189 | erase(it++); 190 | } 191 | } 192 | iterator erase(iterator pos) 193 | { 194 | assert(pos != end()); 195 | 196 | node* cur = pos._node; 197 | node* prev = cur->prev; 198 | node* next = cur->next; 199 | 200 | next->prev = prev; 201 | prev->next = next; 202 | delete cur; 203 | return iterator(next); 204 | } 205 | void pop_back() 206 | { 207 | assert(head->prev != head); 208 | erase(--end()); 209 | } 210 | void pop_fornt() 211 | { 212 | assert(head->prev != head); 213 | erase(begin()); 214 | } 215 | 216 | private: 217 | //双向带头循环链表 218 | node* head; 219 | }; 220 | } 221 | -------------------------------------------------------------------------------- /list_iterator: -------------------------------------------------------------------------------- 1 | //list迭代器的实现 2 | //Ref->T& ptr->T* 3 | template 4 | struct __list_iterator 5 | { 6 | typedef __list_node node; 7 | typedef __list_iterator self; 8 | node* _node; 9 | 10 | //迭代器的作用不是创建节点而是指向原有节点,因此使用指针即可 11 | __list_iterator(node* node) 12 | :_node(node) 13 | {} 14 | //list迭代器中不用实现拷贝构造、赋值运算符重载、析构,因为迭代器的本质并不是创建节点,使用默认的进行值拷贝即可。 15 | bool operator!=(const self& s) const //不需要进行修改,设计成const无论是const和非const都可以调用 16 | { 17 | return _node != s._node; 18 | } 19 | bool operator==(const self& s) const 20 | { 21 | return _node == s._node; 22 | } 23 | //重载-> 24 | Ptr operator->() const 25 | { 26 | return &_node->data; 27 | } 28 | Ref operator*() const 29 | { 30 | return _node->data; 31 | } 32 | //前置++ 33 | self operator++() 34 | { 35 | _node = _node->next;//直接返回++后的结果 36 | return *this; 37 | } 38 | //后置++ 39 | self operator++(int) //参数只是为了和前置构成重载,并没有实际意义,因此只给类型就可以了 40 | { 41 | self tmp = *this; 42 | _node = _node->next; 43 | return tmp; 44 | } 45 | //前置-- 46 | self operator--() 47 | { 48 | _node = _node->next; 49 | return *this; 50 | } 51 | //后置-- 52 | self operator--(int) 53 | { 54 | self tmp = *this; 55 | _node = _node->next; 56 | return tmp; 57 | } 58 | }; 59 | -------------------------------------------------------------------------------- /lock&thread: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | using namespace std; 6 | int main() 7 | { 8 | //两个线程轮流打印,顺序打印1-100 9 | int a = 1; 10 | int b = 2; 11 | bool flag = true; 12 | //一个互斥锁 13 | mutex mtx; 14 | //一个条件变量 15 | condition_variable cd; 16 | //创建两个线程A和B 17 | thread t1([&]{ 18 | while(a <= 100) 19 | { 20 | unique_lock lck(mtx); 21 | cd.wait(lck, [flag]{return flag; }); 22 | cout << a << " "; 23 | a += 2; 24 | flag = false; 25 | cd.notify_one(); 26 | } 27 | }); 28 | 29 | thread t2([&]{ 30 | while (b <= 100) 31 | { 32 | unique_lock lck(mtx); 33 | cd.wait(lck, [flag]{return !flag; }); 34 | cout << b << " "; 35 | b += 2; 36 | flag = true; 37 | cd.notify_one(); 38 | } 39 | }); 40 | 41 | t1.join(); 42 | t2.join(); 43 | 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include"ModuleTest.h" 4 | 5 | //int main() 6 | //{ 7 | // //testAlloc(); 8 | // /*func1(); 9 | // func2(); 10 | // TestSizeClass(); 11 | // TestConcurrentAlloc(); 12 | // TestBigMemory(); 13 | // TestThreads();*/ 14 | // 15 | // //TestMallocFree(); 16 | // 17 | // testA(); 18 | // return 0; 19 | //} -------------------------------------------------------------------------------- /map/map_set: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | //void print(set::iterator begin,set::iterator end) 10 | //{ 11 | // while (begin != end) 12 | // { 13 | // std::cout << *begin << " "; 14 | // begin++; 15 | // } 16 | // 17 | // std::cout << std::endl; 18 | //} 19 | // 20 | //int main() 21 | //{ 22 | // set s1;//使用空构造构造一个空的set 23 | // 24 | // //向s1中插入元素,使s1不在为空 25 | // s1.insert(5); 26 | // s1.insert(8); 27 | // s1.insert(6); 28 | // s1.insert(3); 29 | // s1.insert(9); 30 | // 31 | // print(s1.begin(), s1.end()); 32 | // 33 | // //使用拷贝构造构造一个和s1具有相同元素的set s2 34 | // set s2(s1); 35 | // print(s2.begin(),s2.end()); 36 | // 37 | // //使用迭代器区间构造构造一个和s1相同的set s3 38 | // set s3(s1.begin(),s1.end()); 39 | // print(s3.begin(), s3.end()); 40 | // 41 | // 42 | // //使用数组、vector迭代器区间构造set s4、s5 43 | // int array[5] = {1,2,3,4,5}; 44 | // vector v(array,array+5);//使用数组构造vector 45 | // 46 | // set s4(array,array+5); 47 | // print(s4.begin(), s4.end()); 48 | // 49 | // set s5(v.begin(),v.end()); 50 | // print(s5.begin(), s5.end()); 51 | // 52 | // 53 | // //使用list迭代器构造set 54 | // list lt(array,array+5); 55 | // set s6(lt.begin(),lt.end()); 56 | // print(s6.begin(), s6.end()); 57 | // 58 | // 59 | // //使用string迭代器构造 60 | // string str = "abcd"; 61 | // 62 | // set s7(str.begin(),str.end()); 63 | // auto it = s7.begin(); 64 | // while (it != s7.end()) 65 | // { 66 | // std::cout << *it << " "; 67 | // it++; 68 | // } 69 | // std::cout << std::endl; 70 | // return 0; 71 | //} 72 | 73 | 74 | //int main() 75 | //{ 76 | // set s1; 77 | // s1.insert(5); 78 | // s1.insert(8); 79 | // s1.insert(6); 80 | // s1.insert(3); 81 | // s1.insert(9); 82 | // 83 | // //正向迭代器遍历 84 | // set::iterator it = s1.begin(); 85 | // while (it != s1.end()) 86 | // { 87 | // cout << *it << " "; 88 | // it++; 89 | // } 90 | // cout << endl; 91 | // //反向迭代器遍历 92 | // set::reverse_iterator rit = s1.rbegin(); 93 | // while (rit != s1.rend()) 94 | // { 95 | // cout << *rit << " "; 96 | // rit++; 97 | // } 98 | // cout << endl; 99 | // return 0; 100 | //} 101 | 102 | //int main() 103 | //{ 104 | // set s1; 105 | // s1.insert(5); 106 | // s1.insert(8); 107 | // s1.insert(6); 108 | // s1.insert(3); 109 | // s1.insert(9); 110 | // 111 | // cout << s1.size() << " " << s1.max_size() << endl; 112 | // 113 | // string str = "abcde"; 114 | // set s2(str.begin(),str.end()); 115 | // 116 | // cout << s2.size() << " " << s2.max_size() << endl; 117 | // return 0; 118 | //} 119 | 120 | //void print(set::iterator begin, set::iterator end) 121 | //{ 122 | // while (begin != end) 123 | // { 124 | // std::cout << *begin << " "; 125 | // begin++; 126 | // } 127 | // 128 | // std::cout << std::endl; 129 | //} 130 | // 131 | //int main() 132 | //{ 133 | // set s1; 134 | // s1.insert(5); 135 | // s1.insert(8); 136 | // s1.insert(6); 137 | // s1.insert(3); 138 | // s1.insert(9); 139 | // 140 | // print(s1.begin(),s1.end()); 141 | // //向s1中插入一个值 142 | // s1.insert(15);//set中没有和要插入的值相同的值 143 | // print(s1.begin(), s1.end()); 144 | // 145 | // s1.insert(3);//要插入的值set中已经存在 146 | // print(s1.begin(), s1.end()); 147 | // 148 | // 149 | // //删除 150 | // s1.erase(15); 151 | // print(s1.begin(), s1.end()); 152 | // 153 | // 154 | // //swap---交换两个set 155 | // set s2; 156 | // s2.insert(50); 157 | // s2.insert(80); 158 | // s2.insert(60); 159 | // s2.insert(30); 160 | // s2.insert(90); 161 | // 162 | // s1.swap(s2); 163 | // print(s1.begin(), s1.end()); 164 | // print(s2.begin(), s2.end()); 165 | // 166 | // //查找 167 | // auto it = s1.find(30); 168 | // cout << *it << endl; 169 | // s1.erase(it); 170 | // print(s1.begin(), s1.end()); 171 | // 172 | // //count 173 | // cout << s1.count(50) << endl; 174 | // 175 | // return 0; 176 | //} 177 | 178 | int main() 179 | { 180 | map m1;//构造一个空的map 181 | /* 182 | operator[]的原理是: 183 | 用构造一个键值对,然后调用insert()函数将该键值对插入到map中 184 | 如果key已经存在,插入失败,insert函数返回该key所在位置的迭代器 185 | 如果key不存在,插入成功,insert函数返回新插入元素所在位置的迭代器 186 | operator[]函数最后将insert返回值键值对中的value返回*/ 187 | 188 | m1['a'] = 65; 189 | m1.insert(pair('a', 65)); 190 | m1.insert(pair('b', 66)); 191 | m1.insert(pair('c', 67)); 192 | m1.insert(pair('d', 68)); 193 | m1.insert(pair('e', 69)); 194 | m1.insert(pair('f', 70)); 195 | 196 | auto it = m1.find('a');//key值查找 197 | 198 | //删除 199 | m1.erase('b');//key值删除 200 | m1.erase(it);//迭代器删除 201 | m1.erase(m1.begin(),m1.end());//迭代器区间删除 202 | 203 | //清空 204 | m1.clear(); 205 | 206 | //拷贝构造 207 | map m2(m1); 208 | m1.swap(m2); 209 | 210 | 211 | return 0; 212 | } 213 | -------------------------------------------------------------------------------- /mystring: -------------------------------------------------------------------------------- 1 | //.h 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | 7 | namespace myString 8 | { 9 | class string 10 | { 11 | public: 12 | //iterator 13 | typedef char* iterator; 14 | iterator begin(); 15 | iterator end(); 16 | //默认构造 17 | string(const char* str = ""); 18 | //拷贝构造 19 | string(const string& s); 20 | void swap(string& s1); 21 | //赋值运算符重载 22 | //string& operator=(const string& s); 23 | string& operator=(myString::string s); 24 | //析构函数 25 | ~string(); 26 | 27 | //[]重载 28 | char& operator[](size_t pos); 29 | // 30 | void reserve(size_t n); 31 | void resize(size_t n,char ch = '\0'); 32 | size_t size(); 33 | size_t capacity(); 34 | //插入 35 | void push_back(const char ch); 36 | void insert(size_t pos,const char ch); 37 | void insert(size_t pos,const char* str); 38 | void append(const char* str); 39 | void operator+=(const char ch); 40 | void operator+=(const char* str); 41 | //查找 42 | size_t find(char ch, size_t pos = 0); 43 | size_t find(char* str, size_t pos = 0); 44 | //转换成c字符串 45 | const char* c_str() const; 46 | private: 47 | char* _str; 48 | size_t _size; 49 | size_t _capacity; 50 | public: 51 | const static size_t npos; 52 | }; 53 | ostream& operator<<(ostream& _cout,myString::string s); 54 | istream& operator>>(istream& _cin, myString::string s); 55 | bool operator>(myString::string& s1, myString::string& s2); 56 | bool operator==(myString::string& s1, myString::string& s2); 57 | bool operator>=(myString::string& s1, myString::string& s2); 58 | bool operator<=(myString::string& s1, myString::string& s2); 59 | bool operator!=(myString::string& s1, myString::string& s2); 60 | }; 61 | //string.cpp 62 | #include"string.h" 63 | 64 | const size_t myString::string::npos = -1; 65 | 66 | //默认构造函数 67 | myString::string::string(const char* str) 68 | { 69 | //不能使用nullptr床架对象 70 | assert(str != nullptr); 71 | _str = new char[strlen(str) + 1]; 72 | _size = _capacity = strlen(str); 73 | strcpy(_str,str); 74 | } 75 | //拷贝构造函数-现代写法 76 | //myString::string::string(const string& s) 77 | //:_str(nullptr) 78 | //, _size(0) 79 | //, _capacity(0) 80 | //{ 81 | // string tmp(s._str); 82 | // swap(tmp); 83 | //} 84 | 85 | //拷贝构造-传统写法 86 | myString::string::string(const string& s) 87 | { 88 | _str = new char[strlen(s._str) + 1]; 89 | strcpy(_str,s._str); 90 | _size = _capacity = strlen(s._str); 91 | } 92 | 93 | //析构函数 94 | myString::string::~string() 95 | { 96 | delete[] _str; 97 | _size = _capacity = 0; 98 | _str = nullptr; 99 | } 100 | 101 | //赋值运算符重载-传统写法 102 | //myString::string& myString::string::operator=(const string& s) 103 | //{ 104 | // if (this != &s) 105 | // { 106 | // //开辟新空间 107 | // char* tmp = new char[strlen(s._str) + 1]; 108 | // strcpy(tmp, s._str); 109 | // _size = _capacity = s._size; 110 | // //释放原空间 111 | // delete[] _str; 112 | // _str = tmp; 113 | // } 114 | // return *this; 115 | //} 116 | 117 | //赋值运算符重载-现代写法 118 | myString::string& myString::string::operator=(myString::string s) 119 | { 120 | swap(s); 121 | return *this; 122 | } 123 | //[]重载 124 | char& myString::string::operator[](size_t pos) 125 | { 126 | assert(pos < _size); 127 | return _str[pos]; 128 | } 129 | //交换两个字符串对象 130 | void myString::string::swap(string& s1) 131 | { 132 | std::swap(_str, s1._str); 133 | std::swap(_size,s1._size); 134 | std::swap(_capacity,s1._capacity); 135 | } 136 | 137 | void myString::string::reserve(size_t n) 138 | { 139 | if (n > _capacity) 140 | { 141 | char* tmp = new char[n+1]; 142 | strcpy(tmp,_str); 143 | delete[] _str; 144 | _str = tmp; 145 | _capacity = n; 146 | } 147 | } 148 | 149 | void myString::string::resize(size_t n, char ch) 150 | { 151 | if (n < _size) 152 | { 153 | _str[_size] = '\0'; 154 | _size = n; 155 | } 156 | else 157 | { 158 | if (n > _capacity) 159 | { 160 | reserve(n); 161 | } 162 | //后边补ch 163 | for (size_t i = _size; i < n; i++) 164 | _str[i] = ch; 165 | //加'\0' 166 | _str[n] = '\0'; 167 | _size = n; 168 | } 169 | } 170 | 171 | size_t myString::string::size() 172 | { 173 | return _size; 174 | } 175 | size_t myString::string::capacity() 176 | { 177 | return _capacity; 178 | } 179 | 180 | myString::string::iterator myString::string::begin() 181 | { 182 | return _str; 183 | } 184 | myString::string::iterator myString::string::end() 185 | { 186 | return _str + _size; 187 | } 188 | 189 | void myString::string::insert(size_t pos,const char ch) 190 | { 191 | //检查插入位置是否正确 192 | assert(pos <= _size); 193 | //判断是否需要扩容 194 | if (_capacity == 0) 195 | reserve(10); 196 | else if (_capacity == _size) 197 | reserve(2*_capacity); 198 | //将size及其之后的字符后移 199 | for (size_t i = _size; i >= pos; i--) 200 | { 201 | _str[i+1] = _str[i]; 202 | } 203 | //pos位置插入字符 204 | _str[pos] = ch; 205 | _size++; 206 | } 207 | 208 | void myString::string::insert(size_t pos, const char* str) 209 | { 210 | int len = strlen(str); 211 | //检查插入位置是否正确 212 | assert(pos <= _size); 213 | //判断是否需要扩容 214 | if (_capacity == 0) 215 | reserve(len); 216 | else if (_capacity == _size) 217 | reserve(_size+len); 218 | //移动size之后的字符 219 | for (size_t i = _size; i >= pos; i--) 220 | { 221 | _str[i+len] = _str[i]; 222 | } 223 | //插入字符串 224 | strncpy(_str+pos,str,len); 225 | _size += len; 226 | } 227 | 228 | void myString::string::push_back(const char ch) 229 | { 230 | insert(_size,ch); 231 | } 232 | 233 | void myString::string::append(const char* str) 234 | { 235 | insert(_size,str); 236 | } 237 | 238 | void myString::string::operator+=(const char ch) 239 | { 240 | push_back(ch); 241 | } 242 | void myString::string::operator+=(const char* str) 243 | { 244 | append(str); 245 | } 246 | 247 | size_t myString::string::find(char ch, size_t pos) 248 | { 249 | assert(pos < _size); 250 | for (size_t i = 0; i < _size; i++) 251 | { 252 | if (_str[i] == ch) 253 | return i; 254 | } 255 | return npos; 256 | } 257 | size_t myString::string::find(char* str, size_t pos) 258 | { 259 | const char* ret = strstr(_str + pos, str); 260 | if (ret == nullptr) 261 | { 262 | return npos; 263 | } 264 | else 265 | { 266 | return ret - _str; 267 | } 268 | } 269 | 270 | const char* myString::string::c_str() const 271 | { 272 | return _str; 273 | } 274 | 275 | ostream& myString::operator<<(ostream& _cout,myString::string s) 276 | { 277 | for (size_t i = 0; i < s.size(); i++) 278 | { 279 | _cout << s[i]; 280 | } 281 | _cout << endl; 282 | return _cout; 283 | } 284 | istream& myString::operator>>(istream& _cin, myString::string s) 285 | { 286 | s.resize(0); 287 | char ch; 288 | while (1) 289 | { 290 | //in>>ch; 291 | _cin.get(ch); 292 | if (ch == ' ' || ch == '\n') 293 | { 294 | break; 295 | } 296 | else 297 | { 298 | s += ch; 299 | } 300 | } 301 | 302 | return _cin; 303 | } 304 | 305 | bool myString::operator>(myString::string& s1, myString::string& s2) 306 | { 307 | size_t i1 = 0, i2 = 0; 308 | while (i1 < s1.size() && i2 < s2.size()) 309 | { 310 | if (s1[i1] > s2[i2]) 311 | { 312 | return true; 313 | } 314 | else if (s1[i1] < s2[i2]) 315 | { 316 | return false; 317 | } 318 | else 319 | { 320 | ++i1; 321 | ++i2; 322 | } 323 | } 324 | 325 | if (i1 < s1.size()) 326 | { 327 | return true; 328 | } 329 | else if (i2 < s2.size()) 330 | { 331 | return false; 332 | } 333 | else 334 | { 335 | return false; 336 | } 337 | } 338 | 339 | bool myString::operator==(myString::string& s1, myString::string& s2) 340 | { 341 | size_t i1 = 0, i2 = 0; 342 | while (i1 < s1.size() && i2 < s2.size()) 343 | { 344 | if (s1[i1] > s2[i2]) 345 | { 346 | return false; 347 | } 348 | else if (s1[i1] < s2[i2]) 349 | { 350 | return false; 351 | } 352 | else 353 | { 354 | ++i1; 355 | ++i2; 356 | } 357 | } 358 | 359 | if (i1 == s1.size() && i2 == s2.size()) 360 | { 361 | return true; 362 | } 363 | else 364 | { 365 | return false; 366 | } 367 | } 368 | 369 | bool myString::operator>=(myString::string& s1, myString::string& s2) 370 | { 371 | if (s1 > s2 || s1 == s2) 372 | return true; 373 | return false; 374 | } 375 | 376 | bool myString::operator<=(myString::string& s1, myString::string& s2) 377 | { 378 | if (s1 > s2) 379 | return false; 380 | return true; 381 | } 382 | 383 | bool myString::operator!=(myString::string& s1, myString::string& s2) 384 | { 385 | if (s1 == s2) 386 | return false; 387 | return true; 388 | } 389 | 390 | //test.cpp 391 | #include"string.h" 392 | 393 | int main() 394 | { 395 | //测试默认构造函数 396 | myString::string s1; 397 | //myString::string s2 = NULL; 398 | myString::string s3 = "hello world"; 399 | 400 | //测试拷贝构造 401 | myString::string s4(s3); 402 | 403 | //赋值运算符重载 404 | myString::string s5("hello"); 405 | s5 = s4; 406 | //[]重载 407 | cout << s5[6] << endl; 408 | //reserve和resize 409 | //reserve在插入的时候会调用 410 | myString::string s6; 411 | s6.resize(5,'x'); 412 | //size和capacity 413 | cout << s6.size() << " " << s6.capacity() << endl;//均为5 414 | 415 | //iterator 416 | myString::string::iterator it = s6.begin(); 417 | while (it < s6.end()) 418 | { 419 | cout << *it << " "; 420 | it++; 421 | } 422 | cout << endl; 423 | 424 | //插入 425 | myString::string s7("helloworld"); 426 | s7.insert(5,' '); 427 | s7.push_back('!'); 428 | myString::string s8("12345678"); 429 | s8.insert(2,"hello"); 430 | s8.append("world!"); 431 | //输出 432 | cout << s8; 433 | 434 | cout << (s7 == s8) << endl; 435 | 436 | myString::string s10 = "hello"; 437 | myString::string s11 = "aellobbb"; 438 | cout << (s10 > s11) << endl; 439 | return 0; 440 | } 441 | -------------------------------------------------------------------------------- /priority_queue: -------------------------------------------------------------------------------- 1 | namespace myPriorityQueue 2 | { 3 | //仿函数 4 | template 5 | struct less 6 | { 7 | bool operator()(const T& left, const T& right) 8 | { 9 | return left < right; 10 | } 11 | }; 12 | 13 | template 14 | struct greater 15 | { 16 | bool operator()(const T& left, const T& right) 17 | { 18 | return left > right; 19 | } 20 | }; 21 | template,class compare = greater> 22 | class priority_queue 23 | { 24 | public: 25 | //默认构造函数---看似每写任何东西,实际上对于自定义类型构造函数回去调用自定义类型的默认构造函数 26 | priority_queue(){} 27 | template 28 | priority_queue(Iterator first, Iterator last) 29 | : _con(first, last) 30 | { 31 | int root; 32 | // 将_con中的元素调整成堆的结构 33 | //方法1---从上向下使用向上调整算法 34 | for (root = 0; root < _con.size(); root++) 35 | AdjustUP(root); 36 | //方法2---从下向上使用向下调整算法 37 | /*for (root = (_con.size() - 2) / 2; root >= 0; root--) 38 | AdjustDown(root);*/ 39 | } 40 | //插入元素 41 | void push(const T& data) 42 | { 43 | //优先级队列类似与堆,插入数据时需要使用向上调整算法对调整成堆 44 | _con.push_back(data); 45 | AdjustUP(_con.size() - 1); 46 | } 47 | //删除元素 48 | void pop() 49 | { 50 | //堆删除元素时,将第一个和最后一个元素交换,删除最后一个元素,在堆数组使用向下调整算法调整成堆 51 | if (empty()) 52 | return; 53 | swap(_con.front(), _con.back()); 54 | _con.pop_back(); 55 | AdjustDown(0); 56 | } 57 | //元素个数 58 | size_t size()const 59 | { 60 | return _con.size(); 61 | } 62 | //判空 63 | bool empty()const 64 | { 65 | return _con.empty(); 66 | } 67 | // 堆顶元素不允许修改,因为:堆顶元素修改可以会破坏堆的特性 68 | const T& top()const 69 | { 70 | return _con.front(); 71 | } 72 | void test() 73 | { 74 | for (auto e : _con) 75 | cout << e << " "; 76 | cout << endl; 77 | } 78 | private: 79 | //向下调整算法 80 | void AdjustDown(int root) 81 | { 82 | int child = root * 2 + 1; 83 | while (child < _con.size()) 84 | { 85 | // 找以parent为根的较大的孩子 86 | if (child + 1 < _con.size() && compare()(_con[child+1],_con[child])) 87 | child += 1; 88 | // 检测双亲是否满足情况 89 | if (compare()(_con[child], _con[root])) 90 | { 91 | swap(_con[child], _con[root]); 92 | root = child; 93 | child = root * 2 + 1; 94 | } 95 | else 96 | break; 97 | } 98 | } 99 | //向上调整算法 100 | void AdjustUP(int child) 101 | { 102 | //父子节点比较,如果子节点大于父节点则交换 103 | int parent = (child - 1) / 2; 104 | while (child > 0) 105 | { 106 | if (compare()(_con[child], _con[parent])) 107 | { 108 | swap(_con[child], _con[parent]); 109 | //向下继续迭代 110 | child = parent; 111 | parent = (child - 1) / 2; 112 | } 113 | else 114 | break; 115 | } 116 | } 117 | private: 118 | container _con; 119 | }; 120 | } 121 | -------------------------------------------------------------------------------- /simpleMemoryPool: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | template 7 | class MemPool 8 | { 9 | private: 10 | //内存块结构 11 | typedef struct BlockNode 12 | { 13 | void* _memory;//内存块地址 14 | BlockNode* _next;//下一个blockNode 15 | size_t _objNum;//内存块对象的个数 16 | //构造函数---num表示申请对象的个数 17 | BlockNode(size_t num) 18 | :_objNum(num), 19 | _next(nullptr) 20 | { 21 | _memory = malloc(_objNum*_size); 22 | } 23 | 24 | ~BlockNode() 25 | { 26 | free(_memory); 27 | _memory = nullptr; 28 | _next = nullptr; 29 | _objNum = 0; 30 | } 31 | }BlockNode; 32 | protected: 33 | static size_t _size;//单个对象的大小 34 | T* _releaseMemory = nullptr;//释放的内存 35 | BlockNode* _requestMemory;//申请的内存块 36 | size_t _maxNum;//内存块最大的大小 37 | size_t _useCount;//当前内存块已经使用的对象个数 38 | protected: 39 | //设置单个对象的大小 40 | static size_t setSize() 41 | { 42 | return (sizeof(T) >= sizeof(T*) ? sizeof(T):sizeof(T*)); 43 | } 44 | public: 45 | MemPool() 46 | :_useCount(0), 47 | _releaseMemory(nullptr), 48 | _maxNum(100000*_size) 49 | { 50 | //开始先申请32个_size大小的空间 51 | _requestMemory = new BlockNode(32); 52 | } 53 | 54 | ~MemPool() 55 | { 56 | BlockNode *cur = _requestMemory; 57 | while (cur) 58 | { 59 | BlockNode* del = cur; 60 | cur = cur->_next; 61 | delete del; //会自动调用~BlockNode() 62 | } 63 | } 64 | 65 | T* New() 66 | { 67 | //先在releaseMemory中找 68 | if (_releaseMemory) 69 | { 70 | T* obj = _releaseMemory; 71 | _releaseMemory = *((T**)_releaseMemory);//releaseMemory的前几个字节存储的是下一个节点的地址 72 | return obj; 73 | } 74 | else 75 | { 76 | //判断requesetMemory中是否还有空闲内存 77 | if (_requestMemory->_objNum == _useCount) 78 | { 79 | //取物理内存中申请一块内存 80 | size_t size = 2 * _useCount >= _maxNum ? _maxNum : 2 * _useCount; 81 | BlockNode* newBlock = new BlockNode(size); 82 | 83 | newBlock->_next = _requestMemory; 84 | _requestMemory = newBlock; 85 | _useCount = 0; 86 | } 87 | //走到这里,一定有内存 88 | T* obj = (T*)((char*)_requestMemory->_memory+_useCount*_size); 89 | 90 | _useCount++; 91 | return new(obj)T();//用定位new对这块空间初始化 92 | } 93 | } 94 | 95 | void Delete(T* obj) 96 | { 97 | if (obj) 98 | { 99 | obj->~T(); 100 | 101 | *((T**)obj) = _releaseMemory; 102 | _releaseMemory = obj; 103 | } 104 | } 105 | }; 106 | 107 | //静态成员变量,类外初始化 108 | template 109 | size_t MemPool::_size = MemPool::setSize(); 110 | 111 | struct TreeNode 112 | { 113 | int _val; 114 | TreeNode* _left; 115 | TreeNode* _right; 116 | }; 117 | void test1() 118 | { 119 | MemPool mp; 120 | 121 | vector v; 122 | for (int i = 0; i < 10; i++) 123 | { 124 | TreeNode* mem = mp.New(); 125 | v.push_back(mem); 126 | } 127 | 128 | for (int i = 0; i < 10; i++) 129 | { 130 | mp.Delete(v[i]); 131 | } 132 | } 133 | 134 | void test2() 135 | { 136 | MemPool tnPool; 137 | std::vector v1; 138 | //申请110000个treeNode 139 | //使用MemPoll申请 140 | size_t begin1 = clock(); 141 | for (int i = 0; i < 110000; ++i) 142 | { 143 | v1.push_back(tnPool.New()); 144 | } 145 | for (int i = 0; i < 110000; ++i) 146 | { 147 | tnPool.Delete(v1[i]); 148 | } 149 | v1.clear(); 150 | 151 | size_t end1 = clock(); 152 | 153 | //使用new和delete 154 | size_t begin2 = clock(); 155 | for (int i = 0; i < 110000; ++i) 156 | { 157 | v1.push_back(new TreeNode); 158 | } 159 | 160 | for (int i = 0; i < 110000; ++i) 161 | { 162 | delete v1[i]; 163 | } 164 | v1.clear(); 165 | size_t end2 = clock(); 166 | //使用malloc和free 167 | size_t begin3 = clock(); 168 | for (int i = 0; i < 110000; ++i) 169 | { 170 | v1.push_back((TreeNode*)malloc(sizeof(TreeNode*))); 171 | } 172 | for (int i = 0; i < 110000; ++i) 173 | { 174 | free(v1[i]); 175 | } 176 | v1.clear(); 177 | size_t end3 = clock(); 178 | 179 | cout <<"MemPool " < 2 | #include 3 | using namespace std; 4 | 5 | //直接插入排序 6 | void DirectorSort(vector& v) 7 | { 8 | //思路:将第n个元素插入到前n-1个有序序列中 9 | //时间复杂度:O(N)~O(N^2) 10 | //稳定性:稳定 11 | for(int i = 1;i < v.size();i++) 12 | { 13 | int j = i-1; 14 | int tmp = v[i]; 15 | while(j >= 0) 16 | { 17 | if(v[j] > tmp) 18 | { 19 | v[j+1] = v[j]; 20 | j--; 21 | } 22 | else 23 | { 24 | break; 25 | } 26 | } 27 | v[j+1] = tmp; 28 | } 29 | } 30 | 31 | //希尔排序 32 | void HillSort(vector& v) 33 | { 34 | //思路:以gap为间隔进行直接插入排序 35 | //时间复杂度:O(N^1.3)~O(N^2) 36 | //稳定性:不稳定 37 | int gap = v.size(); 38 | while(gap > 1) 39 | { 40 | gap = gap/3+1;//gap以三倍缩小,为了保证最后一次GAP为1,加1 41 | //直接插入排序 42 | for(int i = 1;i < v.size();i++) 43 | { 44 | int j = i-gap; 45 | int tmp = v[i]; 46 | while(j >= 0) 47 | { 48 | if(v[j] > tmp) 49 | { 50 | v[j+gap] = v[j]; 51 | j -= gap; 52 | } 53 | else 54 | { 55 | break; 56 | } 57 | } 58 | v[j+gap] = tmp; 59 | } 60 | } 61 | } 62 | 63 | //选择排序 64 | void SelectSort(vector& v) 65 | { 66 | //思路:从n个元素选出最大的和第n个元素交换位置 67 | //时间复杂度:O(N^2) 68 | //稳定性:不稳定 69 | 70 | for(int i = 0;i < v.size()-1;i++) 71 | { 72 | int maxIndex = 0; 73 | for(int j = 0;j < v.size()-i;j++) 74 | { 75 | if(v[j] > v[maxIndex]) 76 | { 77 | maxIndex = j; 78 | } 79 | } 80 | 81 | swap(v[maxIndex],v[v.size()-1-i]); 82 | } 83 | } 84 | 85 | //冒泡排序 86 | void BubbleSort(vector& v) 87 | { 88 | //思路:两两比较,大的后移。一趟比较结束,最大的在最后 89 | //世间复杂度:O(N^2) 90 | //稳定性:稳定 91 | for(int i = v.size() - 1;i > 0;i--) 92 | { 93 | for(int j = 1;j <= i;j++) 94 | { 95 | if(v[j-1] > v[j]) 96 | { 97 | swap(v[j-1],v[j]); 98 | } 99 | } 100 | } 101 | } 102 | 103 | //快速排序 - 左右指针 104 | int sort1(vector& v,int left,int right) 105 | { 106 | //思路:左边先走找大,右边再走找小,左右交换 107 | //时间复杂度:O(NlogN),数据完全有序时时间复杂度为O(N^2),数据完全逆序时时间复杂度为O(N) 108 | //稳定性:不稳定 109 | 110 | int tmp = right; 111 | while(left < right) 112 | { 113 | //左边先走找大 114 | while(left < right && v[left] <= v[tmp]) 115 | { 116 | left++; 117 | } 118 | //右边再走找小 119 | while(left < right && v[right] >= v[tmp]) 120 | { 121 | right--; 122 | } 123 | //左右交换 124 | swap(v[left],v[right]); 125 | } 126 | //将tmp存在left位置 127 | swap(v[left],v[tmp]); 128 | 129 | return left; 130 | } 131 | void QuickSort1(vector& v,int left,int right) 132 | { 133 | if(left >= right) 134 | return ; 135 | int index = sort1(v,left,right); 136 | QuickSort1(v,left,index-1); 137 | QuickSort1(v,index,right); 138 | } 139 | 140 | //快速排序 - 前后指针 141 | int Sort2(vector& v,int p1,int p2) 142 | { 143 | //思路:cur < tmp,prev++,否则cur++ 144 | int cur = p1; 145 | int prev = cur-1; 146 | while(cur <= p2) 147 | { 148 | if(v[cur] <= v[p2] && ++prev != cur) 149 | { 150 | swap(v[cur],v[prev]); 151 | } 152 | cur++; 153 | } 154 | 155 | return prev; 156 | } 157 | void QuickSort2(vector& v,int p1,int p2) 158 | { 159 | if(p1 >= p2) 160 | return; 161 | int index = Sort2(v,p1,p2); 162 | QuickSort2(v,p1,index-1); 163 | QuickSort2(v,index,p2); 164 | } 165 | 166 | //快速排序 - 挖坑法 167 | int sort3(vector& v,int left,int right) 168 | { 169 | //思路:左边先走找大,填到右边的坑,右边再走找小填到左边的坑 170 | int tmp = v[right]; 171 | 172 | while(left < right) 173 | { 174 | while(left < right && v[left] <= tmp) 175 | left++; 176 | //左边的值填入右边的坑 177 | v[right] = v[left]; 178 | while(left < right && v[right] >= tmp) 179 | right--; 180 | //右边的值填入左边的坑 181 | v[left] = v[right]; 182 | } 183 | //tmp填入最后一个坑 184 | v[left] = tmp; 185 | return left; 186 | } 187 | void QuickSort3(vector& v,int left,int right) 188 | { 189 | if(left >= right) 190 | return; 191 | int index = sort3(v,left,right); 192 | QuickSort3(v,left,index-1); 193 | QuickSort3(v,index,right); 194 | } 195 | 196 | //堆排 197 | void AdjustDown(vector& v,int root,int end) 198 | { 199 | int child = root*2 + 1; 200 | int parent = root; 201 | 202 | while(child <= end) 203 | { 204 | if(child+1 <= end && v[child+1] > v[child]) 205 | child++; 206 | 207 | if(v[child] > v[parent]) 208 | { 209 | swap(v[child],v[parent]); 210 | //继续迭代 211 | parent = child; 212 | child = parent*2 + 1; 213 | } 214 | else 215 | { 216 | break; 217 | } 218 | } 219 | } 220 | 221 | void HeapSort(vector& v) 222 | { 223 | //建大堆 224 | for(int i = (v.size()-2)/2;i >= 0;i--) 225 | { 226 | AdjustDown(v,i,v.size()-1); 227 | } 228 | 229 | //堆排序 230 | for(int i = 0;i < v.size()-1;i++) 231 | { 232 | swap(v[0],v[v.size()-1-i]); 233 | AdjustDown(v,0,v.size()-2-i); 234 | } 235 | } 236 | 237 | //归并排序 238 | void Merge(vector& v,int begin1,int end1,int begin2,int end2) 239 | { 240 | vector tmp; 241 | int index = begin1; 242 | while(begin1 <= end1 && begin2 <= end2) 243 | { 244 | if(v[begin1] < v[begin2]) 245 | { 246 | tmp.push_back(v[begin1]); 247 | begin1++; 248 | } 249 | else 250 | { 251 | tmp.push_back(v[begin2]); 252 | begin2++; 253 | } 254 | } 255 | 256 | while(begin1 <= end1) 257 | { 258 | tmp.push_back(v[begin1]); 259 | begin1++; 260 | } 261 | while(begin2 <= end2) 262 | { 263 | tmp.push_back(v[begin2]); 264 | begin2++; 265 | } 266 | 267 | for(int i = 0;i < tmp.size();i++) 268 | { 269 | v[index] = tmp[i]; 270 | index++; 271 | } 272 | } 273 | 274 | void MergeSort(vector& v,int begin,int end) 275 | { 276 | if(begin >= end) 277 | return; 278 | int index = (begin+end)/2; 279 | MergeSort(v,begin,index); 280 | MergeSort(v,index+1,end); 281 | 282 | Merge(v,begin,index,index+1,end); 283 | } 284 | 285 | int main() 286 | { 287 | vector v(15); 288 | v = {2,5,8,7,9,3,4,6,0,12,43,35,76,25,7}; 289 | cout<<"待排序序列:"; 290 | for(auto e:v) 291 | { 292 | cout< 2 | 2 using namespace std; 3 | 3 4 | 4 int main() 5 | 5 { 6 | 6 cout<<"hello linux\nhello c++"< 2 | 3 | int main() 4 | { 5 | //test 6 | return 0; 7 | } 8 | -------------------------------------------------------------------------------- /vector: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | namespace myvector 7 | { 8 | template 9 | class vector 10 | { 11 | public: 12 | typedef T* iterator; 13 | 14 | iterator begin() 15 | { 16 | return start; 17 | } 18 | 19 | iterator end() 20 | { 21 | return finish; 22 | } 23 | 24 | //默认构造函数 25 | vector() 26 | :start(nullptr) 27 | , finish(nullptr) 28 | , end_of_storage(nullptr) 29 | {} 30 | //容量 31 | size_t capacity() 32 | { 33 | return end_of_storage - start; 34 | } 35 | 36 | size_t size() 37 | { 38 | return finish - start; 39 | } 40 | 41 | void reserve(size_t n) 42 | { 43 | if (n > capacity()) 44 | { 45 | //开新空间 46 | T* tmp = new T[n]; 47 | //拷贝旧空间的内容 48 | memcpy(tmp, start, sizeof(T)*size()); 49 | //改变容量 50 | finish = tmp + size(); 51 | end_of_storage = tmp + n; 52 | //释放旧空间 53 | T* tmp1 = start; 54 | start = tmp; 55 | tmp = nullptr; 56 | } 57 | } 58 | 59 | void resize(size_t n, const T& val = T()) 60 | { 61 | //判断容量 62 | if (n > capacity()) 63 | reserve(n); 64 | //如果n= start && pos <= finish); 104 | size_t pos1 = pos - start; 105 | check_capacity(); 106 | //解决迭代器失效 107 | pos = start + pos1; 108 | //移动数据 109 | iterator end = finish; 110 | while (end >= pos) 111 | { 112 | *(end + 1) = *end; 113 | end--; 114 | } 115 | //插入数据 116 | *pos = x; 117 | finish++; 118 | return pos; 119 | } 120 | 121 | //删除数据 122 | void pop_back() 123 | { 124 | assert(finish > start); 125 | finish--; 126 | } 127 | iterator erase(iterator pos) 128 | { 129 | assert(pos >= start && pos < finish); 130 | 131 | iterator it = pos + 1; 132 | while (it != finish) 133 | { 134 | *(it - 1) = *it; 135 | ++it; 136 | } 137 | --finish; 138 | 139 | return pos; 140 | } 141 | //析构函数 142 | ~vector() 143 | { 144 | delete[] start; 145 | start = finish = end_of_storage = nullptr; 146 | } 147 | private: 148 | iterator start; 149 | iterator finish; 150 | iterator end_of_storage; 151 | }; 152 | } 153 | -------------------------------------------------------------------------------- /高并发内存池项目完整代码/Benchmark.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MouCoder/cpp_Code/6f6868685562996c866f5aa8f82ef914eada3b0e/高并发内存池项目完整代码/Benchmark.cpp -------------------------------------------------------------------------------- /高并发内存池项目完整代码/CentralControlCache.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MouCoder/cpp_Code/6f6868685562996c866f5aa8f82ef914eada3b0e/高并发内存池项目完整代码/CentralControlCache.cpp -------------------------------------------------------------------------------- /高并发内存池项目完整代码/CentralControlCache.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MouCoder/cpp_Code/6f6868685562996c866f5aa8f82ef914eada3b0e/高并发内存池项目完整代码/CentralControlCache.h -------------------------------------------------------------------------------- /高并发内存池项目完整代码/Common.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MouCoder/cpp_Code/6f6868685562996c866f5aa8f82ef914eada3b0e/高并发内存池项目完整代码/Common.h -------------------------------------------------------------------------------- /高并发内存池项目完整代码/ConCurrmentMemoryPoolProject.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {8F226646-EEC3-41F4-85F3-D1138B54492D} 15 | ConCurrmentMemoryPoolProject 16 | 17 | 18 | 19 | Application 20 | true 21 | v120 22 | MultiByte 23 | 24 | 25 | Application 26 | false 27 | v120 28 | true 29 | MultiByte 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | Level3 45 | Disabled 46 | true 47 | 48 | 49 | true 50 | Console 51 | 52 | 53 | 54 | 55 | Level3 56 | MaxSpeed 57 | true 58 | true 59 | true 60 | 61 | 62 | true 63 | true 64 | true 65 | Console 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /高并发内存池项目完整代码/ConCurrmentMemoryPoolProject.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 头文件 20 | 21 | 22 | 头文件 23 | 24 | 25 | 头文件 26 | 27 | 28 | 头文件 29 | 30 | 31 | 头文件 32 | 33 | 34 | 头文件 35 | 36 | 37 | 38 | 39 | 源文件 40 | 41 | 42 | 源文件 43 | 44 | 45 | 源文件 46 | 47 | 48 | 源文件 49 | 50 | 51 | 源文件 52 | 53 | 54 | -------------------------------------------------------------------------------- /高并发内存池项目完整代码/MemoryManagment.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MouCoder/cpp_Code/6f6868685562996c866f5aa8f82ef914eada3b0e/高并发内存池项目完整代码/MemoryManagment.h -------------------------------------------------------------------------------- /高并发内存池项目完整代码/PageCache.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MouCoder/cpp_Code/6f6868685562996c866f5aa8f82ef914eada3b0e/高并发内存池项目完整代码/PageCache.cpp -------------------------------------------------------------------------------- /高并发内存池项目完整代码/PageCache.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MouCoder/cpp_Code/6f6868685562996c866f5aa8f82ef914eada3b0e/高并发内存池项目完整代码/PageCache.h -------------------------------------------------------------------------------- /高并发内存池项目完整代码/PageMap.h: -------------------------------------------------------------------------------- 1 | #include "Common.h" 2 | 3 | template 4 | class TCMalloc_PageMap2 { 5 | private: 6 | // Put 32 entries in the root and (2^BITS)/32 entries in each leaf. 7 | static const int ROOT_BITS = 5; 8 | static const int ROOT_LENGTH = 1 << ROOT_BITS; 9 | 10 | static const int LEAF_BITS = BITS - ROOT_BITS; 11 | static const int LEAF_LENGTH = 1 << LEAF_BITS; 12 | 13 | // Leaf node 14 | struct Leaf { 15 | Span* values[LEAF_LENGTH]; 16 | }; 17 | 18 | Leaf* root_[ROOT_LENGTH]; // Pointers to 32 child nodes 19 | 20 | public: 21 | typedef uintptr_t Number; 22 | 23 | explicit TCMalloc_PageMap2() { 24 | memset(root_, 0, sizeof(root_)); 25 | PreallocateMoreMemory(); 26 | } 27 | 28 | Span* get(Number k) const { 29 | const Number i1 = k >> LEAF_BITS; 30 | const Number i2 = k & (LEAF_LENGTH - 1); 31 | if ((k >> BITS) > 0 || root_[i1] == NULL) { 32 | return NULL; 33 | } 34 | return root_[i1]->values[i2]; 35 | } 36 | 37 | void set(Number k, Span* v) { 38 | const Number i1 = k >> LEAF_BITS; 39 | const Number i2 = k & (LEAF_LENGTH - 1); 40 | assert(i1 < ROOT_LENGTH); 41 | root_[i1]->values[i2] = v; 42 | } 43 | 44 | Span*& operator[](Number k) 45 | { 46 | const Number i1 = k >> LEAF_BITS; 47 | const Number i2 = k & (LEAF_LENGTH - 1); 48 | assert(i1 < ROOT_LENGTH); 49 | return root_[i1]->values[i2]; 50 | } 51 | 52 | void erase(Number k) 53 | { 54 | const Number i1 = k >> LEAF_BITS; 55 | const Number i2 = k & (LEAF_LENGTH - 1); 56 | assert(i1 < ROOT_LENGTH); 57 | root_[i1]->values[i2] = nullptr; 58 | } 59 | 60 | bool Ensure(Number start, size_t n) { 61 | for (Number key = start; key <= start + n - 1;) { 62 | const Number i1 = key >> LEAF_BITS; 63 | 64 | // Check for overflow 65 | if (i1 >= ROOT_LENGTH) 66 | return false; 67 | 68 | // Make 2nd level node if necessary 69 | if (root_[i1] == NULL) { 70 | Leaf* leaf = new Leaf; 71 | if (leaf == NULL) return false; 72 | memset(leaf, 0, sizeof(*leaf)); 73 | root_[i1] = leaf; 74 | } 75 | 76 | // Advance key past whatever is covered by this leaf node 77 | key = ((key >> LEAF_BITS) + 1) << LEAF_BITS; 78 | } 79 | return true; 80 | } 81 | 82 | void PreallocateMoreMemory() { 83 | // Allocate enough to keep track of all possible pages 84 | Ensure(0, 1 << BITS); 85 | } 86 | 87 | void* Next(Number k) const { 88 | while (k < (1 << BITS)) { 89 | const Number i1 = k >> LEAF_BITS; 90 | Leaf* leaf = root_[i1]; 91 | if (leaf != NULL) { 92 | // Scan forward in leaf 93 | for (Number i2 = k & (LEAF_LENGTH - 1); i2 < LEAF_LENGTH; i2++) { 94 | if (leaf->values[i2] != NULL) { 95 | return leaf->values[i2]; 96 | } 97 | } 98 | } 99 | // Skip to next top-level entry 100 | k = (i1 + 1) << LEAF_BITS; 101 | } 102 | return NULL; 103 | } 104 | }; -------------------------------------------------------------------------------- /高并发内存池项目完整代码/Release/Benchmark.obj: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MouCoder/cpp_Code/6f6868685562996c866f5aa8f82ef914eada3b0e/高并发内存池项目完整代码/Release/Benchmark.obj -------------------------------------------------------------------------------- /高并发内存池项目完整代码/Release/CentralControlCache.obj: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MouCoder/cpp_Code/6f6868685562996c866f5aa8f82ef914eada3b0e/高并发内存池项目完整代码/Release/CentralControlCache.obj -------------------------------------------------------------------------------- /高并发内存池项目完整代码/Release/ConCurrm.8F226646.tlog/CL.read.1.tlog: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MouCoder/cpp_Code/6f6868685562996c866f5aa8f82ef914eada3b0e/高并发内存池项目完整代码/Release/ConCurrm.8F226646.tlog/CL.read.1.tlog -------------------------------------------------------------------------------- /高并发内存池项目完整代码/Release/ConCurrm.8F226646.tlog/CL.write.1.tlog: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MouCoder/cpp_Code/6f6868685562996c866f5aa8f82ef914eada3b0e/高并发内存池项目完整代码/Release/ConCurrm.8F226646.tlog/CL.write.1.tlog -------------------------------------------------------------------------------- /高并发内存池项目完整代码/Release/ConCurrm.8F226646.tlog/ConCurrmentMemoryPoolProject.lastbuildstate: -------------------------------------------------------------------------------- 1 | #TargetFrameworkVersion=v4.0:PlatformToolSet=v120:EnableManagedIncrementalBuild=false:VCToolArchitecture=Native32Bit 2 | Release|Win32|c:\users\user\documents\visual studio 2013\Projects\ConCurrmentMemoryPoolProject\| 3 | -------------------------------------------------------------------------------- /高并发内存池项目完整代码/Release/ConCurrm.8F226646.tlog/cl.command.1.tlog: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MouCoder/cpp_Code/6f6868685562996c866f5aa8f82ef914eada3b0e/高并发内存池项目完整代码/Release/ConCurrm.8F226646.tlog/cl.command.1.tlog -------------------------------------------------------------------------------- /高并发内存池项目完整代码/Release/ConCurrm.8F226646.tlog/link.command.1.tlog: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MouCoder/cpp_Code/6f6868685562996c866f5aa8f82ef914eada3b0e/高并发内存池项目完整代码/Release/ConCurrm.8F226646.tlog/link.command.1.tlog -------------------------------------------------------------------------------- /高并发内存池项目完整代码/Release/ConCurrm.8F226646.tlog/link.read.1.tlog: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MouCoder/cpp_Code/6f6868685562996c866f5aa8f82ef914eada3b0e/高并发内存池项目完整代码/Release/ConCurrm.8F226646.tlog/link.read.1.tlog -------------------------------------------------------------------------------- /高并发内存池项目完整代码/Release/ConCurrm.8F226646.tlog/link.write.1.tlog: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MouCoder/cpp_Code/6f6868685562996c866f5aa8f82ef914eada3b0e/高并发内存池项目完整代码/Release/ConCurrm.8F226646.tlog/link.write.1.tlog -------------------------------------------------------------------------------- /高并发内存池项目完整代码/Release/ConCurrmentMemoryPoolProject.log: -------------------------------------------------------------------------------- 1 | 生成启动时间为 2021/7/12 17:16:29。 2 | 1>项目“c:\Users\user\documents\visual studio 2013\Projects\ConCurrmentMemoryPoolProject\ConCurrmentMemoryPoolProject\ConCurrmentMemoryPoolProject.vcxproj”在节点 2 上(Build 个目标)。 3 | 1>ClCompile: 4 | D:\专业软件\VS2013\VC\bin\CL.exe /c /Zi /nologo /W3 /WX- /sdl /O2 /Oi /Oy- /GL /D _MBCS /Gm- /EHsc /MD /GS /Gy /fp:precise /Zc:wchar_t /Zc:forScope /Fo"Release\\" /Fd"Release\vc120.pdb" /Gd /TP /analyze- /errorReport:prompt Benchmark.cpp CentralControlCache.cpp PageCache.cpp ThreadCache.cpp UnitTest.cpp 5 | Benchmark.cpp 6 | CentralControlCache.cpp 7 | PageCache.cpp 8 | ThreadCache.cpp 9 | UnitTest.cpp 10 | Link: 11 | D:\专业软件\VS2013\VC\bin\link.exe /ERRORREPORT:PROMPT /OUT:"c:\users\user\documents\visual studio 2013\Projects\ConCurrmentMemoryPoolProject\Release\ConCurrmentMemoryPoolProject.exe" /NOLOGO kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /MANIFEST /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /manifest:embed /DEBUG /PDB:"c:\users\user\documents\visual studio 2013\Projects\ConCurrmentMemoryPoolProject\Release\ConCurrmentMemoryPoolProject.pdb" /SUBSYSTEM:CONSOLE /OPT:REF /OPT:ICF /LTCG /TLBID:1 /DYNAMICBASE /NXCOMPAT /IMPLIB:"c:\users\user\documents\visual studio 2013\Projects\ConCurrmentMemoryPoolProject\Release\ConCurrmentMemoryPoolProject.lib" /MACHINE:X86 /SAFESEH Release\Benchmark.obj 12 | Release\CentralControlCache.obj 13 | Release\PageCache.obj 14 | Release\ThreadCache.obj 15 | Release\UnitTest.obj 16 | 正在生成代码 17 | 已完成代码的生成 18 | ConCurrmentMemoryPoolProject.vcxproj -> c:\users\user\documents\visual studio 2013\Projects\ConCurrmentMemoryPoolProject\Release\ConCurrmentMemoryPoolProject.exe 19 | 1>已完成生成项目“c:\Users\user\documents\visual studio 2013\Projects\ConCurrmentMemoryPoolProject\ConCurrmentMemoryPoolProject\ConCurrmentMemoryPoolProject.vcxproj”(Build 个目标)的操作。 20 | 21 | 生成成功。 22 | 23 | 已用时间 00:00:03.73 24 | -------------------------------------------------------------------------------- /高并发内存池项目完整代码/Release/PageCache.obj: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MouCoder/cpp_Code/6f6868685562996c866f5aa8f82ef914eada3b0e/高并发内存池项目完整代码/Release/PageCache.obj -------------------------------------------------------------------------------- /高并发内存池项目完整代码/Release/ThreadCache.obj: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MouCoder/cpp_Code/6f6868685562996c866f5aa8f82ef914eada3b0e/高并发内存池项目完整代码/Release/ThreadCache.obj -------------------------------------------------------------------------------- /高并发内存池项目完整代码/Release/UnitTest.obj: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MouCoder/cpp_Code/6f6868685562996c866f5aa8f82ef914eada3b0e/高并发内存池项目完整代码/Release/UnitTest.obj -------------------------------------------------------------------------------- /高并发内存池项目完整代码/Release/vc120.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MouCoder/cpp_Code/6f6868685562996c866f5aa8f82ef914eada3b0e/高并发内存池项目完整代码/Release/vc120.pdb -------------------------------------------------------------------------------- /高并发内存池项目完整代码/ThreadCache.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MouCoder/cpp_Code/6f6868685562996c866f5aa8f82ef914eada3b0e/高并发内存池项目完整代码/ThreadCache.cpp -------------------------------------------------------------------------------- /高并发内存池项目完整代码/ThreadCache.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MouCoder/cpp_Code/6f6868685562996c866f5aa8f82ef914eada3b0e/高并发内存池项目完整代码/ThreadCache.h -------------------------------------------------------------------------------- /高并发内存池项目完整代码/UnitTest.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MouCoder/cpp_Code/6f6868685562996c866f5aa8f82ef914eada3b0e/高并发内存池项目完整代码/UnitTest.cpp --------------------------------------------------------------------------------