顺序表的实现_数组
#include <iostream> using namespace std; #define InitSize 10 //动态数组的初始化尺寸 #define IncSize 5 //当动态数组存满数据后每次扩容的元素个数 /* //静态数组来保存顺序表中的元素 typedef struct { int m_data[10];//10个位置 int m_length;//顺序表中当前实际长度,当前顺序表中存储的元素个数 }SeqList01; //动态数组来保存顺序表中的元素 typedef struct { int *m_pData;//顺序表中的元素保存在m_pData指向的内存空间中 int m_length;//顺序表中存储元素的实际长度 int m_maxSize;//动态数组的最大容量,动态数组可以扩容,记录该值 }SeqList02; */ template <typename T>//T表示数组中的元素类型 class SeqList { public: SeqList(int length=InitSize);//构造函数,参数可以有默认值 ~SeqList();//析构函数 public: bool ListInsert(int i, const T&e);//在第i个位置插入指定元素e bool ListDelete(int i);//删除第i个位置的元素 bool GetElement(int i, T&e);//获取第i个元素的值 int LocateElement(const T&e);//按照元素值查找其在顺序表中出现的位置 void DisaplayList();//输出线性表中的所有数据 int GetListLength();//获取线性表的长度 void ReverseList();//翻转线性表 void TraverseList();//遍历数组中的元素,并输出 private: void IncreaseSize();//当顺序表存储数据满,调用次函数为书虚表扩容。 private: T *m_pData;//顺序表中的元素保存在m_pData指向的内存空间中 int m_length;//顺序表中存储元素的实际长度 int m_maxSize;//动态数组的最大容量,动态数组可以扩容,记录该值 }; //在外面进行函数的定义 template<typename T> SeqList<T>::SeqList(int length) { m_pData = new T[length];//为一维数组动态分配内存 m_length = 0; //顺序表当前长度为0,表示还没存入任何数据元素 m_maxSize = length; //当前最多可以存入的数据的个数m_maxSize } //通过析构函数来对线性表进行资源释放 template<typename T> SeqList<T>::~SeqList() { delete[]m_pData; //将数组中的元素个数归为0; m_length = 0; } /* 在第i个位置后面插入元素e,时间复杂度为O(n),时间开销主要源于元素的移动。 如插入位置为3的位置,则3后面的元素都需要移动。 注意:数组的下标从0开始,位置从1开始编号。所以下标和位置的对应关系是 位置-1==数组编号 */ template<typename T> bool SeqList<T>::ListInsert(int i, const T&e) { //如果顺序表的元素已经满,那么插入数据失败 if (m_length >= m_maxSize) { //cout << "顺序表中的元素已经满了,插入失败" << endl; //return false; //扩容 IncreaseSize(); } //判断插入数据的位置i是否合法,i的合法值应该从1到m_length+1之间 if ((i < 1) || (i > (m_length + 1))) { cout << "插入数据的位置不合法,请重新检查插入位置" << m_length + 1 << endl; return false; } /* 从最后一个元素向前面遍历,到插入新元素的第i个位置,分别将这些位置中元素向后移动。 如向位置为2的位置插入一个元素,那么就是插入到数组中编号为1的位置, 向位置为i的位置插入一个元素,那么就是插入到数组中编号为i-1的位置, 如数组长度为5,向第2个位置插入数据,则需要将数组标号为1的元素向后依次移动。 分析时间复杂度为(1+2+3+4+....(n-1)+n)/(n+1)= n/2 */ for (int j = m_length; j >= i; j--) { m_pData[j] = m_pData[j-1]; } //在位置为i的位置插入元素,因为数组下标从0开始,所以存储在数组中的位置是i-1 m_pData[i-1] = e; cout << "成功在位置为i==" << i << "的位置插入元素" << e << endl; //将数组中的存储元素的个数增加1 m_length++; cout << "当前数组中元素的个数"<<m_length << endl; return true; } /* 删除第i个位置的元素,则后面的元素需要一次前移动 */ template<typename T> bool SeqList<T>::ListDelete(int i) { //判断线性表是否为空,如果元素的个数为空,则提示不能删除 if (m_length < 1) { cout << "线性表为空,删除失败" << endl; return false; } //判断删除元素的位置是否合法,i<1或者i>m_length,则不合法 if ((i < 1) || (i > m_length)) { cout << "删除的位置" << i << "不合法" << "删除的元素应该在" << i << "到" << m_length << "之间" << endl; return false; } cout << "删除元素i==" << i << "位置元素" << m_pData[i - 1] << "成功" << endl; //执行删除元素的代码,删除i位置,则存储在数组中是i-1,则后面的元素都需要向前面移动 for (int j = i; j < m_length; j++) { m_pData[j - 1] = m_pData[j]; } //拷贝完毕,最后一个位置的元素应该删除,否则最后一个元素数值不为0 m_pData[m_length - 1] = 0; m_length--; //注意这里的元素已经删除,输出的是删除元素之后的下一个元素 //cout << "删除元素i==" << i << "位置元素" << m_pData[i - 1] << "成功" << endl; cout << "删除元素i==" << i << "位置元素成功" << endl; return true; } //获取第i个位置的元素值,并使用e返回 template<typename T> bool SeqList<T>::GetElement(int i, T & e) { //判断数组的长度 if (m_length < 1) { cout << "线性表的长度为0,不能获取元素" << endl; return false; } //判断获取的位置是否合法 if ((i < 1) || i > m_length) { cout << "获取的位置不合法" << endl; return false; } e = m_pData[i - 1];//第i个位置保存在数组中位置为i-1 cout << "成功获取位置为i==" << i <<"的元素"<< endl; return true; } //按照元素值查找其在顺序表中出现的位置 template<typename T> int SeqList<T>::LocateElement(const T&e) { for (int k = 0; k < m_length; k++) { if (e == m_pData[k]) { //e = m_pData[k]; cout << "线性表中存在元素值为" << e << "的元素" << endl; return k+1;//k为数组中的存储位置,返回值应该加1,表示是第几个元素 } } cout << "线性表中不存在元素值为" << e << "的元素" << endl; return 0; } //遍历输出 template<typename T> void SeqList<T>::DisaplayList() { TraverseList(); } //获取线性表的长度 template<typename T> int SeqList<T>::GetListLength() { return m_length; } //反转线性表, template<typename T> void SeqList<T>::ReverseList() { //翻转数组中的元素 编号为i的位置和编号为数组总编号-i的位置进行交换(m_length-1数组最高的位置的编号) T tep; for (int i = 0; i < m_length/2; i++)//这里如果没有 /2,会交换两次==等价于没交换 { tep = m_pData[i]; m_pData[i] = m_pData[m_length - 1 - i]; m_pData[m_length - 1 - i] = tep; } } //数组元素的遍历输出 template<typename T> void SeqList<T>::TraverseList() { for (int k = 0; k < m_length; k++) { cout << m_pData[k] << endl; } } template<typename T> void SeqList<T>::IncreaseSize() { T *p = m_pData; m_pData = new T[m_maxSize + IncSize];//重新为线性表分配更大的内存空间 for (int i = 0; i < m_length; i++) { //把数据搬移过去 m_pData[i] = p[i]; } //设置最大存储数据的数量 m_maxSize = m_maxSize + IncSize; //释放原来的内存空间 delete[]p; } int main() { SeqList<int>* seqList = new SeqList<int>(10); //注意插入空线性表只能从第一个位置开始插入,否则会报错 seqList->ListInsert(1, 1111); seqList->ListInsert(2, 2222); seqList->ListInsert(3, 3333); seqList->ListInsert(4, 4444); seqList->TraverseList(); seqList->ListDelete(2); seqList->TraverseList(); //测试获取元素的位置 int value = 0; seqList->GetElement(3, value); cout << "value=="<<value << endl; //查找线性表中是否包含e元素,并将值返回 int number01= seqList->LocateElement(3333); cout << "number01==" << number01 << endl; //翻转数组 cout << "-----------------------------" << endl; seqList->TraverseList(); cout << "*****************************" << endl; seqList->ReverseList(); seqList->TraverseList(); cout << "扩容*****************************" << endl; //测试扩容函数 for (int i = 1; i < 30; i++) { seqList->ListInsert(i, i * 3); } seqList->TraverseList(); std::cout << "Hello World!\n"; return 0; } /* 2021年11月8日21点28分 */
在那巴山夜雨中寻一份寂静与洒脱。

浙公网安备 33010602011771号