线性表类模板实现

来源:互联网 发布:串口数据协议 编辑:程序博客网 时间:2024/04/27 15:15

测试结果


测试程序

/// @file exam_x_x_cpp.cpp/// @brief 测试动态数组模板实现#include <stdlib.h>#include <stdio.h>#include <stddef.h>#include <iostream>#include <assert.h>#include "DynamicArrays.h"void fnTest_CDynamicArrays(); ///< 测试动态数组//----------------------------------------------------------------------// 动态数组类测试代码//----------------------------------------------------------------------int main(int argc, char* argv[], char* envp[]){fnTest_CDynamicArrays();printf("hello dynamic arrays\n");return 0;}void fnTest_CDynamicArrays(){    bool bValid = false;CDynamicArrays<int> DynAry;    int iTmp = 0;/// 没有数据的情况    printf("\n----------\n");    printf("DynAry.isEmpty() =  %d\n", DynAry.isEmpty());    DynAry.printData();    printf("DynAry.isEmpty() =  %d\n", DynAry.isEmpty());/// 有数据的情况,没有数据时, 插入一个数据printf("\n----------\n");DynAry.insert(0, 0x1);    DynAry.addTail(0x2);    DynAry.addTail(0x3);    DynAry.addTail(0x4);    DynAry.addTail(0x5);    DynAry.addTail(0x6);    DynAry.addTail(0x7);    DynAry.addTail(0x8);    DynAry.printData();    // 9data    printf("\n----------\n");    DynAry.insert(8, 0x9);    DynAry.printData();    // 10data    printf("\n----------\n");    DynAry.addTail(0x10);    DynAry.printData();    iTmp = DynAry.prev(DynAry[7], bValid);    if (bValid)    {        printf("DynAry.prev(DynAry[7], bValid) = %d\n", iTmp);    }    iTmp = DynAry.next(DynAry[3], bValid);    if (bValid)    {        printf("DynAry.next(DynAry[3], bValid) = %d\n", iTmp);    }    // nodata    printf("\n----------\n");    printf("DynAry.isEmpty() =  %d\n", DynAry.isEmpty());    DynAry.clear();    printf("DynAry.isEmpty() =  %d\n", DynAry.isEmpty());    // re add 1data    printf("\n----------\n");    DynAry.addTail(0x11);    DynAry.printData();    printf("DynAry.isEmpty() =  %d\n", DynAry.isEmpty());}

线性表类模板实现

/// @file DynamicArrays.h/// @brief 动态数组模板实现#ifndef DYNAMIC_ARRAYS_H_#define DYNAMIC_ARRAYS_H_#ifndef IN#define IN#endif // #ifndef IN#ifndef OUT#define OUT#endif // #ifndef OUT/**动态数组是线性表结构的一种线性表是数据结构中最常用的一种线性表特点线性存储, 有首元素,尾元素,表长允许有空表首元素没有前驱,只有唯一后继尾元素只有唯一前驱,没有后继非首尾元素,只有唯一前驱和唯一后继线性表抽象后的方法初始化表求表长拿元素求前驱求后继插入删除是否为空清空表线性表基本数据表长数据指针*///----------------------------------------------------------------------// 动态数组类定义//----------------------------------------------------------------------template<typename T>class CDynamicArrays{public:CDynamicArrays();virtual ~CDynamicArrays();/// 线性表类方法/**线性表抽象后的方法初始化表 ///< 用类初始化表代替求表长 ///< size_t getElementCount();拿元素 ///< T& operator [](size_t nIndex);求前驱 ///< T& prev(T&);求后继 ///< T& next(T&);插入 ///< bool insert(size_t nIndex, int data);删除 ///< bool clear();是否为空 ///< bool IsEmpty();清空表 ///< bool clear();*/size_t getElementCount() const; ///< 求表长T& operator [](size_t nIndex); ///< 拿元素bool isEmpty(); ///< 是否为空bool clear(); ///< 清空表T& prev(IN const T& now, OUT bool& bValid) const; ///< 求前驱T& next(IN const T& now, OUT bool& bValid) const; ///< 求后继bool insert(size_t nIndex, T data); ///< 插入数据bool addTail(T data); ///< 在末尾添加void printData(); ///< 打印数据, 用于调试private:bool findData(IN const T& now, OUT size_t& nIndexNow) const; ///< 查找一个引用的索引bool IsIndexValid(size_t nIndex) const; ///< 索引是否有效/// 根据现有的数据数量, 当需要换一个更大的空间时,/// 空间的增长率是不同的size_t getNewElementGrowUpStep() const; ///< 求新数据增长的步长T* copyData(T* dest, const T* src, size_t nCount);private:size_t m_nElementCounter; ///< 元素个数size_t m_nElementCounterMax; ///< 动态数组现有空间能容纳的元素最大个数T* m_pData; ///< 数据指针T m_InValidData; ///< 无效数据, 用于返回[]的无效情况};//----------------------------------------------------------------------// 动态数组类实现//----------------------------------------------------------------------template<typename T>CDynamicArrays<T>::CDynamicArrays(): m_nElementCounter(0), m_nElementCounterMax(m_nElementCounter), m_pData(NULL), m_InValidData((T)-1){    /// 时间复杂度 O(1)}template<typename T>CDynamicArrays<T>::~CDynamicArrays(){    /// 时间复杂度 O(1)    if (NULL != m_pData)    {        delete [] m_pData;        m_pData = NULL;    }}template<typename T>bool CDynamicArrays<T>::IsIndexValid(size_t nIndex) const{    /// 时间复杂度 O(1)bool isInValid = ((0 == getElementCount())|| (nIndex > (getElementCount() - 1))|| (NULL == m_pData));return !isInValid;}template<typename T>size_t CDynamicArrays<T>::getElementCount() const{    /// 时间复杂度 O(1)return m_nElementCounter;}template<typename T>T& CDynamicArrays<T>::operator [](size_t nIndex){    /// 时间复杂度 O(1)if (!IsIndexValid(nIndex)){m_InValidData = (T)-1; ///< 重新赋值, 防止被改写后再用return m_InValidData;}return m_pData[nIndex];}template<typename T>bool CDynamicArrays<T>::isEmpty(){    /// 时间复杂度 O(1)return ((0 == getElementCount()) && (NULL == m_pData));}template<typename T>bool CDynamicArrays<T>::clear(){    /// 时间复杂度 O(1)if (isEmpty()){return false;}m_InValidData = (T)-1;m_nElementCounter = 0;if (NULL != m_pData){delete []m_pData;m_pData = NULL;}return true;}template<typename T>bool CDynamicArrays<T>::findData(IN const T& now, OUT size_t& nIndexNow) const{    /// 时间复杂度 O(n)bool bFind = false;size_t nIndex = 0;nIndexNow = 0;for (nIndex = 0; nIndex < getElementCount(); nIndex++){if (&now == (m_pData + nIndex)){nIndexNow = nIndex;bFind = true;break;}}return bFind;}template<typename T>T& CDynamicArrays<T>::prev(IN const T& now, OUT bool& bValid) const{    /// 时间复杂度 O(1)bool bFind = false;size_t nIndex = 0;bValid = findData(now, nIndex);if (bValid){bValid = IsIndexValid(nIndex - 1); return (bValid ? m_pData[nIndex - 1] : (T&)m_InValidData);}else{return (T&)m_InValidData;}}template<typename T>T& CDynamicArrays<T>::next(IN const T& now, OUT bool& bValid) const{    /// 时间复杂度 O(1)bool bFind = false;size_t nIndex = 0;bValid = findData(now, nIndex);if (bValid){bValid = IsIndexValid(nIndex + 1); return (bValid ? m_pData[nIndex + 1] : (T&)m_InValidData);}else{return (T&)m_InValidData;}}template<typename T>bool CDynamicArrays<T>::insert(size_t nIndex, T data){    /// 时间复杂度 O(n)bool bOk = false;T* pData = NULL;size_t nElementCounterMax = 0;if (nIndex > getElementCount()){return false;}do{if ((0 == getElementCount()) || (m_nElementCounterMax == getElementCount())){/// 再插入一个数据就越界了, 需要建立新空间nElementCounterMax += getNewElementGrowUpStep();pData = new T[nElementCounterMax];assert(NULL != pData);if (NULL == pData){printf("bp2\n");break;}/// 空间分配成功m_nElementCounterMax = nElementCounterMax;/// 拷贝现有数据到新空间if ((NULL != m_pData) && (0 != getElementCount())){/// 旧空间不足的情况m_pData = copyData(pData, m_pData, getElementCount()); }else{/// 初次分配空间的情况m_pData = pData;}}m_nElementCounter++;bOk = true;/// 将数据向后整理挪一个元素, 空出当前元素位置copyData(m_pData + nIndex + 1, m_pData + nIndex, getElementCount() - nIndex);/// 在现有空间中插入数据m_pData[nIndex] = data;} while (0);return bOk;}template<typename T>bool CDynamicArrays<T>::addTail(T data){    /// 时间复杂度 O(n)    return insert(getElementCount(), data);}template<typename T>T* CDynamicArrays<T>::copyData(T* dest, const T* src, size_t nCount){    /// 时间复杂度 O(n)size_t nIndex = 0;assert(NULL != dest);assert(NULL != src);assert(0 != nCount);/// 为了防止元素为类, 需要一个一个拷贝if ((NULL != dest)&& (NULL != src)&& (0 != nCount)){        /// 考虑覆盖的问题        if (src > dest)        {            for (nIndex = 0; nIndex < nCount; nIndex++)            {                dest[nIndex] = src[nIndex];            }        }        else        {            for (nIndex = nCount - 1; nIndex >= 0; nIndex--)            {                dest[nIndex] = src[nIndex];                if (0 == nIndex)                {                    break;                }            }        }}return dest;}template<typename T>void CDynamicArrays<T>::printData(){    /// 时间复杂度 O(n)size_t nIndex = 0;    printf("[0x%X/0x%X/0x%X]\n",        getElementCount(), m_nElementCounterMax, m_InValidData);    printf("[0x%X] ", m_pData);for (nIndex = 0; nIndex < getElementCount(); nIndex++){printf("0x%X ", m_pData[nIndex]);}printf("\n");}/// 特例 : CDynamicArrays<float>::printData()template<>void CDynamicArrays<float>::printData(){    /// 时间复杂度 O(n)    size_t nIndex = 0;        printf("[0x%X/0x%X/0x%X]\n",        getElementCount(), m_nElementCounterMax, m_InValidData);        printf("[0x%X] ", m_pData);    for (nIndex = 0; nIndex < getElementCount(); nIndex++)    {        printf("%f ", m_pData[nIndex]);    }        printf("\n");}/// 特例 : CDynamicArrays<double>::printData()template<>void CDynamicArrays<double>::printData(){    /// 时间复杂度 O(n)    size_t nIndex = 0;        printf("[0x%X/0x%X/0x%X]\n",        getElementCount(), m_nElementCounterMax, m_InValidData);        printf("[0x%X] ", m_pData);    for (nIndex = 0; nIndex < getElementCount(); nIndex++)    {        printf("%f ", m_pData[nIndex]);    }        printf("\n");}template<typename T>size_t CDynamicArrays<T>::getNewElementGrowUpStep() const{    /// 时间复杂度 O(1)size_t nGrowUpStep = 1;size_t nElementCnt = getElementCount();if (nElementCnt <= 0){nGrowUpStep = 8;}else if (nElementCnt <= 256){nGrowUpStep = 16;}else{/// 1/8的现有元素个数, M$的做法nGrowUpStep = (getElementCount() - (getElementCount() % 8)) / 8;}return nGrowUpStep;}#endif // #ifndef DYNAMIC_ARRAYS_H_


0 0
原创粉丝点击