数据结构之线性表之顺序存储结构(3)

1 前言

经过前两张的理论基础,我相信大家都能简单的明白了数据结构和算法一些常用的概念了,从今天开始我们开始学习数据结构中线性表,一起叩响数据结构的大门。

2 详述

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

如果用数学语言来进行定义:

(声明:由于下标不是很好弄出来,所以只能表示下面这种方式了,请见谅!)

若线性表记作(a1,...ai-1,ai,ai+1,...,an),则表中ai-1领先于ai,ai领先于ai+1,称ai-1是ai的直接前驱元素,ai+1是ai的直接后继元素。当i=1,2,...,n-1时,ai有且仅有一个直接后期,当i=2,3,...,n时,ai有且仅有一个直接前驱。如下如所示:

线性表的个数n(n>=0)定义为线性表的长度,当n=0时,成为空表。

在较复杂的线性表中,一个数据元素可以由若干数据项组成。

2.1线性表的抽象数据类型

[cpp]view
plain
 copy

  1. ADT 线性表(List)
  2. Data
  3. 线性表的数据元素集合为(a1,...ai-1,ai,ai+1,...,an),每个元素的类型均为DataType。其中,除了第一个元素a1外,每一个元素都有且只有一个直接前驱,除了最后一个an外,每一个元素都只有只有一个直接后继。数据元素之间的关系是一对一的。
  4. Operation
  5. InitList(*L):初始化操作,建立一个空的线性表L。
  6. ListEmpty(L):若线性表为空,返回true,否则返回false
  7. ClearList(*L):将线性表清空。
  8. GetElem(L,i,*e):将线性表L中的第i个位置元素返回给e。
  9. LocateElem(L,e):在线性表中查找给值e相等的元素,如果查找成功,返回该元素在表中序号表示成功;否则,返回0表示失败。
  10. ListInsert(*L,i,e):在线性表中的第i个位置插入新元素e。
  11. ListDelete(*L,i,*e):删除线性表L中第i个位置元素,并用e返回其值。
  12. ListLength(L):返回线性表L的元素个数。
  13. endADT

下面我们看一个例子,将线性表A和B合并,即:A=AUB。说白了,就是把存在集合B中但不存在A中的数据元素插入到A中。我们假设La表示集合A,Lb表示集合B,则实现的代码如下:

[cpp] view
plain
 copy

  1. ADT 线性表(List)
  2. Data
  3. 线性表的数据元素集合为(a1,...ai-1,ai,ai+1,...,an),每个元素的类型均为DataType。其中,除了第一个元素a1外,每一个元素都有且只有一个直接前驱,除了最后一个an外,每一个元素都只有只有一个直接后继。数据元素之间的关系是一对一的。
  4. Operation
  5. InitList(*L):初始化操作,建立一个空的线性表L。
  6. ListEmpty(L):若线性表为空,返回true,否则返回false
  7. ClearList(*L):将线性表清空。
  8. GetElem(L,i,*e):将线性表L中的第i个位置元素返回给e。
  9. LocateElem(L,e):在线性表中查找给值e相等的元素,如果查找成功,返回该元素在表中序号表示成功;否则,返回0表示失败。
  10. ListInsert(*L,i,e):在线性表中的第i个位置插入新元素e。
  11. ListDelete(*L,i,*e):删除线性表L中第i个位置元素,并用e返回其值。
  12. ListLength(L):返回线性表L的元素个数。
  13. endADT

2.2 线性表的顺序存储结构

线性表的顺序存储结构,指的是用用一段地址连续的存储单元依次存储线性表的数据元素。

线性表的顺序存储的结构代码:

[cpp]view
plain
 copy

  1. #define MAXSIZE 20     /*存储空间初始化分配量*/
  2. typedef int ElemType;    /*ElemType 类根据实际情况而定,这里假设为int*/
  3. typedef struct
  4. {
  5. ElemType data[MAXSIZE];  /*数组存储数据元素,最大值为MAXSIZE*/
  6. int length;                              /*线性表当前长度*/
  7. }SqList;

三个属性:

·存储空间其实位置:数组data,他的存储位置就是空间的存储位置。

·线性表的最大存储容量:数组长度MaxSize。

·线性表的当前长度:length。

2.2.1 数据长度和线性表长度区别

数组的长度是存放线性表的存储空间的长度,存储分配后这个量是一般不变的。

线性表的长度是线性表中数据元素的个数,随着线性表插入和删除操作的进行,这个量是变化的。

在任意时刻,线性表的长度应该小于数组的长度。

2.2.2 地址计算方法

线性表从1开始计数,可是C语言中数组确实从0开始,于是线性表的第i个元素存储在数组下标为i-1的位置,即数据元素的序号和存放它数组下标之间存在对应关系,如图:

存储器中每个存储单元都有自己的编号,这个编号称为地址。

假设每个元素占用的是c个存储单元,那么线性表中第i+1个数据元素的存储位置和第i个数据元素的存储位置满足下列关系(LOC表示获得存储位置的函数)。

[cpp]view
plain
 copy

  1. LOC(ai+1) = LOC(ai)+c

所以对于第i个数据元素ai的存储位置可以由a1推算得出:

[cpp] view
plain
 copy

  1. LOC(ai) = LOC(a1)+(i-1)*c

可以借助如下图来理解:

所以对于存入或者取出数据,计算时间都是系统的,是一个常数,时间复杂度为O(1)。

2.3 顺序存储结构的插入和删除

2.3.1 获得元素操作

实现GetElem操作,即将线性表L中的第i个位置元素值返回,代码如下:

[cpp]view
plain
 copy

  1. #define OK 1
  2. #define ERROR 0
  3. #define TRUE 1
  4. #define FALSE 0
  5. typedef int Status;
  6. /*Status是函数的类型,其值是函数结果状态代码,如OK等*/
  7. /*初始条件:顺序线性表L已存在,1<=i<=ListLength(L)*/
  8. /*操作结果:用e返回L中第i个数据元素的值*/
  9. Status GetElem(SqList L,int i,ElemType* e)
  10. {
  11. if(L.length == 0||i<1||i>L.length)
  12. return ERROR;
  13. *e = L.data(i - 1);
  14. return OK;
  15. }

2.3.2 插入操作

思路:

·如果插入位置不合理,抛出异常;

·如果线性表长度大于等于数组长度,抛出异常或者动态增加容量;

·从最后一个元素开始向前遍历到第i个位置,分别将他们都向后移动一个位置;

·将要插入元素填入位置i处;

·表长加1。

这里我们实现ListInsert(*L,i,e),代码实现:

[cpp]view
plain
 copy

  1. /*初始条件:顺序线性表L已经存在,1<=i<=ListLength(L)*/
  2. /*操作结果:在L中第i个位置之前插入新的数据元素e,L的长度加1*/
  3. Status ListInsert(SqList *L,int i,ElemType e){
  4. int k;
  5. if(L->length == MAXSIZE)  /*顺序线性表已经满*/
  6. return ERROR;
  7. if(i<1||i>L->length+1)  /*当i不在范围内时*/
  8. return ERROR;
  9. if(i<=L->length)
  10. {
  11. for(k = L->length-1;k>=i-1;k-- /*将要插入位置后数据元素向后移动一位*/)
  12. L->data[k+1] = L->data[k];
  13. }
  14. L->data[i-1] = e;  /*将新元素插入*/
  15. L->length++;
  16. return OK;
  17. }

2.3.3 删除操作

思路:

·如果删除位置不合理,抛出异常;

·取出删除元素;

·从删除元素位置开始遍历到最后一个元素位置,分别将他们都向前移动一个位置;

·表长减1。

代码如下:

[cpp]view
plain
 copy

  1. /*初始条件:顺序线性表L已经存在,i<=i<=ListLength(L)*/
  2. /*操作结果:删除L的第i个数据元素,并用e返回其值,L的长度减1*/
  3. Status ListDelete(SqList *L,int i,ElemType *e){
  4. int k;
  5. if(L -> length == 0)   /*线性表为空*/
  6. return ERROR;
  7. if(i<1 || i>L->length)    /*删除位置不正确*/
  8. return ERROR;
  9. *e = L->data[i-1];
  10. if(i<L->length)
  11. {
  12. for(k = i;k<L->length;k++)  /*将删除位置后继元素前移*/
  13. L->data[k-1] = L->data[k];
  14. }
  15. L->length--;
  16. return OK;
  17. }

时间复杂度为O(n)。

2.4 线性表顺序存储结构的优缺点

3 结语

以上是所有内容,希望对大家有所帮助。

时间: 2024-10-10 06:40:58

数据结构之线性表之顺序存储结构(3)的相关文章

数据结构之线性表(顺序存储结构)

小学生放学都是要按顺序排队的,一个接一个,每个小学生的前后位置是固定的,这样便于迅速清点. 其实这就是一个线性表,从这件事里我们就可以找到很多关于线性表的特性,如 1.线性表是一个序列,它是有顺序的(排队) 2.第一个元素无前驱,最后一个无后继,其他每个元素都有一个前驱和后继(一个接一个) 3.元素是有限的(小学生的个数是有限的) 4.数据类型都相同(都是小学生在排队) 说明白线性表示什么,下面我们直接看线性表的实现 线性表的实现分顺序存储结构和链式存储结构 顺序存储结构: #define LI

【数据结构】 线性表 的 顺序存储结构

1 #include<stdio.h> 2 #include<stdlib.h> 3 typedef int ElemType; 4 typedef struct SqList{ 5 ElemType *elem ; // 线性表顺序表示的基本类型 6 int length; // 当前的表长 7 int listsize; // 当前分配存储空间的容量 8 }SqList ; 9 10 //创建顺序表 11 SqList InitList() { 12 SqList L; 13

数据结构之线性表的顺序存储结构的实现--C语言版

#include <stdio.h> #include <stdlib.h> #include <time.h> #define INIT_SIZE 100 #define PER_INCREMENT 10 typedef struct SqList{ char *Element; int Length; int ListSize; }SqList; void InitSqList(SqList *L) { L->Element=(char*)malloc(siz

《大话数据结构》笔记(2)--线性表的顺序存储结构

线性存储结构的Java实现代码: https://github.com/Lyu0709/data-structure/tree/master/src/com/coding/basic/array 第三章 线性表 定义 数学语言 若将线性表记为(a1, ..., ai-1, ai, ai+1, ..., an),则表中ai-1领先于ai,ai领先于ai+1,称ai-1是ai的直接前驱元素,ai+1是ai的直接后继元素.当i=1,2,..,n-1时,ai有且仅有一个直接后继,当n=2,3,...,n

数据结构-线性表之顺序存储结构

一.线性表的顺序存储需要三个属性 1.存储空间的起始位置 2.线性表的最大存储容量 3.线性表的当前长度 二.线性表的时间复杂度: 线性表的顺序存储结构,在存.读数据时,不管是哪个位置,时间复杂度都是O(1); 插入删除的时间复杂度是O(n),所以线性表适合元素个数不太变化,而更多是存取数据的应用. 三.线性表的结构示意图: 四.代码示例: /*我们的计量方式,除下标从0开始外,其余都从1开始算,所以只有在涉及访问数组的时候,要注意是否要+1 或-1*/ #include <stdio.h>

线性表之顺序存储结构(C语言动态数组实现)

线性表的定义:N个数据元素的有限序列 线性表从存储结构上分为:顺序存储结构(数组)和 链式存储结构(链表) 顺序存储结构:是用一段连续的内存空间存储表中的数据 L=(a1,a2,a3....an) 链式存储结构:是用一段一段连续的内存空间存储表中每一行的数据,段与段之间通过一个引用(指针)相互连接来,形成一个链式的存储结构 看到顺序存储结构的图示,我们可能会马上联想到C语言的数组.是的,数组就是一种典型的顺序存储数据结构.下面我通过一个实例,来实现对顺序存储结构中的数据增.删.改.查的操作. 首

简要比较线性表的顺序存储结构和链式存储结构

我们分别从存储分配方式.时间性能.空间性能三方面来做对比. 存储分配方式 顺序存储结构用一段连续的存储单元依次存储线性表的数据元素. 单链表采用链式存储结构,用一组任意的存储单元存放线性表的元素. 时间性能 <1>查找 顺序存储结构O(1) 单链表O(n) <2>插入和删除 顺序存储结构需要平均移动表长一半的元素,时间为O(n) 单链表在计算出某位置的指针后,插入和删除时间仅为O(1) 空间性能 顺序存储结构需要预分配存储空间,分大了,容易造成空间浪费,分小了,容易发生溢出. 单链

第6课 - 线性表的顺序存储结构及实现

1. 线性表的顺序存储结构 [顺序存储结构定义] 线性表的顺序存储结构,指的是用一段地址连续的存储单元依此存储线性表中的数据元素. [设计思路] 可以用一维数组来实现顺序存储结构的线性表. 1 template <typename T> 2 class SeqList : public List<T> 3 { 4 protected: 5 T *m_array; //顺序存储空间 6 int m_length; //当前线性表长度 7 }; [顺序存储线性表类的组成] DTLib顺

线性表的顺序存储结构

1.顺序表: 线性表占用的存储空间=n*sizeof(ElemType) n为线性表的长度,ElemType为线性表的元素类型,sizeof(ElemType)为每个元素所占存储空间大小(即字节数) 线性表的顺序存储结构利用数组实现,数组的基本类型是线性表中元素类型,数组大小大于等于线性表的长度. 基本运算实现: (1)建立顺序表 void CreateList(SqList *&L,ElemType a[],int n)    //由a中的n个元素建立顺序表 {  int i;    L=(S