包含了2个文件ArrayList.hpp和Main.cpp。写这份代码不仅仅是为了练习实现数据结构,还为了练习模版和函数重载。遇到过一些挫折,但是都一一解决了,感觉收获还是挺多的。
1 #ifndef __ARRAY_LIST_HPP__ 2 #define __ARRAY_LIST_HPP__ 3 4 #include "stdlib.h" 5 6 template <class Type> class ArrayList 7 { 8 public: 9 const static size_t INVALID_ARRAYLIST_INDEX = -1; 10 11 typedef bool (*VisitFun)(const Type &elem); 12 typedef bool (*CompareFunEQ)(const Type &left, const Type &right); 13 typedef bool (*CompareFunLT)(const Type &left, const Type &rihgt); 14 typedef bool (*CompareFunGT)(const Type &left, const Type &right); 15 16 ArrayList(size_t capacity = CAPACITY_DEFAULT_SIZE); 17 ArrayList(const ArrayList &array_list); 18 ~ArrayList(); 19 20 void Clear() { m_size = 0; } 21 void Empty() { return 0 == m_size; } 22 size_t Size() { return m_size; } 23 size_t Capacity() { return m_capacity; } 24 25 bool GetElem(size_t index, Type &out_elem); 26 bool LocateElem(const Type &elem, size_t &out_index, CompareFunEQ compare_fun = ArrayList::EQ); 27 bool PriorElem(const Type &cur_elem, Type &out_elem); 28 bool NextElem(const Type &cur_elem, Type &out_elem); 29 bool Insert(size_t index, const Type &elem); 30 bool Delete(size_t index, Type &out_elem); 31 void Traverse(VisitFun visist_fun); 32 private: 33 void destroy(); 34 bool CheckCapacitySize(); 35 36 static bool EQ(const Type &left, const Type &right) { return !(left < right || right < left); } 37 static bool LT(const Type &left, const Type &right) { return left < right; } 38 static bool GT(const Type &left, const Type &right) { return !(left < right) && (left < right || right < left); } 39 40 Type *m_elem_list; 41 size_t m_size; 42 size_t m_capacity; 43 44 static const size_t CAPACITY_DEFAULT_SIZE = 30; 45 const static size_t CAPACITY_INCREASE_SIZE = 10; 46 }; 47 48 template <class Type> 49 ArrayList<Type>::ArrayList(size_t capacity) : m_elem_list(NULL), m_size(0), m_capacity(capacity) 50 { 51 m_elem_list = new Type[m_capacity]; 52 } 53 54 template <class Type> 55 ArrayList<Type>::~ArrayList() 56 { 57 if (NULL != m_elem_list) delete m_elem_list; 58 59 m_elem_list = NULL; 60 m_size = 0; 61 m_capacity = 0; 62 } 63 64 template <class Type> 65 ArrayList<Type>::ArrayList(const ArrayList<Type> &array_list) : m_elem_list(NULL), m_size(0), m_capacity(0) 66 { 67 m_elem_list = new Type[array_list.Capacity()]; 68 if (NULL == m_elem_list) return false; 69 70 m_size = array_list.Size(); 71 m_capacity = array_list.Capacity(); 72 return true; 73 } 74 75 template <class Type> 76 bool ArrayList<Type>::GetElem(size_t index, Type &out_elem) 77 { 78 if (NULL != m_elem_list && index >= m_size) return false; 79 80 out_elem = m_elem_list[index]; 81 return true; 82 } 83 84 template <class Type> 85 bool ArrayList<Type>::LocateElem(const Type &elem, size_t &out_index, CompareFunEQ compare_fun) 86 { 87 if (NULL != m_elem_list && NULL != compare_fun) 88 { 89 for (size_t i = 0; i < m_size; ++ i) 90 { 91 if (compare_fun(elem, m_elem_list[i])) 92 { 93 out_index = i; 94 return true; 95 } 96 } 97 } 98 99 return false; 100 } 101 102 template <class Type> 103 bool ArrayList<Type>::PriorElem(const Type &cur_elem, Type &out_elem) 104 { 105 if (NULL != m_elem_list && m_size > 1) 106 { 107 size_t cur_elem_index = INVALID_ARRAYLIST_INDEX; 108 if (this->LocateElem(cur_elem, cur_elem_index)) 109 { 110 if (cur_elem_index < m_size && cur_elem_index > 0) 111 { 112 out_elem = m_elem_list[cur_elem_index - 1]; 113 return true; 114 } 115 } 116 } 117 118 return false; 119 } 120 121 template <class Type> 122 bool ArrayList<Type>::NextElem(const Type &cur_elem, Type &out_elem) 123 { 124 if (NULL != m_elem_list && m_size > 1) 125 { 126 size_t cur_elem_index = INVALID_ARRAYLIST_INDEX; 127 if (this->LocateElem(cur_elem, cur_elem_index, ArrayList::EQ)) 128 { 129 if (cur_elem_index < m_size - 1) 130 { 131 out_elem = m_elem_list[cur_elem_index + 1]; 132 return true; 133 } 134 } 135 } 136 137 return false; 138 } 139 140 template <class Type> 141 bool ArrayList<Type>::Insert(size_t index, const Type &elem) 142 { 143 if (NULL != m_elem_list) 144 { 145 if (this->CheckCapacitySize()) 146 { 147 if (0 == m_size) 148 { 149 m_elem_list[0] = elem; 150 ++ m_size; 151 return true; 152 } 153 else if (index < m_size) 154 { 155 for (size_t i = m_size; i > index; -- i) 156 { 157 m_elem_list[i] = m_elem_list[i - 1]; 158 } 159 160 m_elem_list[index] = elem; 161 ++ m_size; 162 return true; 163 } 164 } 165 } 166 167 return false; 168 } 169 170 template <class Type> 171 bool ArrayList<Type>::Delete(size_t index, Type &out_elem) 172 { 173 if (NULL != m_elem_list && index < m_size) 174 { 175 if (index == m_size - 1) 176 { 177 -- m_size; 178 return true; 179 } 180 else 181 { 182 for (size_t i = index; i < m_size - 1; ++ i) 183 { 184 m_elem_list[i] = m_elem_list[i + 1]; 185 } 186 187 -- m_size; 188 return true; 189 } 190 } 191 192 return false; 193 } 194 195 template <class Type> 196 bool ArrayList<Type>::CheckCapacitySize() 197 { 198 if (NULL == m_elem_list) return false; 199 200 if (m_size >= m_capacity) 201 { 202 if (m_capacity + CAPACITY_INCREASE_SIZE > INVALID_ARRAYLIST_INDEX) return false; 203 204 Type *tmp_elem_list = new Type[m_capacity + CAPACITY_INCREASE_SIZE]; 205 if (NULL == tmp_elem_list) return false; 206 207 memcpy(tmp_elem_list, m_elem_list, sizeof(Type) * m_size); 208 delete m_elem_list; m_elem_list = tmp_elem_list; 209 m_capacity = m_capacity + CAPACITY_INCREASE_SIZE; 210 return true; 211 } 212 else 213 { 214 return true; 215 } 216 } 217 218 template <class Type> 219 void ArrayList<Type>::Traverse(VisitFun visit_fun) 220 { 221 if (NULL != m_elem_list && NULL != visit_fun && m_size > 0) 222 { 223 for (size_t i = 0; i < m_size; ++ i) 224 { 225 if (!visit_fun(m_elem_list[i])) 226 { 227 break; 228 } 229 } 230 } 231 } 232 233 #endif // __ARRAY_LIST_HPP__
// Main.cpp 用于测试


1 #include "ArrayList.hpp" 2 #include <time.h> 3 #include <stdlib.h> 4 #include <iostream> 5 static const int TEST_ARRAY_LIST_ELEM_COUNT = 5; 6 7 template <class Type> 8 bool VisistArrayList(const Type &elem) 9 { 10 std::cout << elem << std::endl; 11 return true; 12 } 13 14 struct Element 15 { 16 Element(int _id = 0, int _val = 0) : id(_id), val(_val) {} 17 Element(const Element &elem) { id = elem.id; val = elem.val; } 18 //~Element() {} 19 20 Element & operator=(const Element &elem) { id = elem.id; val = elem.val; return *this; } 21 22 int id; 23 int val; 24 }; 25 26 bool operator<(const Element &left, const Element &right) 27 { 28 return left.id < right.id; 29 } 30 31 std::ostream & operator<<(std::ostream &out, const Element &elem) 32 { 33 out << elem.id << " " << elem.val; 34 return out; 35 } 36 37 int main() 38 { 39 srand(static_cast<unsigned int>(time(NULL))); 40 41 ArrayList<int> int_list; 42 43 for (int i = 0; i < TEST_ARRAY_LIST_ELEM_COUNT; ++ i) 44 { 45 int_list.Insert(0, i); 46 } 47 48 std::cout << "------ print list ------ " << std::endl; 49 int_list.Traverse(VisistArrayList); 50 51 size_t out_index = ArrayList<int>::INVALID_ARRAYLIST_INDEX; 52 int locate_elem = 3; int out_elem = -1; 53 54 std::cout << "------ locate index is " << std::endl << locate_elem << " ------ " << std::endl; 55 if (int_list.LocateElem(locate_elem, out_index)) 56 { 57 if (int_list.GetElem(out_index, out_elem)) 58 { 59 std::cout << "find locate elem is " << out_elem << std::endl; 60 } 61 } 62 if (int_list.PriorElem(locate_elem, out_elem)) 63 { 64 std::cout << "find prior elem of locate elem is " << out_elem << std::endl; 65 } 66 if (int_list.NextElem(locate_elem, out_elem)) 67 { 68 std::cout << "find next elem of locate elem is " << out_elem << std::endl; 69 } 70 71 72 while (0 != int_list.Size()) 73 { 74 int a = 0; 75 int_list.Delete(rand() % int_list.Size(), a); 76 int_list.Traverse(VisistArrayList); 77 std::cout << "----------------------------------------------------------------" << std::endl; 78 } 79 80 ArrayList<Element> element_list; 81 82 for (int i = 0; i < TEST_ARRAY_LIST_ELEM_COUNT; ++ i) 83 { 84 element_list.Insert(0, Element(i, rand())); 85 } 86 87 element_list.Traverse(VisistArrayList); 88 }