基于静态分配的数组的顺序表(兼具Boost单元测试)

  首先,我们来搞明白几个概念吧(参考自网站数据结构及百度百科)。

  线性表

  线性表是最基本、最简单、也是最常用的一种数据结构。线性表中数据元素之间的关系是一对一的关系,即除了第一个和最后一个数据元素之外,其它数据元素都是首尾相接的。线性表的逻辑结构简单,便于实现和操作。在实现线性表数据元素的存储方面,一般可用顺序存储结构和链式存储结构两种方法。

  顺序表

  用顺序存储方法存储的线性表简称为顺序表(Sequential List)。顺序表的存储方法是把线性表的结点按逻辑次序依次存放在一组地址连续的存储单元里。

  链表

  链接方式存储的线性表简称为链表(Linked List)。

  顺序表和链表的比较如下:

   

  注:存储密度(Storage Density)是指结点数据本身所占的存储量和整个结点结构所占的存储量之比,即“存储密度=(结点数据本身所占的存储量)/(结点结构所占的存储总量)”。

  下文将具体讲述如何实现基于静态分配的数组的顺序表:

  具体算法可以参考网页顺序表上实现的基本运算及Larry Nyhoff的《数据结构与算法分析》。我的做法基本跟他们是一样的,只是我又额外多了一部分:Boost单元测试。对于如何进行Boost单元测试可以参考本人之前写过的一篇文章如何在VS2013中进行Boost单元测试

  我设计的顺序表类如下:

 // seqlist.h 1 #ifndef SEQLIST
 2 #define SEQLIST
 3
 4 #include <iostream>
 5 #include <cassert>
 6 #include <algorithm>
 7
 8 using namespace std;
 9
10 const int CAPACITY = 1024;
11 typedef int ElementType;
12
13 class SeqList
14 {
15 public:
16     SeqList();
17     virtual ~SeqList();
18     bool empty() const;
19     void clear();
20     bool insert(const int pos, const ElementType val);
21     bool erase(const int pos);
22     void display() const;
23     bool setSeqList(const ElementType *tmpList, const int len);
24     int getLenOfList() const;
25     ElementType getItem(const int pos);
26     ElementType * getSeqList();    // 保留,不推荐使用,因为在使用过程中无法进行越界检查
27
28 private:
29     int lenOfList;            // 线性链表长度
30     ElementType seqList[CAPACITY];
31
32 };
33
34 #endif

  1 // seqlist.cpp
  2 #include "seqlist.h"
  3
  4 SeqList::SeqList()
  5 {
  6     // initialization
  7     lenOfList = 0;
  8     fill(seqList, seqList + CAPACITY - 1, 0);
  9     // memset(SeqList, 1, CAPACITY*sizeof(int));
 10 }
 11
 12 SeqList::~SeqList()
 13 {
 14
 15 }
 16
 17 bool SeqList::empty() const
 18 {
 19     return lenOfList == 0;
 20 }
 21
 22 void SeqList::clear()
 23 {
 24     lenOfList = 0;
 25     fill(seqList, seqList + CAPACITY - 1, 0);
 26 }
 27
 28 bool SeqList::insert(const int pos, const ElementType val)
 29 {
 30     bool success = false;
 31     // assert(lenOfList != CAPACITY);    // 这里的assert分成两行写,是为了方便定位错误发生的地方
 32     // assert(0 <= pos <= lenOfList);
 33     if (lenOfList == CAPACITY)
 34     {
 35         cerr << "No space for insertion!" << endl;
 36     }
 37     else if (pos < 0 || pos > lenOfList)
 38     {
 39         cerr << "The position " << pos <<
 40             " you want to insert is less than zero or exceeds the length of the list!" << endl;
 41         throw out_of_range("throw out_of_range");    // 抛出一个越界异常
 42     }
 43     else
 44     {
 45         int tmpCount = lenOfList - pos;
 46         for (int i = 0; i < tmpCount; i++)
 47         {
 48             seqList[lenOfList - i] = seqList[lenOfList - i - 1];
 49         }
 50         seqList[pos] = val;
 51         lenOfList++;
 52         success = true;
 53     }
 54     return success;
 55 }
 56
 57 bool SeqList::erase(const int pos)
 58 {
 59     bool success = false;
 60     // assert(lenOfList != 0);
 61     // assert(0 <= pos <= lenOfList);
 62     if (lenOfList == 0)
 63     {
 64         cerr << "There is no elements in the list!" << endl;
 65     }
 66     else if (pos < 0 || pos > lenOfList)
 67     {
 68         cerr << "The position " << pos <<
 69             " you want to erase is less than zero or exceeds the length of the list!" << endl;
 70         throw out_of_range("throw out_of_range");    // 抛出一个越界异常
 71     }
 72     else
 73     {
 74         int tmp = lenOfList - pos;
 75         for (int i = 0; i < tmp - 1; i++)
 76         {
 77             seqList[pos + i] = seqList[pos + i + 1];
 78         }
 79         seqList[lenOfList - 1] = 0;
 80         lenOfList--;
 81         success = true;
 82     }
 83     return success;
 84 }
 85
 86 void SeqList::display() const
 87 {
 88     cout << "***Start Displaying***" << endl;
 89     if (lenOfList == 0)
 90     {
 91         cerr << "There is no element in the the list!" << endl;
 92     }
 93     else
 94     {
 95         for (int i = 0; i < lenOfList; i++)
 96         {
 97             cout << i << " : " << seqList[i] << endl;
 98         }
 99         cout << "***End Displaying***" << endl;
100     }
101 }
102
103 bool SeqList::setSeqList(const ElementType *tmpList, const int len)
104 {
105     // assert(len <= CAPACITY);
106     bool success = false;
107     if (len <= CAPACITY)
108     {
109         for (int i = 0; i < len; i++)
110         {
111             seqList[i] = *(tmpList++);
112         }
113         lenOfList = len;
114         success = true;
115     }
116     else
117     {
118         cerr << "The length of the array you set exceeds the CAPACITY." << endl;
119         throw out_of_range("throw out_of_range");    // 抛出一个越界异常
120     }
121     return success;
122 }
123
124 int SeqList::getLenOfList() const
125 {
126     return lenOfList;
127 }
128
129 ElementType SeqList::getItem(const int pos)
130 {
131     // assert(0 <= pos <= lenOfList);
132     if (pos < 0 || pos > lenOfList)
133     {
134         cerr << "The item at " << pos << " you want to get does not exist!" << endl;
135         throw out_of_range("throw out_of_range");    // 抛出一个越界异常
136     }
137     else
138     {
139         return seqList[pos];
140     }
141 }
142
143 ElementType * SeqList::getSeqList()
144 {
145     return seqList;
146 }

seqlist.cpp

  单元测试所用到的代码如下:

  1 // BoostUnitTest.cpp
  2 #define  BOOST_TEST_MODULE ArrayList_Test_Module
  3
  4 #include "stdafx.h"
  5 #include "D:\VSProject\Algorithm\List\SeqList\SeqList\SeqList\seqlist.h"
  6
  7 struct ArrayList_Fixture
  8 {
  9     ArrayList_Fixture()
 10     {
 11         BOOST_TEST_MESSAGE("Setup fixture");
 12         testArrayList = new SeqList();
 13     }
 14     ~ArrayList_Fixture()
 15     {
 16         BOOST_TEST_MESSAGE("Teardown fixture");
 17         delete testArrayList;
 18     }
 19
 20     SeqList * testArrayList;
 21 };
 22
 23 // BOOST_AUTO_TEST_SUITE(ArrayList_Test_Suite)
 24 BOOST_FIXTURE_TEST_SUITE(ArrayList_Test_Suite, ArrayList_Fixture)
 25
 26 BOOST_AUTO_TEST_CASE(ArrayList_Abnormal_Test)
 27 {
 28     // Set values to the array list
 29     int testArray[] = { 1, 2, 3, 4, 5 };    // 5 个元素
 30     int testLenOfList = sizeof(testArray) / sizeof(int);
 31     testArrayList->setSeqList(testArray, testLenOfList);
 32     // BOOST_REQUIRE_THROW(testArrayList->setArrayList(testArray, testLenOfList), out_of_range);
 33
 34
 35     // Method getItem-----------------------------------------------
 36     // If the position of the item you want to get is less than zero
 37     BOOST_REQUIRE_THROW(testArrayList->getItem(-1), out_of_range);
 38     // If the position of the item you want to get is larger than the length of the list
 39     BOOST_REQUIRE_THROW(testArrayList->getItem(10), out_of_range);
 40
 41
 42     // Method insert-------------------------------------------------
 43     // If the inserting position is less than zero
 44     BOOST_REQUIRE_THROW(testArrayList->insert(-1, 10), out_of_range);
 45     BOOST_REQUIRE(testArrayList->getLenOfList() == testLenOfList);
 46
 47     // If the inserting position is larger than the length of the list
 48     BOOST_REQUIRE_THROW(testArrayList->insert(10, 10), out_of_range);
 49     BOOST_REQUIRE(testArrayList->getLenOfList() == testLenOfList);
 50
 51
 52     // Method erase-------------------------------------------------
 53     // If the erasing position is less than zero
 54     BOOST_REQUIRE_THROW(testArrayList->erase(-1), out_of_range);
 55     BOOST_REQUIRE(testArrayList->getLenOfList() == testLenOfList);
 56
 57     // If the erasing position is larger than the length of the list
 58     BOOST_REQUIRE_THROW(testArrayList->erase(10), out_of_range);
 59     BOOST_REQUIRE(testArrayList->getLenOfList() == testLenOfList);
 60
 61 }
 62
 63 BOOST_AUTO_TEST_CASE(ArrayList_Normal_Test)
 64 {
 65     bool expected;
 66     bool actual;
 67     // Method empty-------------------------------------------------
 68     expected = true;
 69     actual = testArrayList->empty();
 70     BOOST_REQUIRE(expected == actual);
 71
 72     // Set values to the array list
 73     int testArray[] = { 1, 2, 3, 4, 5 };    // 5 个元素
 74     int testLenOfList = sizeof(testArray) / sizeof(int);
 75     testArrayList->setSeqList(testArray, testLenOfList);
 76     // BOOST_REQUIRE_THROW(testArrayList->setArrayList(testArray, testLenOfList), out_of_range);
 77
 78
 79     // Method getItem-----------------------------------------------
 80     BOOST_REQUIRE(testArrayList->getItem(1) == testArray[1]);
 81
 82
 83     // Method empty-------------------------------------------------
 84     expected = false;
 85     actual = testArrayList->empty();
 86     BOOST_REQUIRE(expected == actual);
 87
 88
 89     // Method insert-------------------------------------------------
 90     expected = true;
 91     actual = testArrayList->insert(1, 10);
 92     BOOST_REQUIRE(expected == actual);
 93     BOOST_REQUIRE(testArrayList->getLenOfList() == testLenOfList + 1);
 94     BOOST_REQUIRE(testArrayList->getItem(1) == 10);
 95
 96
 97     // Method erase-------------------------------------------------
 98     expected = true;
 99     actual = testArrayList->erase(1);
100     BOOST_REQUIRE(expected, actual);
101     BOOST_REQUIRE(testArrayList->getLenOfList() == testLenOfList);
102     BOOST_REQUIRE(testArrayList->getItem(1) == testArray[1]);
103
104 }
105
106 BOOST_AUTO_TEST_SUITE_END();

BoostUnitTest.cpp

  我在单元测试中偏向于使用REQUIRE型的判断,这样方便我检测出问题出现在哪。另外,我在单元测试中偏向于按“正常测试”和“不正常测试”两类进行测试。

时间: 2024-08-08 09:34:30

基于静态分配的数组的顺序表(兼具Boost单元测试)的相关文章

基于动态分配的数组的顺序表(兼具Boost单元测试)

我们利用静态分配的数组来实现的顺序表的局限还是挺大的,主要在于它的容量是预先定好的,用户不能根据自己的需要来改变.如果为了后续用户能够自己调整顺序表的大小,动态地分配数组空间还是很有必要的.基于动态分配的数组的顺序表绝大部分跟基于静态分配的数组的顺序表是一样的,只需在后者程序上改动一小部分即可. 第一,我们不需定义一个容量常量CAPACITY,而是定义一个私有变量myCapacity. 第二,类的构造函数需要改进一下.我们需要类在被实例化时自动申请内存,即需添加下边程序: ElementType

基于数组实现的单链表(兼具Boost单元测试)

对于单链表,我们大多时候会用指针来实现(可参考基于指针实现的单链表).现在我们就来看看怎么用数组来实现单链表. 1. 定义单链表中结点的数据结构 1 typedef int ElementType; 2 class NodeType 3 { 4 public: 5 ElementType data; 6 int next; 7 }; 该结点包括了两个元素,其一是数据,另一个是指向下一个结点的"指针"(在这篇文章中实际上是指用于实现单链表的数组的下标.)  2. 定义一个的数组 1 co

使用JAVA数组实现顺序表

1,引入了JAVA泛型类,因此定义了一个Object[] 类型的数组,从而可以保存各种不同类型的对象. 2,默认构造方法创建了一个默认大小为16的Object数组:带参数的构造方法创建一个指定长度的Object数组 3,实现的顺序表的基本操作有:返回表的长度.获取指定索引处的元素(注意是索引,而不是位置.索引以下标0开始,位置以下标1开始).按值查找数据元素的位置.直接插入元素(顺序表尾部).向指定位置插入元素.直接删除元素(在顺序表尾部).删除指定索引处元素.判断表是否为空.清空表. 1 im

基本的排序算法之——插入排序法(对于固定的空间数组或者顺序表)(

/********************************************************************** * Copyright (c)2015,WK Studios * Filename: * Compiler: GCC,VS,VC6.0 win32 * Author:WK * Time: 2015 4 20 ************************************************************************/

【C语言】静态顺序表和动态顺序表的实现

静态顺序表 定义一张顺序表也就是在内存中开辟一段连续的存储空间,并给它一个名字进行标识.只有定义了一个顺序表,才能利用该顺序表存放数据元素,也才能对该顺序表进行各种操作. 有两种定义顺序表的方法:一是静态地定义一张顺序表:二是动态地生成一张顺序表. 静态地定义一张顺序表的方法与定义一个数组的方法类似.可以描述如下: #define MAX_SIZE 100 typedef int DataType; typedef struct SeqList { DataType array[MAX_SIZE

java数据结构与算法之顺序表与链表深入分析

转载请注明出处(万分感谢!): http://blog.csdn.net/javazejian/article/details/52953190 出自[zejian的博客] 关联文章: java数据结构与算法之顺序表与链表设计与实现分析 java数据结构与算法之双链表设计与实现 ??数据结构与算法这门学科虽然在大学期间就已学习过了,但是到现在确实也忘了不少,因此最近又重新看了本书-<数据结构与算法分析>加上之前看的<java数据结构>也算是对数据结构的进一步深入学习了,于是也就打算

C++学习(二十九)(C语言部分)之 顺序表

一.数据结构组织 存放数据的方式 精心选择的数据结构可以提升效率 数据结构 1.逻辑结构 一对多关系 父与子 一对一关系 排队中 多对多关系 两地的路线 2.存储结构 数据存放的位置关系 顺序存储数据 一个挨着一个的存储(数组) 链式存储方式 二.线性表逻辑方面是线性关系 一对一线性 每一个元素有唯一的前驱和后继顺序存储的线性表 就是顺序表链式存储的线性表 就是链表 三.顺序表主要实现方式---->数组/动态数组顺序存储的线型表数据结构--->为了管理数据对数据进行操作--->增加 删除

1.2顺序表

计算机内部存储一张线性表(线性结构的数表),最简单方便的方法就是用一组连续地址的内存单元来存储整张线性表. 顺序表的特征: 1)有一个唯一的表名来标识该顺序表: 2)内存单元连续存储,也就是说,一张顺序表要占据一块连续的内存空间: 3)数据顺序存放,元素之间有先后关系 注意:数组本身就是一张顺序表. 顺序表的定义: 两种定义顺序表的方法:静态定义一张顺序表:动态生成一张顺序表. 静态地定义一张顺序表的方法与定义一个数组的方法类似. 向顺序表中插入.删除元素. ------------------

线性表---顺序表&amp;链表

一.线性表 1.线性表中的元素是一对一的关系,除了第一个与最后一个元素之外其他数据元素都是首尾相连的. 如果是一对多就用树来表示,如果是多对多就用网状来表示. 2.线性表的两种存储结构 顺序表:用顺序结构保存数据,数据在内存中是连续的. 链表:用链式存储结构保存数据,数据在内存中是不连续的. 二.顺序表 1.顺序表: 顺序表一般使用数组实现,顺序表的相关操作与数组相关,一般都是移动数组元素 顺序表封装所需要的三个属性: 存储空间的起始位置.数组date的存储位置就是线性表存储空间的存储位置. 线