顺序表

【1】线性结构

在数据元素的非空有限集中,线性结构特点:

a. 存在唯一的一个被称作“第一个”的数据元素

b. 存在唯一的一个被称作“最后一个”的数据元素

c. 除第一个之外,集合中的每个数据元素均只有一个前驱

d. 除最后一个之外,集合中每个数据元素均只有一个后继

【2】线性表

线性表是最常用且简单的一种数据结构。

一个线性表是n个数据元素的有限序列。

线性表中的数据元素可以是各种各样的,但同一线性表中的元素必定具有相同特性。

在复杂的线性表中,一个数据元素可以由若干个数据项组成。这种情况下,常把数据元素称为记录。

而含大量记录的线性表称为文件。

【3】顺序表

线性表的顺序表示指用一组地址连续的存储单元依次存储线性表的数据元素。

线性表的顺序存储结构如下:

【4】顺序表的优缺点

优点:乐于随机存取。

因为物理结构和逻辑结构均连续,所以数据存取尤其简易。

缺点:悲在插入删除

为了保证存储的连续性,插入或删除会比较麻烦。

另外一点:顺序存储要求明确数据的规模用来分配给数据空间。

【5】C++实现顺序表代码

<1>SeqList.h文件

  1 #include <iostream>
  2 #include <assert.h>
  3 #include <typeinfo.h>
  4 #include <string.h>
  5 using namespace std;
  6 
  7 #define     UM_QUIT     0
  8 #define  UM_INPUTR   1
  9 #define  UM_PRINT    2
 10 #define  UM_INPUTH   3
 11 #define  FINDVALUE   4
 12 #define  UM_INSERT   5
 13 #define  UM_REMOVE   6
 14 #define  UM_SORT     7
 15 #define  UM_REMOVEALL  8
 16 #define  UM_REVERSE    9
 17 #define  UM_ERASE      10
 18 #define  UM_PVPOS      11
 19 
 20 #define  MAXSIZE      10
 21 #define  INCSIZE      5
 22 
 23 template <class Type>
 24 class SeqList
 25 {
 26 private:
 27     Type* m_pData;        //数据区域
 28     size_t m_nMaxSize;    //最大容量
 29     size_t m_nLen;        //元素个数
 30 
 31 public:
 32     SeqList(size_t size = MAXSIZE);
 33     SeqList(const SeqList<Type>& sqList);
 34     SeqList<Type>& operator=(const SeqList<Type>& sqList);
 35     ~SeqList();
 36 
 37 public:
 38     size_t GetMaxSize() const;
 39     void SetMaxSize(size_t nMaxSize) const;
 40     size_t GetLength() const;
 41     void SetLength(size_t nLen) const;
 42 
 43 public:
 44     bool IsFull() const;
 45     bool IsEmpty() const;
 46     bool IsElement(const Type& Value);
 47     void Push_Back(const Type& Value);
 48     void Push_Front(const Type& Value);
 49     void At(const size_t pos);
 50     size_t FindPos(const Type& Value);
 51     void Insert(const size_t pos, const Type& Value);
 52     void Remove(const Type& Value);
 53     void Erase(const size_t pos);
 54     void RemoveAll(const Type& Value);
 55     void Sort();
 56     void Reverse();
 57     void Print() const;
 58 
 59 private:
 60     bool IncSize();
 61     void Swap(const size_t leftpos, const size_t rightpos);
 62 };
 63 //基本属性函数
 64 template <class Type>
 65 size_t SeqList<Type>::GetMaxSize() const
 66 {
 67     return m_nMaxSize;
 68 }
 69 template <class Type>
 70 void SeqList<Type>::SetMaxSize(size_t nMaxSize) const
 71 {
 72     m_nMaxSize = nMaxSize;
 73 }
 74 template <class Type>
 75 size_t SeqList<Type>::GetLength() const
 76 {
 77     return m_nLen;
 78 }
 79 template <class Type>
 80 void SeqList<Type>::SetLength(size_t nLen) const
 81 {
 82     m_nLen = nLen;
 83 }
 84 // 作用:扩充顺序表容量
 85 // 当数据数量大于最大容量时,为顺序表增加容量
 86 // 增加度量为INCSIZE
 87 template <class Type>
 88 bool SeqList<Type>::IncSize()
 89 {
 90     Type* pNewDate = new Type[m_nMaxSize + INCSIZE + 1];
 91     if (NULL == pNewDate)
 92         return false;
 93     memcpy(pNewDate, m_pData, sizeof(Type) * (m_nLen + 1));
 94     m_pData = pNewDate;
 95     m_nMaxSize += INCSIZE;
 96     return true;
 97 }
 98 //交换数据
 99 template <class Type>
100 void SeqList<Type>::Swap(const size_t leftpos, const size_t rightpos)
101 {
102     Type temp = m_pData[leftpos];
103     m_pData[leftpos] = m_pData[rightpos];
104     m_pData[rightpos] = temp;
105 }
106 //默认复合构造函数
107 template <class Type>
108 SeqList<Type>::SeqList(size_t size = MAXSIZE)
109 {
110     m_nMaxSize = size > MAXSIZE ? size : MAXSIZE;
111     m_pData = new Type[m_nMaxSize + 1];
112     assert(m_pData != NULL);
113     m_nLen = 0;
114 }
115 //拷贝构造函数
116 template <class Type>
117 SeqList<Type>::SeqList(const SeqList<Type>& sqList)
118 {
119     if (this != &sqList)
120     {
121         m_pData = new Type[sqList.m_nMaxSize + 1];
122         if (m_pData != NULL)
123         {
124             memcpy(m_pData, sqList.m_pData, sizeof(Type) * (sqList.m_nLen + 1));
125         }
126         m_nMaxSize = sqList.m_nMaxSize;
127         m_nLen = sqList.m_nLen;
128     }
129 }
130 //赋值函数(思考什么时候调用赋值函数)
131 template <class Type>
132 SeqList<Type>& SeqList<Type>::operator=(const SeqList<Type>& sqList)
133 {
134     m_nLen = sqList.m_nLen;
135     m_nMaxSize = sqList.m_nMaxSize;
136     memcpy(m_pData, sqList.m_pData, sizeof(Type) * (sqList.m_nLen + 1));
137     return *this; 
138 }
139 //析构函数
140 template <class Type>
141 SeqList<Type>::~SeqList()
142 {
143     if (m_pData != NULL)
144     {
145         delete []m_pData;
146         m_pData = NULL;
147     }
148     m_nMaxSize = 0;
149     m_nLen = 0;
150 }
151 //判满
152 template <class Type>
153 bool SeqList<Type>::IsFull() const
154 {
155     return m_nLen == m_nMaxSize;
156 }
157 //判空
158 template <class Type>
159 bool SeqList<Type>::IsEmpty() const
160 {
161     return 0 == m_nLen;
162 }
163 //是否是顺序表中元素
164 template <class Type>
165 bool SeqList<Type>::IsElement(const Type& Value)
166 {
167     size_t pos = FindPos(Value);
168     return 0 != pos;
169 }
170 //从顺序表末尾添加元素
171 template <class Type>
172 void SeqList<Type>::Push_Back(const Type& Value)
173 {
174     if (IsFull() && !IncSize())    //注意写法用意
175         return;
176     m_pData[++m_nLen] = Value;
177 }
178 //从顺序表首部添加元素
179 template <class Type>
180 void SeqList<Type>::Push_Front(const Type& Value)
181 {
182     if (IsFull() && !IncSize())
183         return;
184     for (size_t i = m_nLen; i > 0; --i)
185     {
186         m_pData[i + 1] = m_pData[i];
187     }
188     ++m_nLen;
189     m_pData[1] = Value;
190 }
191 //输出对应索引处的数据
192 template <class Type>
193 void SeqList<Type>::At(const size_t pos)
194 {
195     if (pos <= 0 || pos > m_nLen)
196         cout << "输入下标有误!" << endl;
197     else
198         cout << pos << "位置的数据为:" << m_pData[pos] << endl; 
199 }
200 //查找某数据的索引
201 template <class Type>
202 size_t SeqList<Type>::FindPos(const Type& Value)
203 {
204     m_pData[0] = Value;
205     size_t i = m_nLen;
206     while (m_pData[i] != Value)
207     {
208         --i;
209     }
210     return i;
211 }
212 //在索引处插入值
213 template <class Type>
214 void SeqList<Type>::Insert(const size_t pos, const Type& Value)
215 {
216     if (pos <= 0 || pos > m_nLen + 1)
217         return;
218     if (IsFull() && !IncSize())
219         return;
220 
221     ++m_nLen;
222     for (size_t i = m_nLen; i > pos; --i)
223     {
224         m_pData[i] = m_pData[i-1];
225     }
226     m_pData[pos] = Value;
227 }
228 //移除某个值
229 template <class Type>
230 void SeqList<Type>::Remove(const Type& Value)
231 {
232     if (IsElement(Value))
233     {
234         size_t pos  = FindPos(Value);
235         Erase(pos);
236     }
237     else
238     {
239         cout << "输入数据不存在!" << endl;
240     }
241 }
242 //按索引删除数据
243 template <class Type>
244 void SeqList<Type>::Erase(const size_t pos)
245 {
246     if (pos <= 0 || pos > m_nLen)
247     {
248         cout << "输入错误" << endl;
249     }
250     else
251     {
252         for (size_t i = pos; i < m_nLen; ++i)
253         {
254             m_pData[i] = m_pData[i+1];
255         }
256         --m_nLen;
257         cout << "删除成功!删除后结果如下:" << endl;
258         Print();
259     }
260 }
261 //删除全部(删除所有出现在顺序表中的某值)
262 template <class Type>
263 void SeqList<Type>::RemoveAll(const Type& Value)
264 {
265     if (IsElement(Value))
266     {
267         for (size_t i = m_nLen; i > 0; --i)
268         {
269             if (m_pData[i] == Value)
270                 Remove(Value);
271         }
272 
273         cout << "删除全部成功!删除后结果如下:" << endl;
274         Print();
275     }
276     else
277     {
278         cout << "输入的数据不存在!" << endl;
279     }
280 }
281 //顺序表数据排序
282 template <class Type>
283 void SeqList<Type>::Sort()
284 {
285     if (m_nLen > 2)
286     {
287         size_t i = 0, j = 0;
288         for (i = 2; i <= m_nLen; ++i)
289         {
290             if (m_pData[i] < m_pData[i - 1])
291             {
292                 m_pData[0] = m_pData[i];
293                 j = i - 1;
294                 do 
295                 {
296                     m_pData[j + 1] = m_pData[j];
297                     --j;
298                 } while(m_pData[j] > m_pData[0]);
299                 m_pData[j + 1] = m_pData[0];
300             }
301         }
302     }
303 }
304 //逆置顺序表
305 template <class Type>
306 void SeqList<Type>::Reverse()
307 {
308     if (m_nLen > 2)
309     {
310         size_t i = 0, j = 0;
311         for (i = 1, j = m_nLen; i < j; ++i, --j)
312         {
313             Swap(i, j);
314         }
315         cout << "逆置结果如下:" << endl;
316         Print();
317     }
318 }
319 //打印顺序表数据信息
320 template <class Type>
321 void SeqList<Type>::Print() const
322 {
323     cout << "容量:" << m_nMaxSize << endl;
324     cout << "元素的个数:" << m_nLen << endl;
325     cout << "数据如下:" << endl;
326     for (size_t i = 1; i <= m_nLen; ++i)
327     {
328         cout << m_pData[i] << " ";
329     }
330     cout << endl;
331 }
View Code

<2>TestSeqList.cpp文件

  1 #include "SeqList.h"
  2 using namespace std;
  3 
  4 void main()
  5 {
  6     cout << "\t**********************深拷贝************************\t\t\t\t" << endl;
  7     SeqList<int> MylistA;
  8     MylistA.Push_Back(12);
  9     MylistA.Push_Back(23);
 10     MylistA.Push_Back(34);
 11     cout << "打印MylistA数据信息:" << endl;
 12     MylistA.Print();
 13     SeqList<int>  YoulistA(MylistA);
 14     cout << "打印YoulistA数据信息:" << endl;
 15     YoulistA.Print();
 16 
 17     cout << "\t**********************赋值功能************************\t\t\t\t" << endl;
 18     SeqList<int> MylistB, YoulistB;
 19     MylistB.Push_Front(10);
 20     MylistB.Push_Front(11);
 21     MylistB.Push_Front(12);
 22     cout << "打印MylistB数据信息:" << endl;
 23     MylistB.Print();
 24     YoulistB = MylistB;
 25     cout << "打印YoulistB数据信息:" << endl;
 26     YoulistB.Print();
 27 
 28     cout << "测试顺序表实现:" << endl;
 29     SeqList<int>  mylist;
 30     int select = 1;
 31     int item = 0;
 32     size_t pos = 0;
 33     while (select != 0)
 34     {
 35         cout << "\t********************菜单*************************\t\t\t\t" << endl;
 36         cout << "\t\t*  1.输入数据r        2.打印数据  *\t\t\t\t" << endl;
 37         cout << "\t\t*  3.输入数据h        4.按值查询  *\t\t\t\t" << endl;
 38         cout << "\t\t*  5.插入数据         6.删除数据  *\t\t\t\t" << endl;
 39         cout << "\t\t*  7.排序             8.全部删除  *\t\t\t\t" << endl;
 40         cout << "\t\t*  9.逆置            10.位置删除  *\t\t\t\t" << endl;
 41         cout << "\t\t*  11.查询位置值      0.退出      *\t\t\t\t" << endl;
 42         cout << "\t**********************************************\t\t\t\t" << endl;
 43         cout << "请选择操作:" <<endl;
 44         cin >> select;
 45         switch (select)
 46         {
 47         case UM_QUIT:     //0
 48             break;
 49         case UM_INPUTR:   //1
 50             cout << "请输入数据并以-1结束" << endl;
 51             while (cin >> item, item != -1)
 52             {
 53                 mylist.Push_Back(item);
 54             }
 55             break;
 56         case UM_PRINT:    //2
 57             mylist.Print();
 58             break;
 59         case UM_INPUTH:   //3
 60             cout << "请输入数据并以-1结束" << endl;
 61             while (cin>>item, item != -1)
 62             {
 63                 mylist.Push_Front(item);
 64             }
 65             break;
 66         case FINDVALUE:   //4
 67             cout << "请输入查询的数据 " << endl;
 68             cin >> item;
 69             pos = mylist.FindPos(item);
 70             if (0 == pos)
 71             {
 72                 cout << "查无此数据" << endl;
 73             }
 74             else
 75             {
 76                 cout << "数据的下标是: " << pos << endl;
 77             }
 78             break;
 79         case UM_INSERT:  //5
 80             cout << "请输入插入的数据和位置信息" << endl;
 81             cin >> item >>pos;
 82             mylist.Insert(pos, item);
 83             mylist.Print();
 84             break;
 85         case UM_REMOVE:   //6
 86             cout << "请输入删除的数据" << endl;
 87             cin >> item;
 88             mylist.Remove(item);
 89             break;
 90         case UM_SORT:   //7
 91             mylist.Sort();
 92             break;
 93         case UM_REMOVEALL:   //8
 94             cout << "请输入数据:" << endl;
 95             cin >> item;
 96             mylist.RemoveAll(item);
 97             break;
 98         case UM_REVERSE:  //9
 99             mylist.Reverse();
100             break;
101         case UM_ERASE:  //10
102             cout << "请输入位置信息:" << endl;
103             cin >> pos;
104             mylist.Erase(pos);
105             break;
106         case UM_PVPOS: //11
107             cout << "请输入位置信息:" << endl;
108             cin >> pos;
109             mylist.At(pos);
110             break;
111         default:
112             cout << "选择错误,请重新选择" << endl;
113         }
114     }
115 }
View Code

备注:以上实现代码当时运行环境为VS2010

为什么模板类的.h文件与模板类的.cpp文件没有像普通类那般分离开,请参见随笔《模板类 声明与定义》。

 

Good   Good  Study, Day  Day  Up.

顺序  选择  循环  总结 

posted @ 2013-11-26 14:43  kaizenly  阅读(3147)  评论(0编辑  收藏  举报
打赏