线性表类模板实现
来源:互联网 发布:串口数据协议 编辑:程序博客网 时间: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
- 线性表类模板实现
- c++模板库线性表线性存储实现实现
- [数据结构]线性表之顺序表的类模板实现
- 类模板实现多数据类型线性链表
- [数据结构]线性表之单链表的类模板实现
- C++模板类线性表的实现与测试
- c++模板类实现线性表顺序存储
- C++类模板与线性表
- 模板链式线性表
- c++数据结构之线性表:间接寻址类模板的实现
- 【代码】模板实现动态线性表(无类型萃取)
- 【data structure】线性表简单模板c++实现
- 线性表的顺序表示和实现模板
- c++模板类实现线性表链式存储
- C++类模板实现线性表单链式存储
- 6.2 C++模板-类模板与线性表
- 类实现线性链表
- 线性表C++类实现
- 职业生涯(待续)
- OS UIAlertController 弹框 (ios 9.0 后代替了UIAlertView弹框 和 UIActionSheet下弹框)
- 用C#制作PDF文件全攻略
- Unity-插件-NGUI-常用UI界面功能(1)
- VS2008转到定义切换时运行卡死
- 线性表类模板实现
- Linux极客命令(工具篇)
- 测试用例检查单
- jQuery中的call和apply
- Linux LVM硬盘管理及LVM扩容
- 基于Tomcat7、Java、WebSocket的服务器推送聊天室
- do{...}while(0)的意义和用法
- tomcat 设置 ip 端口访问 以及 多应用设置
- Scala map sorting