声明:本文内容属于本人原创,欢迎转载,请大家在转载时注明转贴地址
使用一个模板类实现了线性表的顺序表示,我对这个模板类进行了简单的测试,大家如果在使用过程中或看代码的过程中遇到错误请及时提出,谢谢!该代码已经在VS2005环境下编译通过
-
-
#ifndefLISTSQU_H_
-
#defineLISTSQU_H_
-
#include<assert.h>
-
#include<iostream>
-
usingnamespacestd;
-
#defineLIST_INIT_SIZE100
-
#defineLISTINCREMENT10
-
#defineSQUSUCCEED0
-
#defineSQUERROR-1
-
#defineSQUOVERFLOW-2
-
-
-
template<classT>
-
boolequal(Te1,Te2)
- {
-
if(e1==e2)
- {
-
returntrue;
- }
-
else
- {
-
returnfalse;
- }
- }
-
-
-
template<classT>
-
voidshow(Te)
- {
- cout<<e<<endl;
- }
-
template<classT>
-
classListSqu
- {
-
public:
-
-
- ListSqu();
- ~ListSqu();
-
ListSqu(constListSqu<T>&ls);
-
ListSqu<T>&operator=(constListSqu<T>&ls);
-
-
public:
-
-
-
intClearList();
-
-
-
boolIsEmpty();
-
-
-
intLength();
-
-
-
intLocalElem(constT&e,bool(*Compare)(T,T)=equal);
-
-
-
intGetItem(inti,T&e);
-
-
-
intInsertItem(inti,T&e);
-
-
-
intDeleteItem(inti,T&e);
-
-
-
intShow();
-
-
-
voidTraverse(void(*vi)(Te)=show);
-
private:
- T*items;
-
intlength;
-
intlistsize;
- };
-
template<classT>
- ListSqu<T>::ListSqu()
- {
-
items=newT[LIST_INIT_SIZE];
- assert(items);
- length=0;
- listsize=LIST_INIT_SIZE;
- }
-
template<classT>
- ListSqu<T>::~ListSqu()
- {
-
if(items!=NULL)
- {
-
delete[]items;
- items=NULL;
- }
- }
-
template<classT>
-
ListSqu<T>::ListSqu(constListSqu<T>&ls)
- {
- length=ls.length;
- listsize=ls.listsize;
-
items=newT[listsize+1];
- memcpy(items,ls.items,_msize(ls.items));
- }
-
template<classT>
-
ListSqu<T>&ListSqu<T>::operator=(constListSqu<T>&ls)
- {
-
if(this==&ls)
-
return*this;
-
if(items!=NULL)
- {
-
delete[]items;
- items=NULL;
- }
- length=ls.length;
- listsize=ls.listsize;
-
items=newT[listsize+1];
- memcpy(items,ls.items,_msize(ls.items));
-
return*this;
- }
-
template<classT>
-
intListSqu<T>::ClearList()
- {
- length=0;
-
returnSQUSUCCEED;
- }
-
template<classT>
-
boolListSqu<T>::IsEmpty()
- {
-
returnlength==0;
- }
-
template<classT>
-
intListSqu<T>::LocalElem(constT&e,bool(*Compare)(T,T))
- {
-
inti=0;
- T*p;
- p=items;
-
while(i<length&&!Compare(*p++,e))
- {
- ++i;
- }
-
if(i<length)
- {
-
returni+1;
- }
-
else
- {
-
return0;
- }
- }
-
template<classT>
-
intListSqu<T>::GetItem(inti,T&e)
- {
-
if((i<1)||(i>length))
- {
-
cout<<"所给位置超出位置索引!"<<endl;
-
returnSQUERROR;
- }
-
else
- {
- e=items[i-1];
-
returnSQUSUCCEED;
- }
- }
-
template<classT>
-
intListSqu<T>::InsertItem(inti,T&e)
- {
-
if(i<1||i>length+1)
- {
-
cout<<"所给位置出错!"<<endl;
-
returnSQUERROR;
- }
-
else
- {
-
if(length>=listsize)
- {
-
T*pNew=newT[LISTINCREMENT];
- memcpy(pNew,items,_msize(items));
- items=pNew;
-
if(items==NULL)
- {
-
cout<<"申请内存空间失败!"<<endl;
-
returnSQUOVERFLOW;
- }
- listsize+=LISTINCREMENT;
- }
-
for(intk=length;k>=i-1;k--)
- {
- items[k+1]=items[k];
- }
- items[i-1]=e;
- length++;
-
returnSQUSUCCEED;
- }
- }
-
template<classT>
-
intListSqu<T>::DeleteItem(inti,T&e)
- {
-
if(i<1||i>length)
- {
-
cout<<"所给删除位置出错!"<<endl;
-
returnSQUERROR;
- }
- e=items[i-1];
-
for(i=i-1;i<length;i++)
- {
- items[i]=items[i+1];
- }
- length--;
-
returnSQUSUCCEED;
- }
-
template<classT>
-
intListSqu<T>::Show()
- {
-
for(inti=0;i<length;i++)
- {
- cout<<items[i]<<endl;
- }
-
returnSQUSUCCEED;
- }
-
template<classT>
-
voidListSqu<T>::Traverse(void(*vi)(Te))
- {
-
for(inti=0;i<length;i++)
- {
- vi(items[i]);
- }
- }
-
#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. 注意如何把函数指针当作形参并对其使用默认参数的方法
分享到:
相关推荐
线性表的顺序表示以及实现(C语言编写),有完整的注释。
线性表的顺序表示(数组)及C++实现。创建CArrayList类,实现顺序表的各项主要功能:初始化、追加、插入、删除、查找、排序、倒置、打印等。
线性表的顺序表示和实现,附全套C++代码实现
线性表的动态分配顺序表示和实现 线性表的动态分配顺序表示和实现 C++
实现线性表的顺序表示及插入删除操作可直接运行
<br>实验二 单链表结构及计算 实验目的: 通过实验掌握下列知识: 1、熟悉线性表的基本运算在两种存储结构(顺序结构和链式结构)上的实现; 2、继续熟悉VC编程、编译和调试环境; 内容及步骤:...
实验内容: 1.编写程序实现顺序表的下列基本操作: (1)初始化顺序表La。 (2)将La置为空表。 (3)销毁La。 ...(3)假设两个顺序线性表La和Lb分别表示两个集合A和B,利用 union_Sq操作实现A=A∪B。
2、2、0 线性表的顺序表示和实现 2、3、0 线性表的链式表示和实现 2、3、1 线性链表 2、3、2 循环链表 2、3、3 双向链表 2、4、0 一元多项式的表示及相加 3、0、0 栈和队列 3、1、0 栈 3、1、1 抽象数据类型栈的定义...
符号多项式的操作,已经成为表处理的典型用例。在数学上,一个一元多项式Pn(x)可按升幂写 ...本题要求选用线性表的一种合适的存储结构来表示一个一元多项式,并在此结构上实现一元多 项式的加法,减法和乘法操作
采用C++语言实现利用顺序栈、链栈将10进制数转为2、8、16进制数。 通过本编程实例,可以进一步了解到顺序栈和链栈之间区别和联系,体会两者的异同,进一步加深知识印象,是不错的练习素材哦。
第六章 - 二叉树链式存储、二叉树顺序存储、哈夫曼树与哈夫曼编码、树孩子表示法、树孩子兄弟表示法、树双亲表示法 第七章 - 图数组表示法、图邻接表表示、图的应用 第九章 - 哈希表、折半查找、B-树、二叉平衡树 ...
1.4 C++程序的编写和实现 1.5 关于C++上机实践 习题 第2章 数据类型与表达式 2.1 C++的数据类型 2.2 常量 2.2.1 什么是常量 2.2.2 数值常量 2.2.3 字符常量 2.2.4 符号常量 2.3 变量 2.3.1 什么是变量 2.3.2 ...
Data Structures, Algorithms, and Applications in C++, Second Edition 出版者的话 译者序 前言 第一部分 预备知识 第1章 C++回顾 1.1 引言 1.2 函数与参数 1.2.1 传值参数 1.2.2 模板函数 1.2.3 引用参数 ...
线性表的顺序表示 C++语言实现 数据结构 算法
定义一个包含学生信息(学号,姓名,成绩)的顺序表,使其具有如下功能: (1) 根据指定学生个数,逐个输入学生信息; (2) 逐个显示学生表中所有学生的相关信息; (3) 根据姓名进行查找,返回此学生的学号和成绩; (4...
1.4 C++程序的编写和实现 1.5 关于C++上机实践 习题 第2章 数据类型与表达式 2.1 C++的数据类型 2.2 常量 2.2.1 什么是常量 2.2.2 数值常量 2.2.3 字符常量 2.2.4 符号常量 2.3 变量 2.3.1 什么是变量 2.3.2 ...
本教程共分为5个部分,第一部分是C语言提高部分,第二部分为C++基础部分,第三部分为C++进阶部分,第四部分为C、C++及数据结构基础部分,第五部分为C_C++与设计模式基础,内容非常详细. 第一部分 C语言提高部分目录...
|data | next│ └──┴──┘ data域--存放结点值的数据域 next域--存放结点的直接后继的地址(位置)的指针域(链域) 注意: ①链表通过每个结点的链域将线性表的n个结点按其逻辑顺序链接在...
①、掌握线性表的表示和实现 ②、学会定义抽象数据类型 ③、学会分析问题,设计适当的解决方案 ④、深入掌握栈和队列应用的算法设计。