数据结构详解:线性表的C++实现

 2024-03-20 02:05:27  阅读 0

1.线性表的定义

线性表:零个或多个数据元素的有限序列。

线性列表,包括顺序列表和链表

序列表(实际上是一个数组)中元素的地址是连续的。

链表中节点的地址不连续,通过指针连接。

2.线性表的抽象数据类型

线性表的抽象数据类型定义如下:

ADT线性表(List)

数据

线性表的数据对象集合为{a1,a2,....,an},每个元素的类型为。 其中,除第一个元素a1外,每个元素都有且仅有一个直接前驱元素,除最后一个元素an外,每个元素都有且仅有一个直接后继元素。 数据元素之间的关系是一对一的关系。

(*L):创建空线性表的初始化操作。

(L):如果线性表为空,则返回true,否则返回false。

(*L):清除线性表。

(L,i,*e):返回线性表L中第i个位置元素到e。

(L,e):在线性表L中搜索等于给定值e的元素。 如果查找成功,则返回该元素在表中的序号; 否则返回0表示失败。

(*L,i,e):在线性表的第i个位置插入元素e。

(*L,i,*e):删除线性列表L中的第i个元素,并使用e返回其值

(L):返回线性表L的元素数量。

(L):打印线性表

对于不同的应用,线性表的基本操作是不同的,以上操作是最基本的。

对于实际问题中涉及到的更复杂的线性表运算,完全可以使用这些基本运算的组合来实现。

3、线性表的顺序存储

1. 顺序存储定义

序列表一般使用数组来实现。 其实就是在内存中找到一个起始地址,然后以占位符的形式占据一定的连续内存空间,然后将相同数据类型的数据元素依次放置在这个空的空间中。 ,指定数组大小有两种方式,一种是静态分配,一种是动态扩展。

与序列表相关的操作与数组相关,一般是移动数组元素。

数组线性表和数组的区别_数组线性表关系怎么写_数组与线性表的关系

2.如何实现顺序存储

结构

我们直接看序列表的模板类的代码:

常量整数 = 100;

班级

:

(){=0;} //无参构造函数

(a[],int n); //带参数的构造方法

~(){} //析构函数

int (){ ;} //线性表长度

获取(int i); //按位查找

整数(x); //按值搜索

无效(int i,x); //插入

(int i); //删除

空白 (); //遍历

:

数据[]; //序列表是使用数组实现的

整数; //存储顺序表的长度

};

序列表的封装需要三个属性:

存储空间的起始位置。数组数据的存储位置就是线性表存储空间的存储位置。

线性表最大存储容量.数组长度

线性表的当前长度。

注意:数组的长度与线性表当前的长度不同。 数组的长度是存储线性表的存储空间的总长度,初始化后一般不会改变。 线性列表的当前长度是线性列表中元素的数量,该长度会发生变化。

下面我们来实现序列表的各个功能:

构造参数:

创建一个长度为n的序列表,需要将给定的数组元素作为线性表的数据元素传入序列表,并以传入的元素个数作为序列表的长度。

::(a[],int n)

if(n>) 抛出“错误”;

for(int i=0;i

数据[i]=a[i];

=n;

按位搜索

按位查找的时间复杂度为O(1)O(1)。

::获取(int i)

if() 抛出“错误”;

否则数据[i-1];

按值查找

按值搜索需要按顺序比较序列列表中的元素。

整数::(x)

for(int i=0;i

if(数据[i]==x) i+1;

0;

插入

在插入过程中,需要注意元素移动的方向。 您必须从最后一个元素开始移动。 如果表已满,就会发生溢出; 如果插入位置不合理,就会出现位置异常。

无效 ::(int i, x)

if(>=) 抛出“”;

if(+1) 抛出“”;

for(int j=;j>=i;j--)

数据[j]=数据[j-1];

数据[i-1]=x;

++;

删除

注意算法中元素的移动方向。 移动元素之前必须先取出已删除的元素。 如果表为空,就会发生下溢。 如果删除位置不合理,就会出现删除位置异常。 ·

::(整数我)

整数x;

if(==0) 抛出“”;

if() 抛出“”;

x = 数据[i-1];

for(int j=i;j

数据[j-1] = 数据[j];

--;

X;

遍历

按下标按顺序输出每个元素

空白 ::()

for(int i=0;i

)抛出“错误”;

for(int i=0;i

数据[i]=a[i];

=n;

::获取(int i)

if() 抛出“错误”;

否则数据[i-1];

整数::(x)

for(int i=0;i

if(数据[i]==x) i+1;

0;

无效 ::(int i, x)

if(>=) 抛出“”;

if(+1) 抛出“”;

for(int j=;j>=i;j--)

数据[j]=数据[j-1];

数据[i-1]=x;

++;

::(整数我)

整数x;

if(==0) 抛出“”;

if() 抛出“”;

x = 数据[i-1];

for(int j=i;j

数据[j-1] = 数据[j];

--;

X;

空白 ::()

for(int i=0;i

= 空;

头插入法构造单链表

头插入方式是每次将新申请的节点插入到头节点后面

数组线性表和数组的区别_数组与线性表的关系_数组线性表关系怎么写

::(a[], int n)

首先=新节点;

第一个->下一个= NULL;

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

节点 *s = 新节点;

s->数据 = a[i];

s->下一个=第一个->下一个;

第一个->下一个 = s;

尾部插入法构造单链表

尾插法是每次将新申请的节点插入到终端节点后面

数组线性表和数组的区别_数组与线性表的关系_数组线性表关系怎么写

::(a[], int n)

首先=新节点;

节点 *r = 第一个;

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

节点 *s = 新节点;

s->数据 = a[i];

r->下一个=s;

r = s;

r->下一个=NULL;

析构函数

单链表类中的节点是使用new申请的,释放时不能自动释放。 因此,析构函数必须释放单链表中的节点空间。

::~()

而(第一个!= NULL)

节点* q = 第一个;

第一个=第一个->下一个;

q;

计算长度

单链表中无法直接求出长度,所以我们只能扫描一次单链表,所以时间复杂度为O(n)O(n)

数组与线性表的关系_数组线性表和数组的区别_数组线性表关系怎么写

整数::()

节点* p = 第一个->下一个;

整数计数=0;

而(p!= NULL)

p = p->下一个;

计数++;

数数;

按位搜索

即使知道单链表中的节点位置,也无法直接访问它。 需要从头指针开始向下一一查找。 平均时间性能为 O(n)O(n)。 单链表是一种顺序访问结构。

::获取(int i)

节点* p = 第一个->下一个;

整数计数=1;

while (p != NULL && 计数

p = p->下一个;

计数++;

if (p == NULL) 抛出“”;

否则p->数据;

按值查找

单链表中按值查找的实现方法与顺序表类似。 链表中的元素按顺序进行比较,平均时间性能为O(n)O(n)。

整数::(x)

节点 *p = 第一个->下一个;

整数计数=1;

而(p!= NULL)

if (p->data == x) 计数;

p = p->下一个;

计数++;

0;

插入

在单链表的插入过程中,需要注意分析表头、表中、表尾三种情况。 由于单向链表取头结点,因此这三种情况的操作语句是相同的。 不需要特殊处理,时间复杂度为O(n )O(n)

数组线性表和数组的区别_数组与线性表的关系_数组线性表关系怎么写

无效 ::(int i, x)

节点 *p = 第一个;

整数计数=0;

while (p != NULL && 计数

p = p->下一个;

计数++;

if (p == NULL) 抛出“”;

别的 {

节点 *s = 新节点;

s->数据=x;

s->下一个 = p->下一个;

p->下一个=s;

删除

删除时需要注意表尾的特殊情况。 此时,虽然被删除的节点不存在,但其前驱节点却存在。 因此,只有当被删除节点的前驱节点存在且不是终端节点时,才能判断被删除节点的存在,时间复杂度为O(n)O(n)。

数组与线性表的关系_数组线性表关系怎么写_数组线性表和数组的区别

::(整数我)

节点 *p = 第一个;

整数计数=0;

while (p != NULL && 计数

p = p->下一个;

计数++;

if (p == NULL || p->next == NULL) 抛出 "";

别的 {

节点 *q = p->下一个;

int x = q->数据;

p->下一个=q->下一个;

X;

遍历

遍历单链表的时间复杂度是O(n)O(n)。

数组线性表和数组的区别_数组线性表关系怎么写_数组与线性表的关系

空白 ::()

节点 *p = 第一个->下一个;

而(p!= NULL)

接下来计算数据;

完整代码示例(可以找到更完整的数据结构示例):

#

使用标准;

节点

数据;

节点*下一个;

};

班级

:

();

(a[], int n);

〜();

int();

获取(int i);

整数(x);

无效(int i,x);

(int i);

空白 ();

:

节点*第一个;

};

::()

首先=新节点;

第一个->下一个= NULL;

::(a[], int n)

首先=新节点;

第一个->下一个= NULL;

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

节点 *s = 新节点;

s->数据 = a[i];

s->下一个=第一个->下一个;

第一个->下一个 = s;

::~()

而(第一个!= NULL)

节点* q = 第一个;

第一个=第一个->下一个;

q;

整数::()

节点* p = 第一个->下一个;

整数计数=0;

而(p!= NULL)

p = p->下一个;

计数++;

数数;

::获取(int i)

节点* p = 第一个->下一个;

整数计数=1;

while (p != NULL && 计数

p = p->下一个;

计数++;

if (p == NULL) 抛出“”;

否则p->数据;

整数::(x)

节点 *p = 第一个->下一个;

整数计数=1;

而(p!= NULL)

if (p->data == x) 计数;

p = p->下一个;

计数++;

0;

无效 ::(int i, x)

节点 *p = 第一个;

整数计数=0;

while (p != NULL && 计数

p = p->下一个;

计数++;

if (p == NULL) 抛出“”;

别的 {

节点 *s = 新节点;

s->数据=x;

s->下一个 = p->下一个;

p->下一个=s;

::(整数我)

节点 *p = 第一个;

整数计数=0;

while (p != NULL && 计数

p = p->下一个;

计数++;

if (p == NULL || p->next == NULL) 抛出 "";

别的 {

节点 *q = p->下一个;

int x = q->数据;

p->下一个=q->下一个;

X;

空白 ::()

节点 *p = 第一个->下一个;

而(p!= NULL)

接下来计算数据;

int main()

p;

p.(1, 6);

p.(2, 9);

p.();

p.(2, 3);

p.();

库特

标签: 线性 数组 元素

如本站内容信息有侵犯到您的权益请联系我们删除,谢谢!!


Copyright © 2020 All Rights Reserved 京ICP5741267-1号 统计代码