顺序表(SeqList)的理解以及实现

顺序表(SeqList)的理解以及实现

数据结构是计算机存储,组织数据的方式

空间占用尽量少,以节省计算机内存。数据操作尽可能快速,涵盖数据访问、添加、删除、更新等。提供简洁的数据表示和逻辑信息,以便算法高效运行。链表相较于数组,在数据添加和删除操作上更加便捷,但牺牲了数据访问速度。图相较于链表,提供了更丰富的逻辑信息,但需要占用更大的内存空间。可以看出:数据结构的设计是一个充满权衡的过程

其实数组就是简单的数据结构,一个数组就可以去维护同类型的n个数据,顺序表的底层就是数组,顺序表是对数组的封装

顺序表的概念与结构:

线性表:

线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是⼀种在实际中⼴泛使⽤的数据结构,常⻅的线性表:顺序表、链表、栈、队列、字符串...

线性表在逻辑上是线性结构,也就说是连续的⼀条直线。但是在物理结构上并不⼀定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储

顺序表的物理结构是连续的,逻辑结构一定是连续的

顺序表的分类:

顺序表的底层是数组,那么顺序表和数组有什么区别呢?

顺序表的底层结构是数组,对数组的封装,实现了常⽤的增删改查等接⼝(升级了,也方便了对数组的功能使用)

静态顺序表

静态顺序表(在栈上开空间)缺陷:空间给少了不够⽤,给多了造成空间浪费

其实C++提供了array(静态数组),与C语言的a[]有着区别:

#include

using namespace std;

int main()

{

arraya1;

int a2[10];

//区别于越界检查的问题:

//对于静态数组,抽查,正常是在数组后面设置两个标志位

//越界读不检查,越界写检查

cout << a2[10] << endl;

a2[10] = 10;

a2[20] = 10;

//array越界读写都可以检查

//原因是array底层的operator[]加了检查

a1[10];

a1[12] = 10;;

return 0;

}

动态顺序表

动态内存管理,开辟空间:按需申请空间(在堆上开空间)

顺序表带来的问题:

中间/头部的插⼊删除,时间复杂度为O(N) 增容需要申请新空间,拷⻉数据,释放旧空间。会有不⼩的消耗。 增容⼀般是呈2倍的增⻓,势必会有⼀定的空间浪费。例如当前容量为100,满了以后增容到200,我们再继续插⼊了5个数据,后⾯没有数据插⼊了,那么就浪费了95个数据空间。

如何保证程序结束后,历史通讯录信息不会丢失?

为了更直接的体现问题以及思考,下面基于动态顺序表来实现通讯录进而更好的解决问题:

功能要求:

⾄少能够存储100个⼈的通讯信息 能够保存⽤⼾信息:名字、性别、年龄、电话、地址等 增加联系⼈信息 删除指定联系⼈ 查找制定联系⼈ 修改指定联系⼈ 显⽰联系⼈信息历史数据不丢失,要注意指针(传址调用,而不是传值调用),引用便是很好的解决方法(4)

顺序表(例如数组)确实存在一些性能问题,特别是在进行中间或头部的插入和删除操作时,因为这些操作通常需要移动大量元素以维持顺序表的连续性,导致时间复杂度为O(N)。此外,顺序表的增容操作也可能导致性能问题,因为需要申请新空间、复制数据和释放旧空间,这个过程同样需要时间,并且可能会造成空间浪费。

针对这些问题,可以考虑以下几种解决方案:

使用动态数组:动态数组(如C++中的`std::vector`或Java中的`ArrayList`)可以在一定程度上解决增容问题。它们会在需要时自动增加容量,并且通常会使用一种非线性增长策略(例如,每次增加50%的容量),以减少增容操作的频率和空间浪费。使用链表:链表可以提供更灵活的插入和删除操作,因为它们不需要移动其他元素。链表的插入和删除操作的时间复杂度为O(1),前提是你已经有了要操作的节点的引用。使用平衡树结构:如红黑树、AVL树等,它们可以在保持元素有序的同时,提供对数级别的插入、删除和查找操作。使用哈希表:哈希表提供了平均情况下常数时间的插入、删除和查找操作,但它们不保持元素的顺序。使用跳表:跳表是一种概率型数据结构,它可以提供快速的查找、插入和删除操作,并且保持了有序性。

关于如何保证程序结束后,历史通讯录信息不会丢失,可以采取以下措施:

持久化存储:将通讯录信息存储在文件系统或数据库中,这样即使程序关闭,信息也不会丢失。定期备份:定期将通讯录信息备份到其他存储介质,如外部硬盘或云存储服务。事务日志:使用事务日志记录所有的修改操作,以便在程序崩溃或数据损坏时可以从日志中恢复数据。数据同步:如果通讯录信息分布在多个设备或服务上,确保它们之间定期同步,以防止单点故障导致数据丢失。选择合适的数据结构和存储策略,可以有效地解决顺序表带来的问题,并确保数据的安全性和可靠性。

通讯录的实现代码:

插入操作:

铺垫:

bool IsFull()

{

return _size == _capacity;

}

size_t size()

{

return _size;

}

// 开空间

void reserve(size_t n)

{

size_t old_size = size();

T* tmp = new T[n];

for (size_t i = 0; i < old_size; i++)

{

tmp[i] = _arr[i];// 调用赋值:释放旧空间,拷贝新空间

}

delete[] _arr;

_arr = tmp;

_capacity = n;

}

尾插// 尾插一个数据

void push_back(const T& x)

{

if (IsFull())

{

reserve(_capacity == 0 ? 4 : _capacity * 2);

}

_arr[_size] = x;

_size++;

}

头插//头插一个数据

void push_front(const T& x)

{

if (IsFull())

{

reserve(_capacity == 0 ? 4 : _capacity * 2);

}

for (int i = size(); i > 0; i--)

{

_arr[i] = _arr[i - 1];

}

_arr[0] = x;

_size++;

}

指定位置前插入 //在指定位置之前插入数据

void insert(size_t pos, const T& x)

{

assert(pos <= size() && pos >= 0);

if (IsFull())

{

reserve(_capacity == 0 ? 4 : _capacity * 2);

}

for (int i = size(); i > pos; i--)

{

_arr[i] = _arr[i - 1];

}

_arr[pos] = x;

_size++;

}

删除操作:

尾删//尾删

void pop_back()

{

assert(_arr && _size > 0);

_size--;

}

头删//头删

void pop_front()

{

assert(_arr && _size > 0);

for (int i = 0; i

{

_arr[i] = _arr[i + 1];

}

_size--;

}

在指定位置删除数据//指定位置删除

void erase(size_t pos)

{

assert(pos >= 0 && pos < size());

for (int i = pos; i < size() - 1; i++)

{

_arr[i] = _arr[i + 1];

}

_size--;

}

顺序表实现代码:

#pragma once

#include

#include

using namespace std;

namespace home

{

// 动态顺序表

template

class SeqList

{

public:

// 全缺省构造函数

SeqList(T* arr = nullptr, size_t size = 0, size_t capacity = 0)

:_arr(arr)

, _size(size)

, _capacity(capacity)

{}

// 析构函数

~SeqList()

{

delete[] _arr;

_arr = nullptr;

_size = _capacity = 0;

}

const T& operator[](size_t pos) const

{

assert(pos < _size);//防止越界

return _arr[pos];

}

bool IsFull()

{

return _size == _capacity;

}

bool empty()

{

return _size == 0;

}

size_t size()

{

return _size;

}

// 开空间

void reserve(size_t n)

{

size_t old_size = size();

T* tmp = new T[n];

for (size_t i = 0; i < old_size; i++)

{

tmp[i] = _arr[i];// 调用赋值:释放旧空间,拷贝新空间

}

delete[] _arr;

_arr = tmp;

_capacity = n;

}

// 尾插一个数据

void push_back(const T& x)

{

if (IsFull())

{

reserve(_capacity == 0 ? 4 : _capacity * 2);

}

_arr[_size] = x;

_size++;

}

//头插一个数据

void push_front(const T& x)

{

if (IsFull())

{

reserve(_capacity == 0 ? 4 : _capacity * 2);

}

for (int i = size(); i > 0; i--)

{

_arr[i] = _arr[i - 1];

}

_arr[0] = x;

_size++;

}

//尾删

void pop_back()

{

assert(_arr && _size > 0);

_size--;

}

//头删

void pop_front()

{

assert(_arr && _size > 0);

for (int i = 0; i < size() - 1; i++)

{

_arr[i] = _arr[i + 1];

}

_size--;

}

//在指定位置之前插入数据

void insert(size_t pos, const T& x)

{

assert(pos <= size() && pos >= 0);

if (IsFull())

{

reserve(_capacity == 0 ? 4 : _capacity * 2);

}

for (int i = size(); i > pos; i--)

{

_arr[i] = _arr[i - 1];

}

_arr[pos] = x;

_size++;

}

//指定位置删除

void erase(size_t pos)

{

assert(pos >= 0 && pos < size());

for (int i = pos; i < size() - 1; i++)

{

_arr[i] = _arr[i + 1];

}

_size--;

}

//通通删掉

void clear()

{

for (int i = 0; i < size(); i++)

{

pop_back();

}

_size = 0;

}

//查找

int find(const T& x)

{

assert(_arr);

for (int i = 0; i < size(); i++)

{

if (x == _arr[i])

{

return i;

}

}

return -1;

}

//打印

void Print()

{

assert(_arr);

for (int i = 0; i < size(); i++)

{

cout << _arr[i] << " ";

}

cout << endl;

}

private:

T* _arr;

size_t _size;// 顺序表当前有效的数据个数

size_t _capacity;// 当前顺序表的容量

};

}

通讯录项目:

#include"SeqList.h"

#include

struct character_information

{

string _name;

string _gender;

size_t _age;

string _phone_code;

string _address;

};

int main()

{

cout << "---------通讯录----------" << endl;

home::SeqList sl;

int n = 0;

cin >> n;

while (n--)

{

struct character_information infor;

cout << "name:" << endl;

cin >> infor._name;

cout << "gender:" << endl;

cin >> infor._gender;

cout << "age:" << endl;

cin >> infor._age;

cout << "phone_code:" << endl;

cin >> infor._phone_code;

cout << "address:" << endl;

cin >> infor._address;

sl.push_back(infor);

}

//sl.Print();原有不可用

//...

return 0;

}

相关推荐