抱歉,您的浏览器无法访问本站

本页面需要浏览器支持(启用)JavaScript


了解详情 >

线性表是由 n个相同类型的元素组成的有序集合。线性表中元素个数 n 称为线性表的长度,当时为空表。是第一个数据元素,是最后一个数据元素,的直接前驱,的直接后驱。以下为我在学习和实战练习过程中所做的笔记,可供参考。

一、线性表的特点

  1. 表中元素的个数是有限的。
  2. 表中元素的数据类型都相同,意味着每一个元素占用相同大小的空间。
  3. 表中元素具有逻辑上的顺序性,在序列中各元素排序有其先后顺序。

二、线性表的顺序表示

逻辑上相邻的两个元素在物理位置上也相邻。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#define MaxSize 50;    //定义线性表的长度
typedef int ElemType; //顺序表中元素的类型
typedef struct {
ElemType data[MaxSize]; //顺序表的元素
int length; //顺序表的当前长度
}SqList; //顺序表的类型定义

int main()
{
SqList L; //顺序表的名称
bool ret; //查看返回值
ElemType del; //用来存要删除的元素
L.data[0] = 1; L.data[1] = 2; L.data[2] = 3; //手动赋值
L.len = 3; //总共 3 个元素
ret = ListInsert(L, 2, 60); //在 L 的第 2 个位置插入元素 60
if(ret)
PrintList(L);
else
printf("插入失败\n");
ret = ListDelete(L, 1, del); //删除 L 第 1 个位置元素
if(ret)
PrintList(L);
else
printf("删除失败\n");
int pos;
pos = LocateElem(L, 60); //查找值为 60 的元素位置
printf("%4d\n", pos);
}

void PrintList(SqList &L)
{
for(int i = 0; i < L.length; i ++)
printf("%4d", L.data[i]); //所有元素打印到一排,一个元素占4个空间
printf("\n");
}

优点

  1. 可以随机存取(根据表头元素地址和元素序号)表中任意一个元素。
  2. 存储密度高,每个结点只存储数据元素。

缺点

  1. 插入和删除操作需要移动大量元素。
  2. 线性表变化较大时,难以确定存储空间的容量。
  3. 存储分配需要一整段连续的存储空间,不够灵活。

三、插入操作

  1. 最好情况:在表尾插入元素,不需要移动元素,时间复杂度为
  2. 最坏情况:在表头插入元素,所有元素依次后移,时间复杂度为
  3. 平均情况:在插入位置概率均等的情况下,平均移动元素的次数为,复杂度为
1
2
3
4
5
6
7
8
9
10
11
12
bool ListInsert(SqList &L, int i, ElemType e)
{
if(i<1 || i> L.length+1) //判断插入位置 i 是否合法(满足 1 <= i <= len+1)
return false;
if(L.length >= MaxSize) //判断存储空间是否已满(插入 x 后是否会超出数组长度)
return false;
for (int j = L.length; j >= i; j--) //将最后一个元素到第 i 个元素依次后移一位
L.data[j] = L.data[j - 1];
L.data[i - 1] = e; //空出位置 i 放入元素 x
L.length++; //线性表长度 + 1
return true;
}

四、删除操作

  1. 最好情况:删除表尾元素,不需要移动元素,时间复杂度为
  2. 最坏情况:删除表头元素,之后的所有元素依次前移,时间复杂度为
  3. 平均情况:在删除位置概率均等的情况下,平均移动元素的次数为,时间复杂度为
1
2
3
4
5
6
7
8
9
10
bool ListDelete(SqList &L, int i, ElemType e)
{
if(i<=1 || i> L.length || L.length == 0) //判断删除位置 i 是否合法(满足 1 <= i <= len),且顺序表不能为0
return false; //插入和删除时,i 的合法范围是不一样的
e = L.data[i - 1]; //将被删除的元素赋值给 e
for (int j = i; j < L.length; j++)
L.data[j - 1] = L.data[j]; //将删除后的元素依次前移
L.length--; //线性表长度 - 1
return true;
}

五、查找元素

查找成功,返回位置。位置从 1 开始,查找失败,返回 0:

1
2
3
4
5
6
7
int LocateElem(SqList L, ElemType e)
{
for(int i = 0; i < L.length; i ++) //遍历顺序表
if(L.data[i] == e)
return i + 1; //i + 1 是元素在顺序表中的位置
return 0;
}

六、动态分配

C 语言的初始动态分配语句:

1
L.data = (ElemType *)malloc(sizeof(ElemType) * InitSize);

C++ 的初始动态分配语句:

1
L.data = new ElemType[InitSize];

动态分配数组的类型定义:

1
2
3
4
5
#define MaxSize 100;    //定义线性表的长度
typedef struct {
ElemType *data; //指示动态分配数组的指针
int MaxSize, length; //数组的当前容量和最大个数
}SeqList;

评论



Copyright © 2020 - 2022 Zhihao Zhuang. All rights reserved

本站访客数: 人,
总访问量: