[数据结构]Binary_tree | Binary_search_tree | avl_tree
2016-05-19 20:25
423 查看
//Record.h #include<iostream> using namespace std; class Record { public: Record(int x = 0, int y = 0); int the_key() const; private: int key; int other; }; bool operator == (const Record &x, const Record &y); bool operator > (const Record &x, const Record &y); bool operator < (const Record &x, const Record &y); ostream & operator << (ostream &output, Record &x);
这个Record是把树的内容打包起来,作为一个类,方便日后对树内容的修改。
//Record.cpp #include "Record.h" Record::Record(int x, int y) { key = x; other = y; } int Record::the_key() const { return key; } bool operator == (const Record &x, const Record &y) { return x.the_key() == y.the_key(); } bool operator > (const Record &x, const Record &y) { return x.the_key() > y.the_key(); } bool operator < (const Record &x, const Record &y) { return x.the_key() < y.the_key(); } ostream & operator << (ostream &output, Record &x) { output << x.the_key(); output << " "; return output; }
//Binary_tree.h enum Error_code { success, not_present, duplicate_error }; enum Balance_factor { left_higher, equal_height, right_higher }; #include"Record.h" template<class Entry> struct Binary_node { Entry data; Binary_node<Entry> *left_child; Binary_node<Entry> *right_child; Binary_node(); Binary_node(const Entry &x); //Inherit used: virtual void set_balance(Balance_factor b);<span style="white-space:pre"> </span>//虚函数,因为这个函数在这个父类里没有意义所以设为空函数即可 virtual Balance_factor get_balance() const;<span style="white-space:pre"> </span>//这里的虚函数主要是为了avl_node在继承这个类之后可以通过动态绑定 <span style="white-space:pre"> </span>//直接使用left_child和right_child去调用avl_tree中的一些方法 }; template<class Entry> inline Binary_node<Entry>::Binary_node() { left_child = nullptr; right_child = nullptr; } template<class Entry> inline Binary_node<Entry>::Binary_node(const Entry & x) { data = x; left_child = nullptr; right_child = nullptr; } template<class Entry> inline void Binary_node<Entry>::set_balance(Balance_factor b) { } template<class Entry> inline Balance_factor Binary_node<Entry>::get_balance() const { return equal_height; } template<class Entry> class Binary_tree { public: //Basic function: Binary_tree(); bool empty(); void preorder(void(*visit)(Entry &)); void inorder(void(*visit)(Entry &)); void postorder(void(*visit)(Entry &)); int size() ; void clear(); int height(); void insert(const Entry &item); Binary_node<Entry> *Get_root(); //Safety functions: Binary_tree(const Binary_tree<Entry> &original); Binary_tree &operator=(const Binary_tree<Entry> &original); ~Binary_tree(); protected: Binary_node<Entry> *root; int count; void recursive_preorder(Binary_node<Entry> *sub_root, void(*visit)(Entry &)); void recursive_inorder(Binary_node<Entry> *sub_root, void(*visit)(Entry &)); void recursive_postorder(Binary_node<Entry> *sub_root,void (*visit)(Entry &)); int recursive_height(Binary_node <Entry> *sub_root); int recursive_size(Binary_node<Entry> *sub_root); void recursive_clear(Binary_node <Entry> *sub_root); void recursive_insert(Binary_node<Entry> *sub_root,Binary_node<Entry> *node); Binary_node<Entry>* creat(Binary_node<Entry> *sub_root); };
//Binary_tree.cpp #include"Binary_tree.h" #include<iostream> #include<stack> using namespace std; template<class Entry> Binary_tree<Entry>::Binary_tree() { root = NULL; count = 0; } template<class Entry> void Binary_tree<Entry>::recursive_preorder(Binary_node<Entry>* sub_root, void(*visit)(Entry &)) { if (sub_root) { (*visit)(sub_root->data); recursive_preorder(sub_root->left_child, visit); recursive_preorder(sub_root->right_child, visit); } } template<class Entry> void Binary_tree<Entry>::recursive_inorder(Binary_node<Entry>* sub_root, void(*visit)(Entry &)) { if (sub_root) { recursive_inorder(sub_root->left_child,visit); (*visit)(sub_root->data); recursive_inorder(sub_root->right_child, visit); } } template<class Entry> void Binary_tree<Entry>::recursive_postorder(Binary_node<Entry>* sub_root, void(*visit)(Entry &)) { if (sub_root) { recursive_postorder(sub_root->left_child, visit); recursive_postorder(sub_root->right_child, visit); (*visit)(sub_root->data); } } template<class Entry> int Binary_tree<Entry>::recursive_height(Binary_node<Entry>* sub_root) { if (!sub_root)return 0; int left = recursive_height(sub_root->left_child); int right = recursive_height(sub_root->right_child); if (left > right) return (left + 1); else return (right + 1); } template<class Entry> int Binary_tree<Entry>::recursive_size(Binary_node<Entry>* sub_root) { if (!sub_root)return 0; int left = recursive_size(sub_root->left_child); int right = recursive_size(sub_root->right_child); return (left + right + 1); } template<class Entry> void Binary_tree<Entry>::recursive_clear(Binary_node<Entry>* sub_root) { if (sub_root) { recursive_clear(sub_root->left_child); recursive_clear(sub_root->right_child); delete sub_root; } } template<class Entry> void Binary_tree<Entry>::recursive_insert(Binary_node<Entry> *sub_root,Binary_node<Entry> *node) { if (node->data >= sub_root->data) { if (sub_root->right_child == NULL) sub_root->right_child = new Binary_node<Entry>(node->data); else recursive_insert(sub_root->right_child, node); } else { if (sub_root->left_child == NULL) sub_root->left_child = new Binary_node<Entry>(node->data); else recursive_insert(sub_root->left_child, node); } } template<class Entry> Binary_node<Entry> * Binary_tree<Entry>::creat(Binary_node<Entry>* sub_root) { if (!sub_root)return NULL; Binary_node<Entry> *tmp_root = new Binary_node<Entry>(sub_root->data); tmp_root->left_child = creat(sub_root->left_child); tmp_root->right_child = creat(sub_root->right_child); return tmp_root; } template<class Entry> bool Binary_tree<Entry>::empty() { return (root==NULL); } template<class Entry> void Binary_tree<Entry>::preorder(void(*visit)(Entry &)) { recursive_preorder(root, visit); } template<class Entry> void Binary_tree<Entry>::inorder(void(*visit)(Entry &)) { recursive_inorder(root, visit); } template<class Entry> void Binary_tree<Entry>::postorder(void(*visit)(Entry &)) { recursive_postorder(root, visit); } template<class Entry> int Binary_tree<Entry>::size() { return recursive_size(root); } template<class Entry> void Binary_tree<Entry>::clear() { recursive_clear(root); root = nullptr; count = 0; } template<class Entry> int Binary_tree<Entry>::height() { return recursive_height(root); } template<class Entry> void Binary_tree<Entry>::insert(const Entry & item) { if (empty()) { root = new Binary_node<Entry>(item); count++; return; } stack<int>number; int tmpcount = size(); while (tmpcount > 0) { if (tmpcount % 2 == 0)number.push(2); else number.push(1); tmpcount = (tmpcount - 1) / 2; } int direction = 0; Binary_node<Entry> *p = root; while (number.size() > 1) { direction = number.top(); if (direction == 2)p = p->right_child; if (direction == 1)p = p->left_child; number.pop(); } direction = number.top(); if (direction == 2)p->right_child=new Binary_node<Entry>(item); if (direction == 1)p->left_child = new Binary_node<Entry>(item); count++; } template<class Entry> Binary_node<Entry>* Binary_tree<Entry>::Get_root() { return root; } template<class Entry> Binary_tree<Entry>::Binary_tree(const Binary_tree<Entry>& original) { Binary_node<Entry> * original_root = original.Get_root(); root = creat(original_root); } template<class Entry> Binary_tree<Entry> & Binary_tree<Entry>::operator=(const Binary_tree<Entry>& original) { Binary_node<Entry> * original_root = original.Get_root(); if (root == original_root)return; clear(); Binary_tree(original); } template<class Entry> Binary_tree<Entry>::~Binary_tree() { clear(); }
//Binary_search_tree.h #include"Binary_tree.cpp" template<class Record> class Binary_search_tree:public Binary_tree<Record> { public: Binary_search_tree(); Error_code insert(const Record &item); Error_code remove(const Record &item); Error_code search(Record &item); private: Error_code recursive_insert(Binary_node<Record> *&sub_root, const Record &item); Binary_node<Record> * recursive_search(Binary_node<Record> *&sub_root, const Record &item); Error_code search_and_destroy(Binary_node <Record> *&sub_root, const Record &item); Error_code destroy(Binary_node<Record> *&sub_root); };
//Binary_search_tree.cpp #include"Binary_search_tree.h" #include<iostream> using namespace std; template<class Record> Binary_search_tree<Record>::Binary_search_tree() { count = 0; root = NULL; } template<class Record> Error_code Binary_search_tree<Record>::insert(const Record & item) { if (recursive_insert(root, item) == success) { count++; return success; } else return duplicate_error; } template<class Record> Error_code Binary_search_tree<Record>::remove(const Record & item) { if (search_and_destroy(root, item) == success) { count--; return success; } else return not_present; } template<class Record> Error_code Binary_search_tree<Record>::search(Record & item) { Binary_node<Record> *p = recursive_search(root, item); if (p == NULL)return not_present; else { item = p->data; return success; } } template<class Record> Error_code Binary_search_tree<Record>::recursive_insert(Binary_node<Record>*& sub_root, const Record & item) { if (!sub_root) { sub_root = new Binary_node<Record>(item); return success; } else if (sub_root->data > item)return recursive_insert(sub_root->left_child, item); else if (sub_root->data < item)return recursive_insert(sub_root->right_child, item); else return duplicate_error; } template<class Record> Binary_node<Record> * Binary_search_tree<Record>::recursive_search(Binary_node<Record>*& sub_root, const Record & item) { if (sub_root == NULL || sub_root->data == item)return sub_root; else if (sub_root->data > item)return recursive_insert(sub_root->left_child, item); else if (sub_root->data < item)return recursive_insert(sub_root->right_child, item); } template<class Record> Error_code Binary_search_tree<Record>::search_and_destroy(Binary_node<Record>*& sub_root, const Record & item) { if (sub_root == NULL || sub_root->data == item) return destroy(sub_root); else if (sub_root->data > item)return destory(sub_root->left_child); else if (sub_root->data < item)return destory(sub_root->right_child); } template<class Record> Error_code Binary_search_tree<Record>::destroy(Binary_node<Record>*& sub_root) { if (sub_root == NULL)return not_present; Binary_node<Entry> *to_delete = sub_root; if (sub_root->left_child == NULL) sub_root = sub_root->right_child; else if (sub_root->right_child == NULL) sub_root = sub_root->left_child; else { to_delete = sub_root->left_child; Binary_node<Entry> *parent = sub_root; while (!to_delete->right_child) { parent = to_delete; to_delete = to_delete->right_child; } sub_root->data = to_delete->data; if (parent == sub_root)sub_root->left_child = to_delete->left_child; //Special condition:no right_child under to_delete else parent->right_child = to_delete->right_child; } delete to_delete; return success; }
//AVL_tree.h #include"Binary_search_tree.cpp" template<class Record> struct AVL_node :public Binary_node<Record> { Balance_factor balance; AVL_node(); AVL_node(const Record &x); void set_balance(Balance_factor b); Balance_factor get_balance()const; }; template<class Record> inline AVL_node<Record>::AVL_node() { balance = equal_height; } template<class Record> inline AVL_node<Record>::AVL_node(const Record & x) { data = x; balance = equal_height; } template<class Record> inline void AVL_node<Record>::set_balance(Balance_factor b) { balance = b; } template<class Record> inline Balance_factor AVL_node<Record>::get_balance() const { return balance; } template<class Record> class AVL_tree:public Binary_search_tree<Record> { public: Error_code insert(const Record &new_data); Error_code remove(Record &old_data); private: Error_code avl_insert(Binary_node<Record> * &sub_root, const Record &new_data, bool &taller); void rotate_left(Binary_node<Record> * &sub_root); void rotate_right(Binary_node<Record> * &sub_root); void right_balance(Binary_node<Record> * &sub_root); void left_balance(Binary_node<Record> * &sub_root); //add for remove Error_code avl_remove(Binary_node<Record> * &sub_root, Record &new_data, bool &shorter); bool right_balance2(Binary_node<Record> * &sub_root); bool left_balance2(Binary_node<Record> * &sub_root); };
//AVL_tree.cpp #include "AVL_Tree.h" template<class Record> Error_code AVL_tree<Record>::insert(const Record & new_data) { bool taller; return avl_insert(root, new_data, taller); } template<class Record> Error_code AVL_tree<Record>::remove(Record & old_data) { bool shorter = true; return avl_remove(root, old_data, shorter); } template<class Record> Error_code AVL_tree<Record>::avl_insert(Binary_node<Record>*& sub_root, const Record & new_data, bool & taller) { if (sub_root == NULL) { sub_root = new AVL_node<Record>(new_data); taller = true; return success; } else if (sub_root->data == new_data) { taller = false; return duplicate_error; } else if (sub_root->data > new_data) { Error_code result = avl_insert(sub_root->left_child, new_data, taller); if (taller == true) { switch (sub_root->get_balance()) { case left_higher: left_balance(sub_root); taller = false; break; case equal_height: sub_root->set_balance(left_higher); break; case right_higher: sub_root->set_balance(equal_height); taller = false; break; } } return result; } else { Error_code result = avl_insert(sub_root->right_child, new_data, taller); if (taller == true) { switch (sub_root->get_balance()) { case left_higher: sub_root->set_balance(equal_height); taller = false; break; case equal_height: sub_root->set_balance(right_higher); break; case right_higher: right_balance(sub_root); taller = false; break; } } return result; } } template<class Record> void AVL_tree<Record>::rotate_left(Binary_node<Record>*& sub_root) { if (sub_root == nullptr || sub_root->right_child == nullptr) cout << "WARNING:program error detected in rotate left" << endl; else { Binary_node<Record> *right_tree = sub_root->right_child; sub_root->right_child = right_tree->left_child; right_tree->left_child = sub_root; sub_root = right_tree; } } template<class Record> void AVL_tree<Record>::rotate_right(Binary_node<Record>*& sub_root) { if (sub_root == nullptr || sub_root->left_child == nullptr) cout << "WARNING:program error detected in rotate right" << endl; else { Binary_node<Record> *left_tree = sub_root->left_child; sub_root->left_child = left_tree->right_child; left_tree->right_child = sub_root; sub_root = left_tree; } } template<class Record> void AVL_tree<Record>::right_balance(Binary_node<Record>*& sub_root) { Binary_node<Record> *&right_tree = sub_root->right_child; switch (right_tree->get_balance()) { case right_higher: sub_root->set_balance(equal_height); right_tree->set_balance(equal_height); rotate_left(sub_root); break; case equal_height: cout << "WARNING:program error detected in right balance" << endl; break; case left_higher: Binary_node<Record> *sub_tree = right_tree->left_child; switch (sub_tree->get_balance()) { case equal_height: sub_root->set_balance(equal_height); right_tree->set_balance(equal_height); break; case left_higher: sub_root->set_balance(equal_height); right_tree->set_balance(right_higher); break; case right_higher: sub_root->set_balance(left_higher); right_tree->set_balance(equal_height); break; } sub_tree->set_balance(equal_height); rotate_right(right_tree); rotate_left(sub_root); break; } } template<class Record> void AVL_tree<Record>::left_balance(Binary_node<Record>*& sub_root) { Binary_node<Record> *&left_tree = sub_root->left_child; switch (left_tree->get_balance()) { case left_higher: sub_root->set_balance(equal_height); left_tree->set_balance(equal_height); rotate_right(sub_root); break; case equal_height: cout << "WARNING:program error detected in left balance" << endl; break; case right_higher: Binary_node<Record> *sub_tree = left_tree->right_child; switch (sub_tree->get_balance()) { case equal_height: sub_root->set_balance(equal_height); left_tree->set_balance(equal_height); break; case right_higher: sub_root->set_balance(equal_height); left_tree->set_balance(left_higher); break; case left_higher: sub_root->set_balance(right_higher); left_tree->set_balance(equal_height); break; } sub_tree->set_balance(equal_height); rotate_left(left_tree); rotate_right(sub_root); break; } } template<class Record> Error_code AVL_tree<Record>::avl_remove(Binary_node<Record>*& sub_root, Record & new_data, bool & shorter) { Error_code result; if (sub_root == NULL) { shorter = false; return not_present; } else if (new_data == sub_root->data) { Binary_node<Record>*to_delete = sub_root; if (sub_root->right_child == NULL) { sub_root = sub_root->left_child; shorter = true; delete to_delete; return success; } else if (sub_root->left_child == NULL) { sub_root = sub_root->right_child; shorter = true; delete to_delete; return success; } else { to_delete = sub_root->left_child; Binary_node<Record> *parent = sub_root; while (!to_delete->right_child) { parent = to_delete; to_delete = to_delete->left_child; } sub_root->data = to_delete->data; new_data = to_delete->data; delete to_delete; } } if (new_data < sub_root->data) { result = avl_remove(sub_root->left_child, new_data, shorter); if (shorter == true) { switch (sub_root->get_balance()) { case left_higher: sub_root->set_balance(equal_height); break; case equal_height: sub_root->set_balance(right_higher); break; case right_higher: shorter = right_balance2(sub_root); break; } } } if (new_data > sub_root->data) { result = avl_remove(sub_root->right_child, new_data, shorter); if (shorter == true) { switch (sub_root->get_balance()) { case left_higher: shorter=left_balance2(sub_root); break; case equal_height: break; sub_root->set_balance(left_higher); case right_higher: sub_root->set_balance(equal_height); break; } } } return result; } template<class Record> bool AVL_tree<Record>::right_balance2(Binary_node<Record>*& sub_root) { bool shorter; Binary_node<Record> *&right_tree = sub_root->right_child; switch (right_tree->get_balance()) { case right_higher: //RR height-- sub_root->set_balance(equal_height); right_tree->set_balance(equal_height); rotate_left(sub_root); shorter = true; break; case equal_height: //R- height doesn't change right_tree->set_balance(left_higher); rotate_left(sub_root); shorter = false; break; case left_higher: //RL height-- Binary_node<Record> *sub_tree = right_tree->left_child; switch (sub_tree->get_balance()) { case equal_height: sub_root->set_balance(equal_height); right_tree->set_balance(equal_height); break; case left_higher: sub_root->set_balance(equal_height); right_tree->set_balance(right_higher); break; case right_higher: sub_root->set_balance(left_higher); right_tree->set_balance(equal_height); break; } sub_tree->set_balance(equal_height); rotate_right(right_tree); rotate_left(sub_root); shorter = true; break; } return shorter; } template<class Record> bool AVL_tree<Record>::left_balance2(Binary_node<Record>*& sub_root) { bool shorter; Binary_node<Record> *&left_tree = sub_root->left_child; switch (left_tree->get_balance()) { case left_higher: //LL height-- sub_root->set_balance(equal_height); left_tree->set_balance(equal_height); rotate_right(sub_root); shorter = true; break; case equal_height: //L- height doesn't change left_tree->set_balance(right_higher); rotate_right(sub_root); shorter = false; break; case right_higher: //LR height-- Binary_node<Record> *sub_tree = left_tree->left_child; switch (sub_tree->get_balance()) { case equal_height: sub_root->set_balance(equal_height); left_tree->set_balance(equal_height); break; case left_higher: left_tree->set_balance(equal_height); sub_root->set_balance(right_higher); break; case right_higher: sub_root->set_balance(equal_height); left_tree->set_balance(left_higher); break; } sub_tree->set_balance(equal_height); rotate_left(left_tree); rotate_right(sub_root); shorter = true; break; } return shorter; }
/****************************************************************************************************************************************/
下面放一个我的驱动函数main可以用来测试代码,有三个,两个被我注释掉了,分别是测试Binary_tree、Binary_search_tree和avl_tree:
//main.cpp #include"AVL_Tree.cpp" #include<iostream> #include<string> using namespace std; template<class Entry> void print(Entry &item) { cout << item << ' '; } void UI() { cout << "***************************Binary_tree*********************************" << endl; cout << "MENU:" << endl; cout << "1.Preorder ." << endl; cout << "2.Inorder." << endl; cout << "3.Postorder." << endl; cout << "4.Size." << endl; cout << "5.Clear." << endl; cout << "6.Height." << endl; cout << "7.Insert." << endl; cout << "0.Exit." << endl; } void flash() { system("pause"); system("cls"); UI(); } int Get_command() { cout << "Please choose one of the number above." << endl; string tmp; int command; cin >> tmp; command = tmp[0] - '0'; while (command != 0 && command != 1 && command != 2 && command != 3 && command != 4 && command != 5 && command != 6 && command != 7) { cout << "Invalid command,please enter again." << endl; cin >> tmp; command = tmp[0] - '0'; } return command; } //Binary_tree's main //void main() { // UI(); // Binary_tree<int> tmp; // int command; // for (int i = 0; i < 11; i++)tmp.insert(i); // do // { // command = Get_command(); // switch (command) // { // case 1: { // cout << "This is the preorder tranverse." << endl; // tmp.preorder(print); // flash(); // break; // } // case 2: { // cout << "This is the inorder tranverse." << endl; // tmp.inorder(print); // flash(); // break; // } // case 3: { // cout << "This is the postorder tranverse." << endl; // tmp.postorder(print); // flash(); // break; // } // case 4: { // cout << "The size of this Binary_tree is : "; // cout << tmp.size() << endl; // flash(); // break; // } // case 5: { // tmp.clear(); // cout << "Clear Success!" << endl; // flash(); // break; // } // case 6: { // cout << "The height of this Binary_tree is : "; // cout << tmp.height() << endl; // flash(); // break; // } // case 7: { // cout << "Please enter the item you want to insert." << endl; // int item; // cin >> item; // tmp.insert(item); // cout << "Insert success." << endl; // flash(); // break; // } // case 0: { // cout << "You'll exit the programm later." << endl; // system("pause"); // return ; // } // default: // break; // } // } while (command); //} //Binary_search_tree's main //void main() { // UI(); // Binary_search_tree<int> tmp; // int command; // for (int i = 0; i < 10; i++)tmp.insert(i); // do // { // command = Get_command(); // switch (command) // { // case 1: { // cout << "This is the preorder tranverse." << endl; // tmp.preorder(print); // flash(); // break; // } // case 2: { // cout << "This is the inorder tranverse." << endl; // tmp.inorder(print); // flash(); // break; // } // case 3: { // cout << "This is the postorder tranverse." << endl; // tmp.postorder(print); // flash(); // break; // } // case 4: { // cout << "The size of this Binary_tree is : "; // cout << tmp.size() << endl; // flash(); // break; // } // case 5: { // tmp.clear(); // cout << "Clear Success!" << endl; // flash(); // break; // } // case 6: { // cout << "The height of this Binary_tree is : "; // cout << tmp.height() << endl; // flash(); // break; // } // case 7: { // cout << "Please enter the item you want to insert." << endl; // int item; // cin >> item; // tmp.insert(item); // cout << "Insert success." << endl; // flash(); // break; // } // case 0: { // cout << "You'll exit the programm later." << endl; // system("pause"); // return; // } // default: // break; // } // } while (command); //} //avl_tree's main: void main() { UI(); AVL_tree<int>tmp; int command; for (int i = 0; i < 10; i++) { tmp.insert(i); } do { command = Get_command(); switch (command) { case 1: { cout << "This is the preorder tranverse." << endl; tmp.preorder(print); cout << endl; flash(); break; } case 2: { cout << "This is the inorder tranverse." << endl; tmp.inorder(print); cout << endl; flash(); break; } case 3: { cout << "This is the postorder tranverse." << endl; tmp.postorder(print); cout << endl; flash(); break; } case 4: { cout << "The size of this Binary_tree is : "; cout << tmp.size() << endl; flash(); break; } case 5: { tmp.clear(); cout << "Clear Success!" << endl; flash(); break; } case 6: { cout << "The height of this Binary_tree is : "; cout << tmp.height() << endl; flash(); break; } case 7: { cout << "Please enter the item you want to insert." << endl; int item; cin >> item; tmp.insert(item); cout << "Insert success." << endl; flash(); break; } case 0: { cout << "You'll exit the programm later." << endl; system("pause"); return; } default: break; } } while (command); }
相关文章推荐
- HYSBZ 1012
- 【数据结构】串 YTU 2297 KMP算法(3)next
- 【数据结构】串 YTU 2296 KMP算法(2)next
- 【数据结构】串 YTU 2295 KMP算法(1)next
- 数据结构与算法分析(3)算法分析
- 数据结构之红黑树
- Redis各种数据结构内存占用测试
- MySQL索引背后的数据结构及算法原理
- C/C++,java 数据结构---线性链表存储数据:获取数据慢,增删快
- java 数据结构和泛型
- 数据结构之排序
- 【数据结构】平衡二叉树—AVL树
- Java 容器类内部使用的数据结构
- 数据结构提纲
- Windows内核中的数据结构与函数调用
- 链表List
- 《Java数据结构和算法(第二版)》读书笔记
- POJ 3450 3080 后缀数组+二分
- 为什么我认为数据结构与算法对前端开发很重要?
- 【41】递增数组判断是否存在两个树等于给定值