C++实现动态顺序表

顺序表是在计算机内存中以数组的形式保存的线性表,是指用一组地址连续的存储单元依次存储数据元素的线性结构。这样的存储方式使得线性表逻辑上相邻的元素,其在物理存储单元中也是相邻的。只要知道了第一个元素的存储地址,就可以知道线性表中任何一个元素的存储地址。本文利用C++语言,在Windows平台 Visual Studio 2015开发环境下实现。功能:应用C++语言实现顺序表的各项操作。基本的成员函数:构造函数、拷贝构造函数、赋值运算符的重载、析构函数。

// 顺序表构造成功之后,里面存放了n个元素data
Vector(size_t n, const DataType& data = DataType());
Vector(const Vector& v);  
Vector& operator=(const Vector& v);
~Vector();

void PushBack(const DataType& data);  //尾插
void PopBack();  //尾删

void Print()//打印顺序表

// 给顺序表重新赋值,该函数执行完里面存放了n个元素data
void Assign(size_t n, const DataType& data);

// 在顺序表的pos位置上插入元素data
void Insert(size_t pos, const DataType& data);

// 删除顺序表pos位置上的元素
void Erase(size_t pos);

// 改变顺序表中的元素为n个,如果n>原来顺序表中的元素的个数,多出来的空间用data来填充
void ReSize(size_t n, const DataType& data = DataType());

// 清空顺序表中的元素-->请自己动手验证是否需要清理vector中的空间
void Clear();

// 返回顺序表中有效元素的大小
size_t Size()const;

// 返回顺序表中空间容量的大小
size_t Capacity()const;

// 顺序表是否为空,若为空返回true,否则返回null
bool Empty()const;

// 通过下边访问顺序表index位置上的元素。 思考为什么要成对的来重载
DataType& operator[](size_t index);
const DataType& operator[](size_t index)const;

// 返回顺序表中第一个元素的引用,思考为什么要返回应用,为什么要成对重载
DataType& Front();
const DataType& Front()const;

// 返回顺序表中最后一个的元素的引用,思考为什么要返回引用,为什么要成对重载
DataType& Back();
const DataType& Back()const;

void _CheckCapacity()// 动态扩容

int Find(const DataType & data)//查找数据

  1 #ifndef __VECTOR_H__
  2 #define __VECTOR_H__
  3
  4 #include<iostream>
  5 #include<stdio.h>
  6 #include<assert.h>
  7 using namespace std;
  8
  9 #define COW 4
 10 typedef int DataType;
 11
 12 class Vector
 13 {
 14 public:
 15     Vector()
 16         : _array(NULL)
 17         , _size(0)
 18         , _capacity(0)
 19     {}
 20
 21     // 顺序表构造成功之后,里面存放了n个元素data
 22     Vector(size_t n, const DataType& data = DataType())
 23     {
 24             _array = new DataType[n];
 25             _size = n;
 26             _capacity = n;
 27             for(size_t i = 0; i<n;i++)
 28             _array[i] = data;
 29
 30     }
 31     Vector(const Vector& v)
 32         :_array(new DataType[v._size])
 33         , _size(v._size)
 34         ,_capacity(v._capacity)
 35     {
 36         memcpy(_array, v._array, sizeof(DataType)*_size);
 37     }
 38     Vector& operator=(const Vector& v)
 39     {
 40         if (this != &v)
 41         {
 42             DataType *temp = new DataType[v._size];
 43             temp = v._array;
 44             delete[] _array;
 45             _array = temp;
 46             _size = v._size;
 47             _capacity = v._capacity;
 48             memcpy(_array, v._array, sizeof(DataType)*_size);
 49         }
 50         return *this;
 51     }
 52     ~Vector()
 53     {
 54         if (_array)
 55         {
 56             delete[] _array;
 57             _array = NULL;
 58             _size = 0;
 59             _capacity = 0;
 60         }
 61     }
 62
 63 public:
 64     void PushBack(const DataType& data)
 65     {
 66         _CheckCapacity();
 67         _array[_size++] = data;
 68     }
 69     void PopBack()
 70     {
 71         assert(!Empty());
 72         --_size;
 73     }
 74     void Print()
 75     {
 76         for (size_t i = 0; i < _size; ++i)
 77         {
 78             cout << _array[i] << " ";
 79         }
 80         cout << endl;
 81     }
 82     // 给顺序表重新赋值,该函数执行完里面存放了n个元素data
 83     void Assign(size_t n, const DataType& data)
 84     {
 85         assert(n<_size);
 86         for (size_t i = 0; i<n; i++)
 87             _array[i] = data;
 88     }
 89
 90     // 在顺序表的pos位置上插入元素data
 91     void Insert(size_t pos, const DataType& data)
 92     {
 93         assert(pos<_size);    //需检验pos的合法性
 94         _CheckCapacity();
 95         if (pos == _size - 1)  //在最后一个位置插入数据等于尾插
 96         {
 97             PushBack(data);
 98             return;
 99         }
100         else
101         {
102             for (size_t i = _size; i > pos; --i)
103             {
104                 _array[i] = _array[i - 1];
105             }
106             _array[pos] = data;
107             _size++;
108         }
109     }
110
111     // 删除顺序表pos位置上的元素
112     void Erase(size_t pos)
113     {
114         assert(pos<_size);    //需检验pos的合法性
115         if (pos == _size - 1)  //在最后一个位置删除数据等于尾删
116         {
117             PopBack();
118             return;
119         }
120         else
121         {
122             for (size_t i = pos; i < _size - 1; i++)
123             {
124                 _array[i] = _array[i + 1];
125             }
126             --_size;
127         }
128     }
129
130     // 改变顺序表中的元素为n个,如果n>原来顺序表中的元素的个数,多出来的空间
131     // 请用data来填充
132     void ReSize(size_t n, const DataType& data = DataType())
133     {
134         if (n > _size)
135         {
136             size_t i = _size;
137             _size = n;
138             _CheckCapacity();
139             for (i; i < n; i++)
140                 _array[i] = data;
141         }
142         else
143         {
144             size_t i = n;
145             for(i; i<_size; i++)
146                 PopBack();
147         }
148     }
149
150     // 清空顺序表中的元素-->请自己动手验证是否需要清理vector中的空间
151     void Clear()
152     {
153         delete[] _array;
154         _array = NULL;
155         _size = 0;
156         _capacity = 0;
157     }
158     // 返回顺序表中有效元素的大小
159     size_t Size()const
160     {
161         return _size;
162     }
163     // 返回顺序表中空间容量的大小
164     size_t Capacity()const
165     {
166         return _capacity;
167     }
168     // 顺序表是否为空,若为空返回true,否则返回null
169     bool Empty()const
170     {
171         return _size == 0;
172     }
173
174     // 通过下边访问顺序表index位置上的元素
175     // 思考为什么要成对的来重载
176     DataType& operator[](size_t index)
177     {
178         assert(index);
179         return _array[index];
180     }
181     const DataType& operator[](size_t index)const
182     {
183         assert(index);
184         return _array[index];
185     }
186     // 返回顺序表中第一个元素的引用,思考为什么要返回应用,为什么要成对重载
187     DataType& Front()
188     {
189         return _array[0];
190     }
191     const DataType& Front()const
192     {
193         return _array[0];
194
195     }
196     // 返回顺序表中最后一个的元素的引用,思考为什么要返回引用,为什么要成对重载
197     DataType& Back()
198     {
199         return _array[_size - 1];
200     }
201     const DataType& Back()const
202     {
203         return _array[_size - 1];
204     }
205 private:
206     // 动态扩容-->该函数中有坑,请找出坑在哪?
207     void _CheckCapacity()
208     {
209         // 2*_capacity  有问题?
210         if (_size >= _capacity)
211         {
212             DataType* pTemp = new DataType[_capacity * 2];
213             //memcpy(pTemp, _array, _size*sizeof(DataType));
214             for (size_t index = 0; index < _size; ++index)
215                 pTemp[index] = _array[index];
216             delete[] _array;
217             _array = pTemp;
218             _capacity *= 2;
219         }
220     }
221     int Find(const DataType & data)
222     {
223         assert(_array != NULL);
224         for (size_t i = 0; i < _size; i++)
225         {
226             if (_array[i] == data)
227                 return i;
228         }
229         return -1;
230     }
231 private:
232     DataType* _array;
233     size_t _size;  // 保存有效元素的个数
234     size_t _capacity;  // 空间的实际大小
235 };
236
237 #endif //__VECTOR_H__

代码当中存在的问题将在下一篇文章中探讨。

时间: 2024-12-29 07:36:45

C++实现动态顺序表的相关文章

c实现的动态顺序表

第一篇文章中用c实现了静态顺序表,但是使用静态顺序表还有不足的地方.当我们需要存储的数据很少时,如果静态顺序表的数组容量较大就会造成空间的浪费:当我们需要存储的数据很多时,如果静态顺序表的数组容量较小可能就会造成数据丢失.所以一般情况我们应该尽量把顺序表实现成动态的.需要多大容量就开辟多大容量. 静态顺序表和动态顺序表只有以下函数不同: 1.定义结构体时,多定义一个capacity,并对capacity进行初始化和增加大小的设置: #define INIT_CAPACITY 3 #define 

C语言:【动态顺序表】动态顺序表的初始化、打印、尾插PushBack、尾删PopBack

#include<stdio.h> #include<stdlib.h> #include<assert.h> #include<string.h> #include<malloc.h> typedef int DateType; typedef struct SeqList {     DateType *arr;     size_t capacility;     size_t size; }SeqList; //创建空间 void Che

动态顺序表 与 双向链表的模板类

//////////////////////////////////////////////////////////////////////// /////////////////////泛型编程之动态顺序表的模板///////////////////////// //////////////////////////////////////////////////////////////////////// #include<iostream> #include<string> u

静态顺序表和动态顺序表

实现一个静态顺序表,首先,要定义一个保存数据的数组,保存在结构体中,用size来存储数组中的元素个数, typedef struct SeqList { DataType array[MAX_SIZE]; size_t size; }SeqList; 首先来实现一下静态顺序表的初始化函数,可以借用系统的memset函数来实现,开辟一块空间全部初始化为0,没有存入数据所以size也为0 void InitSeqList(SeqList *pSeq) { assert(pSeq); memset(p

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

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

动态顺序表(可分配内存空间)

<strong style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">前几天写了一个静态顺序表,但是觉得一开始开辟很大一部分空间却不一定可以完全用得上,会造成很大的内存浪费,于是写了一个可以自动开辟内存空间的动态顺序表作为改进.</strong> "DynamicSeqllist.h" #pragma once #def

实现动态顺序表

SeqList.h #pragma once #include<stdio.h> #include<string.h> #include<assert.h> #include<malloc.h>   typedef int DataType; typedef struct SeqList { DataType* arry; size_t size; size_t capacity; }SeqList;   void check(SeqList*Seq);//

数据结构—动态顺序表的实现

前面我们实现了顺序表,但是我们应该会考虑到一个问题,顺序表一次性创建那么大空间造成的浪费很多,所以在这里,我们需要一个可以动态增长的顺序表来满足我们的需求! 实现中需要注意的是:在这里我们要注意的是首先你应该给顺序表一个容量,当每次满了的时候,进行扩容! 另外,在这里我分别使用了三种的排序算法:插入排序,选择排序,冒泡排序. dynamic_seqlist.h #define _CRT_SECURE_NO_WARNINGS 1 #ifndef __DYNAMIC_SEQLIST_H__ #inc

C++模板实现动态顺序表(更深层次的深浅拷贝)与基于顺序表的简单栈的实现

前面介绍的模板有关知识大部分都是用顺序表来举例的,现在我们就专门用模板来实现顺序表,其中的很多操作都和之前没有多大区别,只是有几个比较重要的知识点需要做专门的详解. 1 #pragma once 2 #include<iostream> 3 #include<string> 4 #include<stdlib.h> 5 using namespace std; 6 7 template <class T> 8 class Vector 9 { 10 publ