├── BinaryTree ├── BinaryTree.cpp ├── BinaryTree.h └── main.cpp ├── DynamicArray ├── DynamicArray.cpp ├── DynamicArray.h └── main.cpp ├── LinkList ├── LinkList.cpp ├── LinkList.h └── main.cpp ├── LinkQueue ├── LinkQueue.cpp ├── LinkQueue.h └── main.cpp ├── LinkStack ├── LinkStack.cpp ├── LinkStack.h └── main.cpp ├── README.md ├── SeqQueue ├── SeqQueue.cpp ├── SeqQueue.h └── main.cpp ├── SeqStack ├── SeqStack.cpp ├── SeqStack.h └── main.cpp └── Sorter ├── Sorter.cpp ├── Sorter.h └── main.cpp /BinaryTree/BinaryTree.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by wenhan on 2021/1/28. 3 | // 4 | 5 | #include 6 | #include "BinaryTree.h" 7 | #include 8 | 9 | BinaryTree::BinaryTree() { 10 | root = nullptr; 11 | } 12 | 13 | BinaryTree::~BinaryTree() { 14 | std::cout << "\n-------------------" << std::endl; 15 | std::cout << "free BinaryTree: "; 16 | _freeBinaryTree(root); 17 | } 18 | 19 | void BinaryTree::createBinaryTree() { 20 | // 创建结点 21 | // 这里必须使用new, 否则构造完成后各node会自动销毁! 22 | // 使用new之后,虽不会被自动销毁,但是必须手动在析构函数中释放内存! 23 | 24 | auto *node1 = new BinaryNode{'A', nullptr, nullptr}; 25 | auto *node2 = new BinaryNode{'B', nullptr, nullptr}; 26 | auto *node3 = new BinaryNode{'C', nullptr, nullptr}; 27 | auto *node4 = new BinaryNode{'D', nullptr, nullptr}; 28 | auto *node5 = new BinaryNode{'E', nullptr, nullptr}; 29 | auto *node6 = new BinaryNode{'F', nullptr, nullptr}; 30 | auto *node7 = new BinaryNode{'G', nullptr, nullptr}; 31 | auto *node8 = new BinaryNode{'H', nullptr, nullptr}; 32 | 33 | // 建立结点关系 34 | node1->lchild = node2; 35 | node1->rchild = node6; 36 | node2->rchild = node3; 37 | node3->lchild = node4; 38 | node3->rchild = node5; 39 | node6->rchild = node7; 40 | node7->lchild = node8; 41 | 42 | root = node1; 43 | } 44 | 45 | 46 | void BinaryTree::createBinaryTree(char *nodeSeq, size_t num) { 47 | if (nodeSeq == nullptr){ 48 | return; 49 | } 50 | if (root != nullptr){ 51 | _freeBinaryTree(root); 52 | } 53 | int pos = 0; 54 | root = _createBinaryTree(nodeSeq, num, pos); 55 | } 56 | 57 | // 先序遍历递归实现 58 | void BinaryTree::recursion() { 59 | if (root == nullptr){ 60 | return; 61 | } 62 | _recursion(root); 63 | } 64 | 65 | // 计算叶子结点数目 66 | void BinaryTree::calculateLeafNum() { 67 | if (root == nullptr){ 68 | return; 69 | } 70 | int num = 0; 71 | _calculateLeafNum(root, num); 72 | std::cout << "叶子结点的数目:" << num << std::endl; 73 | } 74 | 75 | void BinaryTree::calculateTreeHeight() { 76 | if (root == nullptr){ 77 | return; 78 | } 79 | int height = 0; 80 | _calculateTreeHeight(root, height); 81 | std::cout << "树的高度:" << height << std::endl; 82 | } 83 | 84 | // 先序遍历非递归实现,借助STL中的stack实现 85 | void BinaryTree::nonRecursion() { 86 | if (root == nullptr){ 87 | return; 88 | } 89 | 90 | std::stack stk; 91 | BiTreeStackNode biTreeStackNode{root, false}; 92 | stk.push(biTreeStackNode); 93 | while (!stk.empty()){ 94 | BiTreeStackNode& node = stk.top(); 95 | // 必须重新复制一个与node一样的结点,否则node一直指向stack栈顶,出现结果异常! 96 | BiTreeStackNode rootNode{node.root, node.flag}; 97 | stk.pop(); 98 | if (rootNode.root == nullptr){ 99 | continue; 100 | } 101 | if (rootNode.flag){ 102 | std::cout << rootNode.root->ch << " "; 103 | continue; 104 | } 105 | rootNode.flag = true; 106 | 107 | // 通过控制入栈的顺序,可以分别实现前序、中序、后序遍历! 108 | 109 | // 当前结点的右结点入栈 110 | BiTreeStackNode rnode{rootNode.root->rchild, false}; 111 | stk.push(rnode); 112 | // 当前结点的左结点入栈 113 | BiTreeStackNode lnode{rootNode.root->lchild, false}; 114 | stk.push(lnode); 115 | // 当前结点入栈 116 | stk.push(rootNode); 117 | } 118 | } 119 | 120 | // 序列化 121 | std::string BinaryTree::serializeTree(){ 122 | return _serializeTree(root); 123 | } 124 | 125 | // 反序列化 126 | void BinaryTree::deserializeTree(const std::string &treeSeq){ 127 | if (treeSeq.empty()){ 128 | return; 129 | } 130 | if (root != nullptr){ 131 | _freeBinaryTree(root); 132 | } 133 | int pos = 0; 134 | root = _deserializeTree(treeSeq, pos); 135 | } 136 | 137 | // 重载赋值运算符,实现拷贝 138 | 139 | BinaryTree & BinaryTree::operator=(const BinaryTree& tree){ 140 | if (tree.root == nullptr){ 141 | return *this; 142 | } 143 | // 检查是否自我赋值! 144 | if (this == &tree){ 145 | return *this; 146 | } 147 | // BinaryNode *root_; 148 | // _copyBinaryTree(tree.root, &root_); 149 | this->root = _copyBinaryTree(tree.root); 150 | return *this; 151 | } 152 | 153 | void BinaryTree::_recursion(BinaryNode *currentRoot) { 154 | if (currentRoot == nullptr){ 155 | return; 156 | } 157 | 158 | // 访问根结点 159 | std::cout << currentRoot->ch << " "; 160 | 161 | // 遍历左子树 162 | _recursion(currentRoot->lchild); 163 | 164 | // 遍历右子树 165 | _recursion(currentRoot->rchild); 166 | } 167 | 168 | void BinaryTree::_freeBinaryTree(BinaryNode *currentRoot) { 169 | // 后序遍历销毁各结点 170 | 171 | if (currentRoot == nullptr){ 172 | return; 173 | } 174 | // 释放左子树 175 | _freeBinaryTree(currentRoot->lchild); 176 | // 释放右子树 177 | _freeBinaryTree(currentRoot->rchild); 178 | std::cout << currentRoot->ch << " "; 179 | // 释放当前结点 180 | delete currentRoot; 181 | } 182 | 183 | void BinaryTree::_calculateLeafNum(BinaryNode *currentRoot, int &num) { 184 | if (currentRoot == nullptr){ 185 | return; 186 | } 187 | if (currentRoot->lchild == nullptr && currentRoot->rchild == nullptr){ 188 | num ++; 189 | } 190 | // 左子树叶子结点数目 191 | _calculateLeafNum(currentRoot->lchild, num); 192 | 193 | // 右子树叶子结点数目 194 | _calculateLeafNum(currentRoot->rchild, num); 195 | 196 | } 197 | 198 | void BinaryTree::_calculateTreeHeight(BinaryNode *currentRoot, int &height) { 199 | if (currentRoot == nullptr){ 200 | return; 201 | } 202 | int lh = 0, rh = 0; 203 | _calculateTreeHeight(currentRoot->lchild,lh); 204 | _calculateTreeHeight(currentRoot->rchild, rh); 205 | height = 1 + ((lh>rh)?lh:rh); 206 | } 207 | 208 | void BinaryTree::_copyBinaryTree(BinaryNode* currentRoot, BinaryNode** copyRoot){ 209 | if (currentRoot == nullptr){ 210 | return; 211 | } 212 | *copyRoot = new BinaryNode{currentRoot->ch, nullptr, nullptr}; 213 | _copyBinaryTree(currentRoot->lchild, &((*copyRoot)->lchild)); 214 | _copyBinaryTree(currentRoot->rchild, &((*copyRoot)->rchild)); 215 | } 216 | 217 | BinaryNode* BinaryTree::_copyBinaryTree(BinaryNode* currentRoot){ 218 | if (currentRoot == nullptr){ 219 | return nullptr; 220 | } 221 | // 拷贝左子树 222 | BinaryNode *lchild = _copyBinaryTree(currentRoot->lchild); 223 | 224 | // 拷贝右子树 225 | BinaryNode *rchild = _copyBinaryTree(currentRoot->rchild); 226 | 227 | // 创建结点 228 | auto *newNode = new BinaryNode{currentRoot->ch, lchild, rchild}; 229 | return newNode; 230 | } 231 | 232 | BinaryNode* BinaryTree::_createBinaryTree(const char* nodeSeq, size_t num, int &pos){ 233 | if (nodeSeq == nullptr){ 234 | return nullptr; 235 | } 236 | if (pos >= num){ 237 | return nullptr; 238 | } 239 | if (nodeSeq[pos] == '#'){ 240 | pos++; 241 | return nullptr; 242 | } 243 | auto pNode = new BinaryNode{nodeSeq[pos], nullptr, nullptr}; 244 | pos++; 245 | pNode->lchild = _createBinaryTree(nodeSeq, num, pos); 246 | pNode->rchild = _createBinaryTree(nodeSeq, num, pos); 247 | return pNode; 248 | } 249 | 250 | std::string BinaryTree::_serializeTree(BinaryNode* currentRoot){ 251 | if (currentRoot == nullptr){ 252 | return "#"; 253 | } 254 | 255 | std::string treeString; 256 | treeString = treeString + currentRoot->ch; 257 | treeString += _serializeTree(currentRoot->lchild); 258 | treeString += _serializeTree(currentRoot->rchild); 259 | 260 | return treeString; 261 | } 262 | 263 | BinaryNode* BinaryTree::_deserializeTree(const std::string &treeSeq, int &pos) { 264 | if (treeSeq.empty()){ 265 | return nullptr; 266 | } 267 | if (pos >= treeSeq.size()){ 268 | return nullptr; 269 | } 270 | char ch = treeSeq.at(pos); 271 | if (ch == '#'){ 272 | pos ++; 273 | return nullptr; 274 | } 275 | auto *node = new BinaryNode{ch, nullptr, nullptr}; 276 | pos ++; 277 | node->lchild = _deserializeTree(treeSeq, pos); 278 | node->rchild = _deserializeTree(treeSeq, pos); 279 | return node; 280 | } -------------------------------------------------------------------------------- /BinaryTree/BinaryTree.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by wenhan on 2021/1/28. 3 | // 4 | 5 | #ifndef BINARYTREE_BINARYTREE_H 6 | #define BINARYTREE_BINARYTREE_H 7 | 8 | typedef struct BINARYNODE{ 9 | char ch; 10 | struct BINARYNODE * lchild; 11 | struct BINARYNODE * rchild; 12 | }BinaryNode; 13 | 14 | typedef struct BITREESTACKNODE{ 15 | BinaryNode *root; 16 | bool flag; 17 | }BiTreeStackNode; 18 | 19 | class BinaryTree { 20 | private: 21 | BinaryNode *root; 22 | 23 | public: 24 | BinaryTree(); 25 | 26 | ~BinaryTree(); 27 | 28 | void createBinaryTree(); 29 | 30 | void createBinaryTree(char* nodeSeq, size_t num); 31 | 32 | // 先序遍历递归实现 33 | void recursion(); 34 | 35 | // 计算叶子结点数目 36 | void calculateLeafNum(); 37 | 38 | // 计算二叉树的高度,对应视频无法观看,自己实现 39 | void calculateTreeHeight(); 40 | 41 | // 先序遍历非递归实现,借助STL中的stack实现 42 | void nonRecursion(); 43 | 44 | // 序列化 45 | std::string serializeTree(); 46 | 47 | // 反序列化 48 | void deserializeTree(const std::string &treeSeq); 49 | 50 | // 重载赋值运算符,实现拷贝 51 | BinaryTree& operator=(const BinaryTree &tree); 52 | 53 | private: 54 | static void _recursion(BinaryNode* currentRoot); 55 | 56 | static void _freeBinaryTree(BinaryNode* currentRoot); 57 | 58 | static void _calculateLeafNum(BinaryNode* currentRoot, int& num); 59 | 60 | static void _calculateTreeHeight(BinaryNode* currentRoot, int& height); 61 | 62 | // 自己想的拷贝方式,比较繁琐 63 | static void _copyBinaryTree(BinaryNode* currentRoot, BinaryNode** copyRoot); 64 | 65 | // 视频中的拷贝方式,比较简洁 66 | static BinaryNode* _copyBinaryTree(BinaryNode* currentRoot); 67 | 68 | static BinaryNode* _createBinaryTree(const char* nodeSeq, size_t num, int &pos); 69 | 70 | static std::string _serializeTree(BinaryNode* currentRoot); 71 | 72 | static BinaryNode* _deserializeTree(const std::string &treeSeq, int &pos); 73 | 74 | }; 75 | 76 | 77 | #endif //BINARYTREE_BINARYTREE_H 78 | -------------------------------------------------------------------------------- /BinaryTree/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "BinaryTree.h" 3 | 4 | int main() { 5 | BinaryTree tree; 6 | tree.createBinaryTree(); 7 | 8 | // 递归前序遍历 9 | std::cout << "递归前序遍历:" << std::endl; 10 | tree.recursion(); 11 | std::cout << "\n****************************" << std::endl; 12 | 13 | // 计算叶子结点数目 14 | tree.calculateLeafNum(); 15 | std::cout << "****************************" << std::endl; 16 | 17 | // 计算二叉树的高度 18 | tree.calculateTreeHeight(); 19 | std::cout << "****************************" << std::endl; 20 | 21 | // 非递归前序遍历 22 | std::cout << "非递归前序遍历:" << std::endl; 23 | tree.nonRecursion(); 24 | std::cout << "\n****************************" << std::endl; 25 | 26 | BinaryTree copyTree; 27 | 28 | // 深拷贝二叉树 29 | std::cout << "拷贝二叉树..." << std::endl; 30 | copyTree = tree; 31 | std::cout << "拷贝二叉树的前序遍历:" << std::endl; 32 | copyTree.recursion(); 33 | std::cout << "\n****************************" << std::endl; 34 | 35 | // #号法创建二叉树 36 | char nodeSeq[] = {'A', 'B', '#', 'C', 'D', '#', '#', 'E','#', '#', 'F', '#', 'G', 'H', '#', '#', '#'}; 37 | int num = 17; 38 | BinaryTree seqTree; 39 | std::cout << "#号法创建二叉树..." << std::endl; 40 | seqTree.createBinaryTree(nodeSeq, num); 41 | std::cout << "#号法创建二叉树前序遍历:" << std::endl; 42 | seqTree.recursion(); 43 | std::cout << "\n****************************" << std::endl; 44 | 45 | // 二叉树的反序列化与序列化 46 | std::string nodeSeqStr = "AB#CD##E##F#GH###"; 47 | BinaryTree seqTree2; 48 | std::cout << "二叉树反序列化-" << nodeSeqStr << "..." << std::endl; 49 | seqTree2.deserializeTree(nodeSeqStr); 50 | std::cout << "反序列化二叉树前序遍历:" << std::endl; 51 | seqTree2.recursion(); 52 | std::cout << "\n二叉树序列化:" << std::endl; 53 | std::string nodeSeqStr2 = seqTree2.serializeTree(); 54 | std::cout << nodeSeqStr2 << std::endl; 55 | 56 | // 自动调用析构函数释放内存(4次) 57 | 58 | return 0; 59 | } 60 | -------------------------------------------------------------------------------- /DynamicArray/DynamicArray.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by wenhan on 2021/1/24. 3 | // 4 | 5 | #include "DynamicArray.h" 6 | 7 | DynamicArray::DynamicArray(){ 8 | pAddr = nullptr; 9 | size = 0; 10 | capacity = 20; 11 | pAddr = new int[capacity]; 12 | } 13 | 14 | // 销毁array使用析构函数代替 15 | DynamicArray::~DynamicArray() { 16 | delete[] pAddr; 17 | std::cout << "free array!" << std::endl; 18 | } 19 | void DynamicArray::push_back_array(int value){ 20 | if (pAddr == nullptr){ 21 | return; 22 | } 23 | if (size == capacity){ 24 | int *newAddr = new int[2*capacity]; 25 | memcpy(newAddr, pAddr, capacity*sizeof(int)); 26 | delete [] pAddr; 27 | pAddr = newAddr; 28 | capacity = capacity * 2; 29 | } 30 | pAddr[size] = value; 31 | size ++; 32 | } 33 | void DynamicArray::remove_array_pos(int pos){ 34 | if (pAddr == nullptr){ 35 | return; 36 | } 37 | if (pos < 0 || pos >= size){ 38 | return; 39 | } 40 | for (int i = pos; i < size - 1; ++i) { 41 | pAddr[i] = pAddr[i+1]; 42 | } 43 | size --; 44 | } 45 | void DynamicArray::remove_array_val(int value){ 46 | if (pAddr == nullptr){ 47 | return; 48 | } 49 | int pos = find_array(value); 50 | remove_array_pos(pos); 51 | } 52 | 53 | void DynamicArray::clear_array() { 54 | size = 0; 55 | } 56 | 57 | int DynamicArray::find_array(int value){ 58 | if (pAddr == nullptr){ 59 | return -1; 60 | } 61 | int pos = -1; 62 | for (int i = 0; i < size; ++i) { 63 | if (pAddr[i] == value){ 64 | pos = i; 65 | break; 66 | } 67 | } 68 | return pos; 69 | } 70 | void DynamicArray::print_array(){ 71 | if (pAddr == nullptr){ 72 | return; 73 | } 74 | for (int i = 0; i < size; ++i) { 75 | std::cout << pAddr[i] << " "; 76 | } 77 | std::cout << std::endl; 78 | } 79 | 80 | int DynamicArray::get_capacity() const{ 81 | return capacity; 82 | } 83 | int DynamicArray::get_size() const{ 84 | return size; 85 | } 86 | 87 | int DynamicArray::at_array(int pos){ 88 | return pAddr[pos]; 89 | } 90 | 91 | bool DynamicArray::at_array(int pos, int& value){ // 视频中原始实现方式可变为更安全的方式 92 | if (pAddr == nullptr || pos >= size || pos >= capacity || pos < 0){ 93 | return false; 94 | } 95 | value = pAddr[pos]; 96 | return true; 97 | } -------------------------------------------------------------------------------- /DynamicArray/DynamicArray.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by wenhan on 2021/1/24. 3 | // 4 | 5 | #ifndef DYNAMICARRAY_DYNAMICARRAY_H 6 | #define DYNAMICARRAY_DYNAMICARRAY_H 7 | #include 8 | #include 9 | #include 10 | 11 | 12 | class DynamicArray { 13 | private: 14 | int *pAddr; 15 | int size; 16 | int capacity; 17 | 18 | public: 19 | DynamicArray(); 20 | ~DynamicArray(); 21 | void push_back_array(int value); 22 | void remove_array_pos(int pos); 23 | void remove_array_val(int value); 24 | void clear_array(); 25 | int find_array(int value); 26 | void print_array(); 27 | int get_capacity() const; 28 | int get_size() const; 29 | int at_array(int pos); 30 | bool at_array(int pos, int& value); 31 | 32 | }; 33 | 34 | 35 | #endif //DYNAMICARRAY_DYNAMICARRAY_H 36 | -------------------------------------------------------------------------------- /DynamicArray/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "DynamicArray.h" 3 | 4 | 5 | int test_01(){ 6 | DynamicArray dynamicArray; 7 | std::cout << "数组容量:" << dynamicArray.get_capacity() << std::endl; 8 | std::cout << "数组大小:" << dynamicArray.get_size() << std::endl; 9 | for (int i = 0; i < 30; ++i) { 10 | dynamicArray.push_back_array(i); 11 | } 12 | std::cout << "数组容量:" << dynamicArray.get_capacity() << std::endl; 13 | std::cout << "数组大小:" << dynamicArray.get_size() << std::endl; 14 | 15 | dynamicArray.print_array(); 16 | 17 | dynamicArray.remove_array_pos(0); 18 | dynamicArray.remove_array_val(27); 19 | dynamicArray.print_array(); 20 | 21 | int pos = dynamicArray.find_array(5); 22 | std::cout << "5查找到:pos:"<< pos << " " << dynamicArray.at_array(pos) << std::endl; 23 | 24 | //测试 at_array 安全实现 25 | int value = 0; 26 | pos = 100; 27 | bool ret = dynamicArray.at_array(pos, value); 28 | if (!ret){ 29 | std::cout << "查找 pos " << pos << " 失败!" << std::endl; 30 | }else{ 31 | std::cout << "查找 pos " << pos << " 成功!值为 " << value << std::endl; 32 | } 33 | 34 | pos = 26; 35 | ret = dynamicArray.at_array(pos, value); 36 | if (!ret){ 37 | std::cout << "查找 pos " << pos << " 失败!" << std::endl; 38 | }else{ 39 | std::cout << "查找 pos " << pos << " 成功!值为 " << value << std::endl; 40 | } 41 | 42 | // dynamicArray.free_array(); 43 | return 0; 44 | } 45 | 46 | int main() { 47 | test_01(); 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /LinkList/LinkList.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by wenhan on 2021/1/25. 3 | // 4 | 5 | #include 6 | #include "LinkList.h" 7 | 8 | LinkList::LinkList(){ 9 | head = new LinkNode; 10 | size = 0; 11 | // 头结点不保存数据信息 12 | head->data = nullptr; 13 | head->next = nullptr; 14 | } 15 | 16 | // 释放链表内存由析构函数代替 17 | LinkList::~LinkList() { 18 | if (head == nullptr){ 19 | return; 20 | } 21 | auto *pCurrent = head; 22 | while (pCurrent != nullptr){ 23 | // 缓存下一个结点指针 24 | auto *pNext = pCurrent->next; 25 | delete pCurrent; 26 | pCurrent = pNext; 27 | } 28 | size = 0; 29 | std::cout << "free LinkList!" << std::endl; 30 | } 31 | 32 | 33 | // 指定位置插入 34 | void LinkList::insert_linkList(int pos, void* data){ 35 | if (head == nullptr){ 36 | return; 37 | } 38 | if (data == nullptr){ 39 | return; 40 | } 41 | // 友好处理,pos越界 42 | if (pos < 0 ||pos > size){ 43 | pos = size; 44 | } 45 | //创建新结点 46 | auto * newNode = new LinkNode; 47 | newNode->data = data; 48 | newNode->next = nullptr; 49 | 50 | // 找结点 51 | // 辅助指针变量 52 | auto *pCurrent = head; 53 | for (int i = 0; i < pos; ++i) { 54 | pCurrent = pCurrent->next; 55 | } 56 | // 新结点入链表 57 | newNode->next = pCurrent->next; 58 | pCurrent->next = newNode; 59 | 60 | size++; 61 | } 62 | 63 | // 删除指定位置的值 64 | void LinkList::remove_linkList_pos(int pos){ 65 | if (head == nullptr){ 66 | return; 67 | } 68 | if (pos < 0 || pos >= size){ 69 | return; 70 | } 71 | auto *pCurrent = head; 72 | for (int i = 0; i < pos; ++i) { 73 | pCurrent = pCurrent->next; 74 | } 75 | auto *pDel = pCurrent->next; 76 | pCurrent->next = pDel->next; 77 | delete pDel; 78 | size --; 79 | } 80 | 81 | // 获得链表的长度 82 | int LinkList::get_size() const{ 83 | return size; 84 | } 85 | 86 | // 查找元素值位置 87 | int LinkList::find_linkList(void* data){ 88 | if (head == nullptr){ 89 | return -1; 90 | } 91 | if (data == nullptr){ 92 | return -1; 93 | } 94 | 95 | auto *pCurrent = head->next; 96 | int i = 0; 97 | while (pCurrent != nullptr){ 98 | if (pCurrent->data == data){ 99 | return i; 100 | } 101 | pCurrent = pCurrent->next; 102 | i++; 103 | } 104 | return -1; 105 | } 106 | 107 | // 返回第一个结点 108 | void *LinkList::get_front(){ 109 | return head -> next ->data; 110 | } 111 | 112 | // 打印 113 | void LinkList::print_linkList(PRINTLINKNODE print){ 114 | if (head == nullptr){ 115 | return; 116 | } 117 | auto *pCurrent = head->next; 118 | while (pCurrent != nullptr){ 119 | print(pCurrent->data); 120 | pCurrent = pCurrent ->next; 121 | } 122 | 123 | } 124 | 125 | 126 | 127 | -------------------------------------------------------------------------------- /LinkList/LinkList.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by wenhan on 2021/1/25. 3 | // 4 | 5 | #ifndef LINKLIST_LINKLIST_H 6 | #define LINKLIST_LINKLIST_H 7 | 8 | //链表结点 9 | typedef struct LINKNODE{ 10 | void* data; // 指向任意类型的数据 11 | struct LINKNODE* next; 12 | }LinkNode; 13 | 14 | // 打印函数指针 15 | typedef void(*PRINTLINKNODE)(void*); 16 | 17 | class LinkList { 18 | private: 19 | LinkNode *head; 20 | int size; 21 | public: 22 | // 初始化使用无参数构造器代替! 23 | LinkList(); 24 | 25 | // 释放链表内存由析构函数代替! 26 | ~LinkList(); 27 | 28 | // 指定位置插入 29 | void insert_linkList(int pos, void* data); 30 | 31 | // 删除指定位置的值 32 | void remove_linkList_pos(int pos); 33 | 34 | // 获得链表的长度 35 | int get_size() const; 36 | 37 | // 查找元素值位置 38 | int find_linkList(void* data); 39 | 40 | // 返回第一个结点 41 | void *get_front(); 42 | 43 | 44 | // 打印 45 | void print_linkList(PRINTLINKNODE print); 46 | 47 | 48 | }; 49 | 50 | 51 | #endif //LINKLIST_LINKLIST_H 52 | -------------------------------------------------------------------------------- /LinkList/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "LinkList.h" 3 | 4 | // 自定义数据类型 5 | typedef struct PERSON{ 6 | char name[64]; 7 | int age; 8 | int score; 9 | }Person; 10 | 11 | // 打印函数 12 | 13 | void myPrint(void *data){ 14 | auto *p = (Person *)data; 15 | std::cout << "Name:" << p->name << " Age:" << p->age << " Score:" << p->score << std::endl; 16 | } 17 | 18 | int main() { 19 | 20 | // 创建链表 21 | LinkList list; 22 | 23 | // 创建数据 24 | Person p1 = {"aaa", 18, 100}; 25 | Person p2 = {"bbb", 19, 99}; 26 | Person p3 = {"ccc", 20, 101}; 27 | Person p4 = {"ddd", 17, 97}; 28 | Person p5 = {"eee", 16, 59}; 29 | 30 | // 数据插入链表 31 | 32 | list.insert_linkList(0, &p1); 33 | list.insert_linkList(0, &p2); 34 | list.insert_linkList(0, &p3); 35 | list.insert_linkList(0, &p4); 36 | list.insert_linkList(0, &p5); 37 | 38 | // 打印 39 | list.print_linkList(myPrint); 40 | 41 | list.remove_linkList_pos(3); 42 | 43 | // 打印 44 | std::cout << "----------------------" << std::endl; 45 | list.print_linkList(myPrint); 46 | 47 | // 返回第一个结点 48 | std::cout << "---------查找结果-------------" << std::endl; 49 | auto ret = (Person *)list.get_front(); 50 | std::cout << "Name:" << ret->name << " Age:" << ret->age << " Score:" << ret->score << std::endl; 51 | 52 | // 查找(新增测试) 53 | std::cout << "----------------------" << std::endl; 54 | int pos = list.find_linkList(&p3); 55 | std::cout << "Name:" << p3.name << " Age:" << p3.age << " Score:" << p3.score << std::endl; 56 | std::cout << "pos: " << pos << std::endl; 57 | int size = list.get_size(); 58 | std::cout << "size: " << size << std::endl; 59 | 60 | // 自动调用LinkList析构函数 销毁 61 | 62 | return 0; 63 | } 64 | -------------------------------------------------------------------------------- /LinkQueue/LinkQueue.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by wenhan on 2021/1/27. 3 | // 4 | #include 5 | #include "LinkQueue.h" 6 | 7 | // 初始化方法使用无参数构造器代替 8 | LinkQueue::LinkQueue(){ 9 | head.next = nullptr; 10 | size = 0; 11 | } 12 | 13 | // 销毁队列使用析构函数代替 14 | LinkQueue::~LinkQueue(){ 15 | // 结点中没有使用new创建的元素,无需处理 16 | std::cout << "free LinkQueue!" << std::endl; 17 | } 18 | 19 | // 入栈 20 | void LinkQueue::push_linkQueue(LinkNode* data){ 21 | if (data == nullptr){ 22 | return; 23 | } 24 | if (size == 0){ 25 | head.next = data; 26 | size ++; 27 | return; 28 | } 29 | LinkNode *pCurrent = &head; 30 | for (int i = 0; i < size; ++i) { 31 | pCurrent = pCurrent->next; 32 | } 33 | pCurrent ->next = data; 34 | data->next = nullptr; 35 | size++; 36 | } 37 | 38 | // 返回队头元素 39 | void* LinkQueue::front_linkQueue() const{ 40 | if (size == 0){ 41 | return nullptr; 42 | } 43 | return head.next; 44 | } 45 | 46 | // 出队 47 | void LinkQueue::pop_linkQueue(){ 48 | if (size == 0){ 49 | return; 50 | } 51 | LinkNode *pNext = head.next; 52 | head.next = pNext->next; 53 | size --; 54 | } 55 | 56 | // 返回队尾元素 57 | void* LinkQueue::back_linkQueue(){ 58 | if (size == 0){ 59 | return nullptr; 60 | } 61 | LinkNode *pCurrent = &head; 62 | for (int i = 0; i < size; ++i) { 63 | pCurrent = pCurrent->next; 64 | } 65 | return pCurrent; 66 | } 67 | 68 | // 返回大小 69 | int LinkQueue::get_size() const{ 70 | return size; 71 | } 72 | 73 | // 清空队列 74 | void LinkQueue::clear_linkQueue(){ 75 | if (size == 0){ 76 | return; 77 | } 78 | head.next = nullptr; 79 | size = 0; 80 | } -------------------------------------------------------------------------------- /LinkQueue/LinkQueue.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by wenhan on 2021/1/27. 3 | // 4 | 5 | #ifndef LINKQUEUE_LINKQUEUE_H 6 | #define LINKQUEUE_LINKQUEUE_H 7 | 8 | // 链式队列的结点 9 | typedef struct LINKNODE{ 10 | struct LINKNODE* next; 11 | }LinkNode; 12 | 13 | class LinkQueue { 14 | private: 15 | LinkNode head{}; 16 | int size; 17 | public: 18 | // 初始化方法使用无参数构造器代替 19 | LinkQueue(); 20 | 21 | // 销毁队列使用析构函数代替 22 | ~LinkQueue(); 23 | 24 | // 入栈 25 | void push_linkQueue(LinkNode* data); 26 | 27 | // 返回队头元素 28 | void* front_linkQueue() const; 29 | 30 | // 出队 31 | void pop_linkQueue(); 32 | 33 | // 返回队尾元素 34 | void* back_linkQueue(); 35 | 36 | // 返回大小 37 | int get_size() const; 38 | 39 | // 清空队列 40 | void clear_linkQueue(); 41 | 42 | 43 | }; 44 | 45 | 46 | #endif //LINKQUEUE_LINKQUEUE_H 47 | -------------------------------------------------------------------------------- /LinkQueue/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "LinkQueue.h" 3 | #include 4 | 5 | typedef struct PERSON{ 6 | LinkNode node; 7 | char name[64]; 8 | int age; 9 | }Person; 10 | 11 | int main() { 12 | // 创建队列 13 | LinkQueue queue; 14 | 15 | // 创建数据 16 | Person p1, p2, p3, p4, p5; 17 | strcpy(p1.name, "aaa"); 18 | strcpy(p2.name, "bbb"); 19 | strcpy(p3.name, "ccc"); 20 | strcpy(p4.name, "ddd"); 21 | strcpy(p5.name, "eee"); 22 | p1.age = 10; 23 | p2.age = 20; 24 | p3.age = 30; 25 | p4.age = 40; 26 | p5.age = 50; 27 | 28 | // 数据入队列 29 | queue.push_linkQueue((LinkNode*)&p1); 30 | queue.push_linkQueue((LinkNode*)&p2); 31 | queue.push_linkQueue((LinkNode*)&p3); 32 | queue.push_linkQueue((LinkNode*)&p4); 33 | queue.push_linkQueue((LinkNode*)&p5); 34 | 35 | // 输出队尾元素 36 | auto backPerson = (Person*)queue.back_linkQueue(); 37 | std::cout << "Name:" << backPerson->name << " Age:" << backPerson->age << std::endl; 38 | 39 | // 输出 40 | while (queue.get_size() > 0){ 41 | // 取队头元素 42 | auto p = (Person*)queue.front_linkQueue(); 43 | std::cout << "Name:" << p->name << " Age:" << p->age << std::endl; 44 | // 从队头弹出元素 45 | queue.pop_linkQueue(); 46 | } 47 | // 自动调用析构函数 48 | 49 | return 0; 50 | } 51 | -------------------------------------------------------------------------------- /LinkStack/LinkStack.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by wenhan on 2021/1/26. 3 | // 4 | 5 | #include 6 | #include "LinkStack.h" 7 | 8 | 9 | // 初始化方法使用无参数构造器代替! 10 | LinkStack::LinkStack(){ 11 | head.next = nullptr; 12 | size = 0; 13 | } 14 | 15 | LinkStack::~LinkStack() { 16 | // 结点中没有使用new创建的元素,无需处理 17 | std::cout << "free LinkStack!" << std::endl; 18 | } 19 | 20 | // 入栈 21 | void LinkStack::push_linkStack(LinkNode* data){ 22 | if (data == nullptr){ 23 | return; 24 | } 25 | data ->next = head.next; 26 | head.next = data; 27 | size ++; 28 | } 29 | 30 | // 出栈 31 | void LinkStack::pop_linkStack(){ 32 | if (size == 0){ 33 | return; 34 | } 35 | 36 | // 第一个有效结点 37 | LinkNode *pNext = head.next; 38 | head.next = pNext->next; 39 | size --; 40 | 41 | } 42 | 43 | // 返回栈顶元素 44 | LinkNode* LinkStack::top_linkStack() const{ 45 | if (size == 0){ 46 | return nullptr; 47 | } 48 | return head.next; 49 | } 50 | 51 | // 返回栈元素个数 52 | int LinkStack::get_size()const{ 53 | return size; 54 | } 55 | 56 | // 清空栈 57 | void LinkStack::clear_linkStack(){ 58 | if (size == 0){ 59 | return; 60 | } 61 | head.next = nullptr; 62 | size = 0; 63 | } 64 | -------------------------------------------------------------------------------- /LinkStack/LinkStack.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by wenhan on 2021/1/26. 3 | // 4 | 5 | #ifndef LINKSTACK_LINKSTACK_H 6 | #define LINKSTACK_LINKSTACK_H 7 | 8 | // 链式栈的结点 9 | typedef struct LINKNODE{ 10 | struct LINKNODE* next; 11 | }LinkNode; 12 | 13 | // 链式栈 14 | // 头部作为栈顶,可直接插入或删除,无需遍历 15 | class LinkStack { 16 | private: 17 | LinkNode head{}; 18 | int size; 19 | public: 20 | // 初始化方法使用无参数构造器代替! 21 | LinkStack(); 22 | 23 | // 销毁栈使用析构函数代替! 24 | ~LinkStack(); 25 | 26 | // 入栈 27 | void push_linkStack(LinkNode* data); 28 | 29 | // 出栈 30 | void pop_linkStack(); 31 | 32 | // 返回栈顶元素 33 | LinkNode* top_linkStack() const; 34 | 35 | // 返回栈元素个数 36 | int get_size()const; 37 | 38 | // 清空栈 39 | void clear_linkStack(); 40 | 41 | 42 | }; 43 | 44 | 45 | #endif //LINKSTACK_LINKSTACK_H 46 | -------------------------------------------------------------------------------- /LinkStack/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "LinkStack.h" 3 | #include 4 | 5 | typedef struct PERSON{ 6 | LinkNode node; 7 | char name[64]; 8 | int age; 9 | }Person; 10 | 11 | int main() { 12 | // 创建栈 13 | LinkStack stack; 14 | 15 | // 创建数据 16 | Person p1, p2, p3, p4, p5; 17 | strcpy(p1.name, "aaa"); 18 | strcpy(p2.name, "bbb"); 19 | strcpy(p3.name, "ccc"); 20 | strcpy(p4.name, "ddd"); 21 | strcpy(p5.name, "eee"); 22 | 23 | p1.age = 10; 24 | p2.age = 20; 25 | p3.age = 30; 26 | p4.age = 40; 27 | p5.age = 50; 28 | 29 | // 入栈 30 | stack.push_linkStack((LinkNode*)&p1); 31 | stack.push_linkStack((LinkNode*)&p2); 32 | stack.push_linkStack((LinkNode*)&p3); 33 | stack.push_linkStack((LinkNode*)&p4); 34 | stack.push_linkStack((LinkNode*)&p5); 35 | 36 | while (stack.get_size() > 0){ 37 | // 取出栈顶元素 38 | auto *p = (Person *)stack.top_linkStack(); 39 | std::cout << "Name:" << p->name << " Age:" << p->age << std::endl; 40 | // 弹出栈顶元素 41 | stack.pop_linkStack(); 42 | } 43 | 44 | // 自动析构,销毁stack 45 | 46 | return 0; 47 | } 48 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 黑马程序员C++数据结构课OOP实现 2 | 3 | 现在工作上常用C++,也是为了业余时间锻炼思维,开始回顾下数据结构,在B站上找不到太像样的基于C++的数据结构课程,好不容易找到了来自黑马程序员的一个号称基于C++的数据结构课程,结果打开一看,基本是就是纯C实现,没有体现C++的特点。这个课程简洁明快,只包含了最基础的几个数据结构,虽然有些地方说的太简单了点,但对于有基础的人来说足够了。于是花了点时间把其中的算法进行了C++ OOP实现。 4 | 课程链接:[https://www.bilibili.com/video/BV13b411t7LF?p=1](https://www.bilibili.com/video/BV13b411t7LF?p=1) 5 | 数据结构类: 6 | 7 | | 类名 | 含义 | 备注 | 8 | | --- | --- | --- | 9 | | DynamicArray | 动态数组实现 | | 10 | | LinkList | 单链表实现 | | 11 | | SeqStack | 基于数组的堆栈实现 | | 12 | | LinkStack | 基于链表的堆栈实现 | | 13 | | SeqQueue | 基于数组的队列实现 | | 14 | | LinkQueue | 基于链表的队列实现 | 原视频中未给出(或上传遗漏?) | 15 | | BinaryTree | 二叉树实现 | | 16 | | Sorter | 各排序算法实现与性能对比 | | 17 | 18 | 各算法以类静态或非静态方法的形式提供。 19 | 代码 github:[https://github.com/Aiwiscal/HeimaDataStructure](https://github.com/Aiwiscal/HeimaDataStructure) 20 | 有用麻烦给颗star~ 21 | -------------------------------------------------------------------------------- /SeqQueue/SeqQueue.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by wenhan on 2021/1/27. 3 | // 4 | 5 | #include 6 | #include "SeqQueue.h" 7 | 8 | // 初始化使用无参数构造器代替 9 | SeqQueue::SeqQueue(){ 10 | for (auto & i : data) { 11 | i = nullptr; 12 | } 13 | size = 0; 14 | } 15 | 16 | // 销毁使用析构函数代替 17 | SeqQueue::~SeqQueue(){ 18 | // 数组所用数组未使用new创建,无需显式释放 19 | std::cout << "free SeqQueue!" << std::endl; 20 | } 21 | 22 | // 入队 23 | void SeqQueue::push_seqQueue(void* value){ 24 | // 数组左边当做队头 25 | // 防止与成员变量data重名,入参名改为value 26 | if (value == nullptr){ 27 | return; 28 | } 29 | if (size == MAX_SIZE){ 30 | return; 31 | } 32 | data[size] = value; 33 | size++; 34 | 35 | } 36 | 37 | // 返回队头元素 38 | void* SeqQueue::front_seqQueue(){ 39 | if (size == 0){ 40 | return nullptr; 41 | } 42 | return data[0]; 43 | } 44 | 45 | // 出队 46 | void SeqQueue::pop_seqQueue(){ 47 | if (size == 0){ 48 | return; 49 | } 50 | for (int i = 0; i < size - 1; ++i) { 51 | data[i] = data[i+1]; 52 | } 53 | size --; 54 | } 55 | 56 | // 返回队尾元素 57 | void* SeqQueue::back_seqQueue(){ 58 | if (size == 0){ 59 | return nullptr; 60 | } 61 | return data[size-1]; 62 | } 63 | 64 | // 返回大小 65 | int SeqQueue::get_size() const{ 66 | return size; 67 | } 68 | 69 | // 清空队列 70 | void SeqQueue::clear_seqQueue(){ 71 | if (size == 0){ 72 | return; 73 | } 74 | size = 0; 75 | } -------------------------------------------------------------------------------- /SeqQueue/SeqQueue.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by wenhan on 2021/1/27. 3 | // 4 | 5 | #ifndef SEQQUEUE_SEQQUEUE_H 6 | #define SEQQUEUE_SEQQUEUE_H 7 | 8 | const int MAX_SIZE = 1024; 9 | 10 | 11 | class SeqQueue { 12 | private: 13 | void* data[MAX_SIZE]{}; 14 | int size; 15 | 16 | public: 17 | // 初始化使用无参数构造器代替 18 | SeqQueue(); 19 | 20 | // 销毁使用析构函数代替 21 | ~SeqQueue(); 22 | 23 | // 入队 24 | void push_seqQueue(void* data); 25 | 26 | // 返回队头元素 27 | void* front_seqQueue(); 28 | 29 | // 出队 30 | void pop_seqQueue(); 31 | 32 | // 返回队尾元素 33 | void* back_seqQueue(); 34 | 35 | // 返回大小 36 | int get_size() const; 37 | 38 | // 清空队列 39 | void clear_seqQueue(); 40 | 41 | 42 | 43 | }; 44 | 45 | 46 | #endif //SEQQUEUE_SEQQUEUE_H 47 | -------------------------------------------------------------------------------- /SeqQueue/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "SeqQueue.h" 3 | 4 | typedef struct PERSON{ 5 | char name[64]; 6 | int age; 7 | }Person; 8 | 9 | int main() { 10 | // 创建队列 11 | SeqQueue queue; 12 | 13 | // 创建数据 14 | Person p1 = {"aaa", 10}; 15 | Person p2 = {"bbb", 20}; 16 | Person p3 = {"ccc", 30}; 17 | Person p4 = {"ddd", 40}; 18 | Person p5 = {"eee", 50}; 19 | 20 | // 数据入队列 21 | queue.push_seqQueue(&p1); 22 | queue.push_seqQueue(&p2); 23 | queue.push_seqQueue(&p3); 24 | queue.push_seqQueue(&p4); 25 | queue.push_seqQueue(&p5); 26 | 27 | // 输出队尾元素 28 | auto backPerson = (Person*)queue.back_seqQueue(); 29 | std::cout << "Name:" << backPerson->name << " Age:" << backPerson->age << std::endl; 30 | 31 | // 输出 32 | while (queue.get_size() > 0){ 33 | // 取队头元素 34 | auto p = (Person*)queue.front_seqQueue(); 35 | std::cout << "Name:" << p->name << " Age:" << p->age << std::endl; 36 | // 从队头弹出元素 37 | queue.pop_seqQueue(); 38 | } 39 | // 自动调用析构函数 40 | 41 | return 0; 42 | } 43 | -------------------------------------------------------------------------------- /SeqStack/SeqStack.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by wenhan on 2021/1/26. 3 | // 4 | 5 | #include 6 | #include "SeqStack.h" 7 | 8 | // 初始化方法使用无参数构造器代替! 9 | SeqStack::SeqStack(){ 10 | for (auto & i : data) { 11 | i = nullptr; 12 | } 13 | size = 0; 14 | } 15 | 16 | // 销毁 17 | SeqStack::~SeqStack() { 18 | std::cout << "free seq stack!" << std::endl; 19 | } 20 | 21 | // 入栈 22 | void SeqStack::push_seqStack(void *value){ 23 | // 防止与成员变量data冲突,改形参名为value 24 | if (value == nullptr){ 25 | return; 26 | } 27 | if (size == MAX_SIZE){ 28 | return; 29 | } 30 | data[size] = value; 31 | size ++; 32 | } 33 | 34 | // 返回栈顶元素 35 | void* SeqStack::top_seqStack(){ 36 | if (size == 0){ 37 | return nullptr; 38 | } 39 | return data[size-1]; 40 | } 41 | 42 | // 出栈 43 | void SeqStack::pop_seqStack(){ 44 | if (size == 0){ 45 | return; 46 | } 47 | data[size-1] = nullptr; 48 | size--; 49 | } 50 | 51 | // 判断是否为空 52 | bool SeqStack::is_empty() const{ 53 | if (size == 0){ 54 | return true; 55 | } 56 | return false; 57 | } 58 | 59 | // 返回栈中元素的个数 60 | int SeqStack::get_size() const{ 61 | return size; 62 | } 63 | 64 | // 清空栈 65 | void SeqStack::clear_seqStack(){ 66 | for (int i = 0; i < size; ++i) { 67 | data[i] = nullptr; 68 | } 69 | size = 0; 70 | } 71 | -------------------------------------------------------------------------------- /SeqStack/SeqStack.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by wenhan on 2021/1/26. 3 | // 4 | 5 | #ifndef SEQSTACK_SEQSTACK_H 6 | #define SEQSTACK_SEQSTACK_H 7 | 8 | const int MAX_SIZE = 1024; 9 | 10 | // 数组模拟堆栈的顺序存储 11 | // 数组右侧作为栈顶,无需频繁移动元素 12 | 13 | class SeqStack { 14 | private: 15 | void *data[MAX_SIZE]{}; 16 | int size; 17 | public: 18 | // 初始化方法使用无参数构造器代替! 19 | SeqStack(); 20 | 21 | // 销毁使用析构函数代替! 22 | ~SeqStack(); 23 | 24 | // 入栈 25 | void push_seqStack(void *data); 26 | 27 | // 返回栈顶元素 28 | void* top_seqStack(); 29 | 30 | // 出栈 31 | void pop_seqStack(); 32 | 33 | // 判断是否为空 34 | bool is_empty() const; 35 | 36 | // 返回栈中元素的个数 37 | int get_size() const; 38 | 39 | // 清空栈 40 | void clear_seqStack(); 41 | 42 | }; 43 | 44 | 45 | #endif //SEQSTACK_SEQSTACK_H 46 | -------------------------------------------------------------------------------- /SeqStack/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "SeqStack.h" 3 | 4 | typedef struct PERSON{ 5 | char name[64]; 6 | int age; 7 | }Person; 8 | 9 | int main() { 10 | // 创建栈 11 | SeqStack stack; 12 | 13 | //创建数据 14 | Person p1 = {"aaa", 10}; 15 | Person p2 = {"bbb", 20}; 16 | Person p3 = {"ccc", 30}; 17 | Person p4 = {"ddd", 40}; 18 | Person p5 = {"eee", 50}; 19 | 20 | // 入栈 21 | stack.push_seqStack(&p1); 22 | stack.push_seqStack(&p2); 23 | stack.push_seqStack(&p3); 24 | stack.push_seqStack(&p4); 25 | stack.push_seqStack(&p5); 26 | 27 | while (stack.get_size() > 0){ 28 | // 访问栈顶元素 29 | auto *person = (Person *)stack.top_seqStack(); 30 | std::cout << "Name:" << person->name << " Age:" << person->age << std::endl; 31 | // 弹出栈顶元素 32 | stack.pop_seqStack(); 33 | } 34 | 35 | // 析构函数调用,释放内存 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /Sorter/Sorter.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by wenhan on 2021/1/31. 3 | // 4 | 5 | #include "Sorter.h" 6 | 7 | // 冒泡排序 8 | // 比较次数为 n(n-1)/2, 移动次数为3n(n-1)/2 9 | void Sorter::bubbleSort(int arr[], int length){ 10 | for (int i = 0; i < length - 1; ++i) { 11 | bool flag = false; 12 | for (int j = length-1; j > i; --j) { 13 | if (arr[j] < arr[j-1]){ 14 | flag = true; 15 | _swap(&arr[j], &arr[j-1]); 16 | } 17 | } 18 | if (!flag){ 19 | break; 20 | } 21 | } 22 | } 23 | 24 | // 选择排序 25 | // 比较次数为 n(n-1)/2, 移动次数为3(n-1) 26 | void Sorter::selectSort(int *arr, int length) { 27 | // 选择排序通过减少交换次数来提升效率 28 | for (int i = 0; i < length; ++i) { 29 | int min = i; 30 | for (int j = i; j < length; ++j) { 31 | if (arr[j] < arr[min]){ 32 | min = j; 33 | } 34 | } 35 | _swap(&arr[i], &arr[min]); 36 | } 37 | } 38 | 39 | // 插入排序 40 | // 最好情况:原始序列正序,需要比较(n-1)次,移动2(n-1)次,时间复杂度O(n) 41 | // 最坏情况:原始序列倒序,需要比较(n-1)(n+2)/2次(2~n求和值),移动(n-1)(n+4)/2次 ((2+1)~(n+1)求和值) 42 | void Sorter::insertSort(int *arr, int length) { 43 | for (int i = 1; i < length; ++i) { 44 | if (arr[i] < arr[i-1]){ 45 | int temp = arr[i]; 46 | int j; 47 | for (j = i-1; j >= 0 && arr[j] > temp; --j) { 48 | arr[j+1] = arr[j]; 49 | } 50 | arr[j+1] = temp; 51 | } 52 | 53 | } 54 | } 55 | 56 | // 希尔排序 57 | void Sorter::shellSort(int *arr, int length) { 58 | int increase = length; 59 | do { 60 | increase = increase/3 + 1; 61 | for (int i = 0; i < increase; ++i) { 62 | for (int j = i+increase; j < length; j+=increase) { 63 | if (arr[j] < arr[j-increase]){ 64 | int temp = arr[j]; 65 | int k; 66 | for (k = j-increase; k >=0 && arr[k] > temp; k-=increase) { 67 | arr[k+increase] = arr[k]; 68 | } 69 | arr[k+increase] = temp; 70 | } 71 | } 72 | } 73 | } while (increase > 1); 74 | 75 | } 76 | 77 | // 快速排序 78 | // 分治法+挖坑填数,找基准数,经过移动使小于基准数的全部在左边,大于基准数的全部在右边 79 | void Sorter::quickSort(int arr[], int start, int end) { 80 | if (start >= end){ 81 | return; 82 | } 83 | int pivotPos = _partition(arr, start, end); 84 | quickSort(arr, start, pivotPos - 1); 85 | quickSort(arr, pivotPos + 1, end); 86 | } 87 | 88 | void Sorter::mergeSort(int *arr, int start, int end, int temp[]) { 89 | if (start >= end){ 90 | return; 91 | } 92 | int mid = start + (end-start)/2; 93 | mergeSort(arr, start, mid, temp); 94 | mergeSort(arr, mid + 1, end, temp); 95 | _merge(arr, start, end, mid, temp); 96 | } 97 | 98 | void Sorter::heapSort(int *arr, int length) { 99 | // 初始化堆,大顶堆 100 | for (int i = length/2-1; i >= 0; --i) { 101 | _adjust(arr, i, length); 102 | } 103 | // 交换堆顶元素和最后一个元素 104 | for (int i = length-1; i >= 0; --i) { 105 | _swap(&arr[0], &arr[i]); 106 | _adjust(arr, 0, i); 107 | } 108 | } 109 | 110 | void Sorter::_swap(int* a, int* b){ 111 | int temp = *a; 112 | *a = *b; 113 | *b = temp; 114 | } 115 | 116 | int Sorter::_partition(int *arr, int start, int end) { 117 | int pivot = arr[start]; 118 | int pivotPos = start; 119 | int i = start, j = end; 120 | while (i < j){ 121 | while (arr[i] <= pivot) i++; 122 | while (arr[j] > pivot) j--; 123 | if (i >= j) break; 124 | _swap(&arr[i], &arr[j]); 125 | } 126 | arr[pivotPos] = arr[j]; 127 | arr[j] = pivot; 128 | return j; 129 | } 130 | 131 | void Sorter::_merge(int *arr, int start, int end, int mid, int *temp) { 132 | int i_start = start; 133 | int j_start = mid + 1; 134 | int i_end = mid; 135 | int j_end = end; 136 | int pos = start; 137 | while (i_start <= i_end && j_start <= j_end){ 138 | if (arr[i_start] < arr[j_start]){ 139 | temp[pos] = arr[i_start]; 140 | i_start++; 141 | pos++; 142 | } else{ 143 | temp[pos] = arr[j_start]; 144 | j_start++; 145 | pos++; 146 | } 147 | } 148 | while (i_start <= i_end){ 149 | temp[pos] = arr[i_start]; 150 | i_start++; 151 | pos ++; 152 | } 153 | while (j_start <= j_end){ 154 | temp[pos] = arr[j_start]; 155 | j_start++; 156 | pos++; 157 | } 158 | for (int i = start; i <= end; ++i) { 159 | arr[i] = temp[i]; 160 | } 161 | 162 | } 163 | 164 | // arr:待调整数组 index: 待调整结点下标 length:数组长度 165 | // 自上向下调整,外围调用从下向上,只有这样才能确保能找到结点正确的位置 166 | void Sorter::_adjust(int *arr, int index, int length) { 167 | while ((2*index+1) < length){ 168 | int lchild = 2*index + 1; 169 | int rchild = lchild + 1; 170 | int maxChild = (rchild < length && arr[rchild] > arr[lchild])?rchild:lchild; 171 | if (arr[index] >= arr[maxChild]) break; 172 | _swap(&arr[index], &arr[maxChild]); 173 | index = maxChild; 174 | } 175 | } -------------------------------------------------------------------------------- /Sorter/Sorter.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by wenhan on 2021/1/31. 3 | // 4 | 5 | #ifndef SORTER_SORTER_H 6 | #define SORTER_SORTER_H 7 | 8 | class Sorter { 9 | public: 10 | static void bubbleSort(int arr[], int length); 11 | 12 | static void selectSort(int arr[], int length); 13 | 14 | static void insertSort(int arr[], int length); 15 | 16 | static void shellSort(int arr[], int length); 17 | 18 | static void quickSort(int arr[], int start, int end); 19 | 20 | static void mergeSort(int arr[], int start, int end, int temp[]); 21 | 22 | static void heapSort(int arr[], int length); 23 | 24 | private: 25 | static void _swap(int* a, int* b); 26 | // 快速排序使用 27 | static int _partition(int arr[], int start, int end); 28 | 29 | // 归并排序使用 30 | static void _merge(int arr[], int start, int end, int mid, int temp[]); 31 | 32 | // 堆排序使用 33 | static void _adjust(int arr[], int index, int length); 34 | }; 35 | 36 | 37 | #endif //SORTER_SORTER_H 38 | -------------------------------------------------------------------------------- /Sorter/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "Sorter.h" 4 | #include 5 | 6 | // timeb 解释:https://www.cnblogs.com/wanghao111/archive/2009/05/25/1489018.html 7 | 8 | const int MAX_SIZE = 100000; 9 | void printArray(int arr[], int length){ 10 | for (int i = 0; i < length; ++i) { 11 | std::cout << arr[i] << " "; 12 | } 13 | std::cout << std::endl; 14 | } 15 | 16 | long getSystemTime(){ 17 | struct timeb tb{}; 18 | ftime(&tb); 19 | return tb.time * 1000 + tb.millitm; 20 | } 21 | 22 | int main() { 23 | 24 | int* arr = new int[MAX_SIZE]; 25 | std::srand((unsigned int)time(nullptr)); 26 | for (int i = 0; i < MAX_SIZE; ++i) { 27 | arr[i] = std::rand() % MAX_SIZE; 28 | } 29 | std::cout << "排序前:" << std::endl; 30 | // printArray(arr, MAX_SIZE); 31 | long t_start = getSystemTime(); 32 | Sorter::bubbleSort(arr, MAX_SIZE); 33 | long t_end = getSystemTime(); 34 | std::cout << "冒泡排序" << MAX_SIZE << "个元素,所需时间:" << (t_end - t_start) << std::endl; 35 | std::cout << "排序后:" << std::endl; 36 | // printArray(arr, MAX_SIZE); 37 | 38 | 39 | for (int i = 0; i < MAX_SIZE; ++i) { 40 | arr[i] = std::rand() % MAX_SIZE; 41 | } 42 | 43 | std::cout << "排序前:" << std::endl; 44 | // printArray(arr, MAX_SIZE); 45 | t_start = getSystemTime(); 46 | Sorter::selectSort(arr, MAX_SIZE); 47 | t_end = getSystemTime(); 48 | std::cout << "选择排序" << MAX_SIZE << "个元素,所需时间:" << (t_end - t_start) << std::endl; 49 | std::cout << "排序后:" << std::endl; 50 | // printArray(arr, MAX_SIZE); 51 | 52 | for (int i = 0; i < MAX_SIZE; ++i) { 53 | arr[i] = std::rand() % MAX_SIZE; 54 | } 55 | std::cout << "排序前:" << std::endl; 56 | // printArray(arr, MAX_SIZE); 57 | t_start = getSystemTime(); 58 | Sorter::insertSort(arr, MAX_SIZE); 59 | t_end = getSystemTime(); 60 | std::cout << "插入排序" << MAX_SIZE << "个元素,所需时间:" << (t_end - t_start) << std::endl; 61 | std::cout << "排序后:" << std::endl; 62 | // printArray(arr, MAX_SIZE); 63 | 64 | for (int i = 0; i < MAX_SIZE; ++i) { 65 | arr[i] = std::rand() % MAX_SIZE; 66 | } 67 | std::cout << "排序前:" << std::endl; 68 | // printArray(arr, MAX_SIZE); 69 | t_start = getSystemTime(); 70 | Sorter::shellSort(arr, MAX_SIZE); 71 | t_end = getSystemTime(); 72 | std::cout << "希尔排序" << MAX_SIZE << "个元素,所需时间:" << (t_end - t_start) << std::endl; 73 | std::cout << "排序后:" << std::endl; 74 | // printArray(arr, MAX_SIZE); 75 | 76 | for (int i = 0; i < MAX_SIZE; ++i) { 77 | arr[i] = std::rand() % MAX_SIZE; 78 | } 79 | std::cout << "排序前:" << std::endl; 80 | // printArray(arr, MAX_SIZE); 81 | t_start = getSystemTime(); 82 | Sorter::quickSort(arr, 0, MAX_SIZE-1); 83 | t_end = getSystemTime(); 84 | std::cout << "快速排序" << MAX_SIZE << "个元素,所需时间:" << (t_end - t_start) << std::endl; 85 | std::cout << "排序后:" << std::endl; 86 | // printArray(arr, MAX_SIZE); 87 | 88 | for (int i = 0; i < MAX_SIZE; ++i) { 89 | arr[i] = std::rand() % MAX_SIZE; 90 | } 91 | int* temp = new int[MAX_SIZE]; 92 | std::cout << "排序前:" << std::endl; 93 | // printArray(arr, MAX_SIZE); 94 | t_start = getSystemTime(); 95 | Sorter::mergeSort(arr, 0, MAX_SIZE-1, temp); 96 | t_end = getSystemTime(); 97 | std::cout << "归并排序" << MAX_SIZE << "个元素,所需时间:" << (t_end - t_start) << std::endl; 98 | std::cout << "排序后:" << std::endl; 99 | // printArray(arr, MAX_SIZE); 100 | 101 | for (int i = 0; i < MAX_SIZE; ++i) { 102 | arr[i] = std::rand() % MAX_SIZE; 103 | } 104 | std::cout << "排序前:" << std::endl; 105 | // printArray(arr, MAX_SIZE); 106 | t_start = getSystemTime(); 107 | Sorter::heapSort(arr, MAX_SIZE); 108 | t_end = getSystemTime(); 109 | std::cout << "堆排序" << MAX_SIZE << "个元素,所需时间:" << (t_end - t_start) << std::endl; 110 | std::cout << "排序后:" << std::endl; 111 | // printArray(arr, MAX_SIZE); 112 | 113 | delete[] temp; 114 | delete[] arr; 115 | return 0; 116 | } 117 | --------------------------------------------------------------------------------