02.线性表(一)顺序存储结构

2015-01-27 22:40:21 · 作者: · 浏览: 17
顺序存储结构 一、线性表基本概念 1.线性表定义 线性表(list)是指零个或多个数据元素的有限序列,所有数据元素为相同数据类型且一个数据元素可以由多个数据项组成。若将线性表记为(a1,..ai-1,ai,ai+1...,an),线性表元素的个数n(n>0,n=0时为空表)定义为线性表的长度,其中ai-1是ai 的直接前驱元素,ai+1是ai的直接后继元素。 2.线性表的抽象数据类型 ADT 线性表(List) Data 线性表的数据对象集合为{a1,a2,....an},每个元素的类型均匀DataType。其中,除了第一个元素a1外,每一个元素有且只有一个直接前驱元素;除了最后一个元素an外,每一个元素有且只有一个直接后继元素。数据元素之间的关系是一对一的关系。 Operation Initlist(*L):初始化操作,建立一个空的线性表L; ListEmpty(L):若线性表为空,返回true,否者返回false; ClearList(*L):将线性表清空; GetElem(L,i,*e):将线性表L中的第i个位置元素的值返回给e; LocateElem(L,e):在线性表L中查找与给定值e相等的元素,如果查找成功,返回该元素在表中序号表示成功;否者,返回0表示失败 ListInsert(*L,i,e):在线性表L中的第i个位置插入新元素e; ListDelete(*L,i,e):删除线性表L中的第i个位置元素,并用e返回其值; ListLength(L):返回线性表L的元素个数 注释:传递参数L和*L作用? 3.线性表的存储结构 顺序存储结构、链式存储结构 二、线性表的顺序存储结构 1.顺序存储定义 线性表的顺序存储结构,指的是用一段地址连续的存储单元依次存储线性表的数据类型相同的数据元素,在C语言中通常使用一维数组来实现顺序存储结构。 2.顺序存储结构3个属性 (1)存储空间的起始位置; (2)数据长度,即指存放线性表的最大存储容量,存储分配后这个量是一般是不变的; (3)线性表长度,即指线性表中数据元素的个数,随着线性表插入和删除操作的进行,这个量是变化的。 3.顺序存储结构的优缺点 (1)优点 a.无须为表示表中元素之间的逻辑关系而增加额外的存储空间。 b.可以快速的存取表中任一位置的元素。因为是数组实现顺序存储,我们可以直接通过数组下标存取数据元素。 (2)缺点 a.插入和删除操作需要移动大量的元素。需要从最后一个元素开始遍历,直到需插入或删除线性表的第i个元素。 b.当线性表长度变化较大时,难以确认存储空间的容量 c.造成存储空间的"碎片"。 4.顺行存储结构的结构代码示例 #define MAXSIZE 20 //存储控件初始分配空间大小 typedef int ElemType; //Elemtype即为int类型,假设数据元素的数据类型为int typedef struct /*存储结构的struc结构体*/ { ElemType data[MAXSIZE]; //数据存储数据元素,最大值为MAXSIZE int length; //线性表当前长度 }SqList; 其中,SqList就是struct结构体,如果以后我们需要定义一个struct结构体对象,可表现为SqList L。 5.顺序存储结构的插入和删除 (1)获得元素操作 实现操作: GetElem(L,i,*e)----将线性表L中的第i个位置元素的值返回给e 算法思路:因为线性表中的第i位置的数据元素,实际存储在数组下标为i-1的存储单元(数组下标从0开始),即就是把数据的第i-1下标的值返回即可。 源码实现: /*初始条件---顺序线性表L已经存在,且表长小于数据长度(1=
L.length)) //L.length为线性表长度 return ERROR; else { *e=L.data[i-1]; //将存储空间的第i-1位置的数据元素赋值到指针变量e所指向的空间中 return OK; } } (2)插入操作 实现操作: ListInsert(*L,i,e)----在线性表L中的第i个位置插入新元素e 算法思路: a.首先判断非法插入情况:线性表长度大于存储空间的长度;插入位置不合理; b.从最后一个元素开始向前遍历到第i个位置,分别将它们都向后移动一个位置; c.将新元素插入线性表的第i个位置,存储空间数组下标为i-1位置; d.线性表长度加1. 源码实现: /*初始条件---顺序线性表L已经存在,且表长小于数据长度(1=length==MAXSIZE) //线性表长度大于数据长度,抛出异常 return ERROR; if(i<1 || i>(L->length+1)) //插入位置不再存储空间段,抛出异常 return ERROR; if(i<=L->length) //插入位置符合条件,从最后一个元素开始向前遍历到第i个位置 { for(k=L->length-1;k>i;k--) { L->data[k+1]=L->data[k]; //将存储在位置k的数据元素,向后移动一位存储 } L->data[i-1]=e; //将新元素插入到第i个线性表元素对应的第(i-1)存储位置 L->length++; //线性表长度加1 return OK; } } 注释:k数据元素的存储位置,i表示数据元素在线性表的位置
(3)删除操作 实现操作:ListDelete(*L,i,e),删除线性表L中的第i个位置元素,并用e返回其值 算法思路: a.首先判断非法插入情况:线性表长度大于存储空间的长度;删除位置不合理; b.取出删除元素 b.从最后一个元素开始向前遍历到第i个位置,分别将它们都向前移动一个位置; d.线性表长度减1. 源码实现: /*初始条件---顺序线性表L已经存在,且表长小于数据长度(1=length==0) return ERROR; if(i<1 || i>(L->length+1)) return ERROR; if(i<=L->length) //插入位置符合条件,从最后一个元素开始向前遍历到第i个位置 { e=L->data[i-1]; //取出存储位置为(i-1)的数据元素 for(k=L->length-1;k>i;k--) { L->data[k-1]=L->data[k]; //将存储在位置k的数据元素,向后移动一位存储 } L->length--; //线性表长度加1 return OK; } } 注释:k数据元素的存储位置,i表示数据元素在线性表的位置 6.顺序存储结构性能分析 (1)存、读数据时间复杂度:线性表的顺序存储结构,在存、读数据时,不管是哪个位置都是通过数组下标直接读存、读数据元素(执行一次),所以时间复杂度都是O(1); (2)插入或删除时间复杂度:线性表的插入或删除操作都需要从最后一个元素开始遍历,直到需插入或删除线性表的第i个元素。所以,时间复杂度为O(n); (3)适用范围:元素个数不太变化(即少插入或删除数据元素),而更多的是存取数据的应用。