数据结构:线性表的顺序表现和实现

本文通过实现模版化的ArrayList类,介绍了C++中模版和函数重载的应用,并提供了具体的测试案例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

包含了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 }
View Code

 

转载于:https://www.cnblogs.com/xiaol-luo/p/3293627.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值