`
dengbaoleng
  • 浏览: 1133936 次
文章分类
社区版块
存档分类
最新评论

线性表的顺序表示实现-C++版

 
阅读更多

声明:本文内容属于本人原创,欢迎转载,请大家在转载时注明转贴地址

使用一个模板类实现了线性表的顺序表示,我对这个模板类进行了简单的测试,大家如果在使用过程中或看代码的过程中遇到错误请及时提出,谢谢!该代码已经在VS2005环境下编译通过

  1. /**
  2. *@fileListSqu.h
  3. *@authorWangLiuqiang
  4. *@version1.0
  5. *@date2008-11-30
  6. *@brief该类实现了线性表的顺序表示
  7. */
  8. #ifndefLISTSQU_H_
  9. #defineLISTSQU_H_
  10. #include<assert.h>
  11. #include<iostream>
  12. usingnamespacestd;
  13. #defineLIST_INIT_SIZE100
  14. #defineLISTINCREMENT10
  15. #defineSQUSUCCEED0
  16. #defineSQUERROR-1
  17. #defineSQUOVERFLOW-2
  18. /*
  19. *定义了两个默认的函数,如果用户在调用LocalElem()函数时没有指定
  20. *函数,则使用默认的equal()函数;如果指定了自己的比较函数,则将
  21. *自己的函数指针赋给LocalElem()函数
  22. */
  23. template<classT>
  24. boolequal(Te1,Te2)
  25. {
  26. if(e1==e2)
  27. {
  28. returntrue;
  29. }
  30. else
  31. {
  32. returnfalse;
  33. }
  34. }
  35. /*
  36. *定义了两个默认的函数,如果用户在调用Traverse()函数时没有指定
  37. *函数,则使用默认的show()函数;如果指定了自己的比较函数,则将
  38. *自己的函数指针赋给Traverse()函数
  39. */
  40. template<classT>
  41. voidshow(Te)
  42. {
  43. cout<<e<<endl;
  44. }
  45. template<classT>
  46. classListSqu
  47. {
  48. public:
  49. /*
  50. *name构造函数/析构函数
  51. *@{
  52. */
  53. ListSqu();
  54. ~ListSqu();
  55. ListSqu(constListSqu<T>&ls);
  56. ListSqu<T>&operator=(constListSqu<T>&ls);
  57. /**@}*///构造函数/析构函数
  58. public:
  59. /*
  60. *清空顺序表
  61. *@return返回函数执行结果:
  62. *-0表示执行成功
  63. *-1表示执行出错
  64. */
  65. intClearList();
  66. /*
  67. *判断顺序表是否为空
  68. *@return返回函数执行结果:
  69. *-true表示顺序表为空
  70. *-false表示顺序表不为空
  71. */
  72. boolIsEmpty();
  73. /*
  74. *返回顺序表中元素个数
  75. *@return返回顺序表中元素个数
  76. */
  77. intLength();
  78. /*
  79. *返回线性表中第一个与e满足关系Compare()的数据元素的位序
  80. *@param[in]e待判定的元素
  81. *@param[in]Compare函数指针,指向判定元素的函数指针,默认为比较元素是否相等
  82. *@return返回线性表中第一个与e满足关系Compare()的数据元素的位序
  83. */
  84. intLocalElem(constT&e,bool(*Compare)(T,T)=equal);
  85. /*
  86. *返回顺序表中第i个位置的元素
  87. *@param[in]i需要获取元素的位置
  88. *@param[out]e顺序表中第i个位置的元素值
  89. *@return返回函数执行结果
  90. *-SQUSUCCEED表示函数执行成功
  91. *-SQUERROR表示函数执行失败
  92. *@noteC++中数组的下标是从0开始,因此第i个位置的元素应该取下标为i-1的元素
  93. */
  94. intGetItem(inti,T&e);
  95. /*
  96. *在顺序表的第i个位置之前插入元素
  97. *@param[in]元素的插入位置
  98. *@param[in]插入元素值
  99. *@return返回函数的执行结果
  100. *-SQUSUCCEED表示函数执行成功
  101. *-SQUERROR表示函数执行失败
  102. */
  103. intInsertItem(inti,T&e);
  104. /*
  105. *删除顺序表中第i个位置的元素
  106. *@param[in]i待删除元素位置
  107. *@param[out]e删除元素的值
  108. *@return返回函数的执行结果
  109. *-SQUSUCCEED表示函数执行成功
  110. *-SQUERROR表示函数执行失败
  111. */
  112. intDeleteItem(inti,T&e);
  113. /*
  114. *显示顺序表中元素
  115. *@return返回函数的执行结果
  116. *-SQUSUCCEED表示函数执行成功
  117. *-SQUERROR表示函数执行失败
  118. */
  119. intShow();//输出表中元素
  120. /*
  121. *遍历线性表中元素
  122. *@param[in]vi函数指针,指向处理元素函数,默认为在屏幕打印元素
  123. */
  124. voidTraverse(void(*vi)(Te)=show);
  125. private:
  126. T*items;
  127. intlength;
  128. intlistsize;
  129. };
  130. template<classT>
  131. ListSqu<T>::ListSqu()
  132. {
  133. items=newT[LIST_INIT_SIZE];
  134. assert(items);
  135. length=0;
  136. listsize=LIST_INIT_SIZE;
  137. }
  138. template<classT>
  139. ListSqu<T>::~ListSqu()
  140. {
  141. if(items!=NULL)
  142. {
  143. delete[]items;
  144. items=NULL;
  145. }
  146. }
  147. template<classT>
  148. ListSqu<T>::ListSqu(constListSqu<T>&ls)
  149. {
  150. length=ls.length;
  151. listsize=ls.listsize;
  152. items=newT[listsize+1];
  153. memcpy(items,ls.items,_msize(ls.items));
  154. }
  155. template<classT>
  156. ListSqu<T>&ListSqu<T>::operator=(constListSqu<T>&ls)
  157. {
  158. if(this==&ls)
  159. return*this;
  160. if(items!=NULL)
  161. {
  162. delete[]items;
  163. items=NULL;
  164. }
  165. length=ls.length;
  166. listsize=ls.listsize;
  167. items=newT[listsize+1];
  168. memcpy(items,ls.items,_msize(ls.items));
  169. return*this;
  170. }
  171. template<classT>
  172. intListSqu<T>::ClearList()
  173. {
  174. length=0;
  175. returnSQUSUCCEED;
  176. }
  177. template<classT>
  178. boolListSqu<T>::IsEmpty()
  179. {
  180. returnlength==0;
  181. }
  182. template<classT>
  183. intListSqu<T>::LocalElem(constT&e,bool(*Compare)(T,T))
  184. {
  185. inti=0;
  186. T*p;
  187. p=items;
  188. while(i<length&&!Compare(*p++,e))
  189. {
  190. ++i;
  191. }
  192. if(i<length)
  193. {
  194. returni+1;
  195. }
  196. else
  197. {
  198. return0;
  199. }
  200. }
  201. template<classT>
  202. intListSqu<T>::GetItem(inti,T&e)
  203. {
  204. if((i<1)||(i>length))
  205. {
  206. cout<<"所给位置超出位置索引!"<<endl;
  207. returnSQUERROR;
  208. }
  209. else
  210. {
  211. e=items[i-1];
  212. returnSQUSUCCEED;
  213. }
  214. }
  215. template<classT>
  216. intListSqu<T>::InsertItem(inti,T&e)
  217. {
  218. if(i<1||i>length+1)
  219. {
  220. cout<<"所给位置出错!"<<endl;
  221. returnSQUERROR;
  222. }
  223. else
  224. {
  225. if(length>=listsize)
  226. {
  227. T*pNew=newT[LISTINCREMENT];
  228. memcpy(pNew,items,_msize(items));
  229. items=pNew;
  230. if(items==NULL)
  231. {
  232. cout<<"申请内存空间失败!"<<endl;
  233. returnSQUOVERFLOW;
  234. }
  235. listsize+=LISTINCREMENT;
  236. }
  237. for(intk=length;k>=i-1;k--)
  238. {
  239. items[k+1]=items[k];
  240. }
  241. items[i-1]=e;
  242. length++;
  243. returnSQUSUCCEED;
  244. }
  245. }
  246. template<classT>
  247. intListSqu<T>::DeleteItem(inti,T&e)
  248. {
  249. if(i<1||i>length)
  250. {
  251. cout<<"所给删除位置出错!"<<endl;
  252. returnSQUERROR;
  253. }
  254. e=items[i-1];
  255. for(i=i-1;i<length;i++)
  256. {
  257. items[i]=items[i+1];
  258. }
  259. length--;
  260. returnSQUSUCCEED;
  261. }
  262. template<classT>
  263. intListSqu<T>::Show()
  264. {
  265. for(inti=0;i<length;i++)
  266. {
  267. cout<<items[i]<<endl;
  268. }
  269. returnSQUSUCCEED;
  270. }
  271. template<classT>
  272. voidListSqu<T>::Traverse(void(*vi)(Te))
  273. {
  274. for(inti=0;i<length;i++)
  275. {
  276. vi(items[i]);
  277. }
  278. }
  279. #endif

通过编写这段代码,觉得以下几点需要特别注意:

1. 需要特别注意内存越界的情况,对于动态申请的内存指针,如果对其进行越界操作,在使用delete操作释放该指针时会造成程序崩溃。在编写上面的程序时就将

template <class T> ListSqu<T>& ListSqu<T>::operator=(const ListSqu<T>& ls)

函数中items = new T[listsize + 1];错误的写成了items = new T[length + 1];而造成内存越界,详细解释如下:

template <class T>
ListSqu <T>& ListSqu <T>::operator=(const ListSqu <T>& ls)
{
if( this == &ls )
return *this;

delete[] items;
items = NULL;

length = ls.length;
listsize = ls.listsize;

items = new T[length + 1];
memcpy(items, ls.items, _msize(ls.items));
return *this;
}

items = new T[length + 1];
这里应该是
items = new T[listsize + 1];
listsize是我在类的构造函数中初始化分配的内存数,而length是当前线性表中存放的元素个数,这里用length+1分配内存,而在memcpy(items, ls.items, _msize(ls.items)); 又将sizeof(T)*listsize长的字节拷贝给items该处发生越界了

2. 注意模板类的复制构造函数和赋值操作符的声明方法

3. 注意如何把函数指针当作形参并对其使用默认参数的方法

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics