数据结构——第一章线性表:02线性表的顺序存储结构

1.线性表的顺序映像:以元素x的存储位置和元素y的存储位置之间的某种关系表示逻辑关系<x, y>。顺序映像的C语言描述:

(1)线性表的静态分配顺序存储结构:

#define LISTSIZE 100 //存储空间最大分配量为100

typedef struct

{

  ElemType elem[LISTSIZE];

  int length; //当前线性表长度

} Sqlist;

在线性表的静态分配顺序存储结构中,线性表的最大数据元素个数确定,元素数量不能随意增加,这是以数组方式描述线性表的缺点。为了实现线性表最大存储数据元素个数可以随意变化,可以使用一个动态分配的数组来取代上面的固定长度数组:

(2)线性表的动态分配顺序存储结构:

#define LISTINITSIZE 100 //初始空间分配量为100

#define LISTINCREMENT 10 //分配空间增加量为10

typedef struct

{

  ElemType* elem; //存储空间基址

  int length; //当前线性表长度

  int listSize; //当前线性表分配的存储容量(以sizeof(ElemType)为单位长度)

} Sqlist;

2.线性表的顺序存储(顺序表):用一组地址连续的存储单元依次存放线性表中的数据元素

a1 a2 ... ai-1 ai ... an

线性表的起始地址称作线性表的基地址。

3.顺序表以“存储位置相邻”表示有序对,即position(ai) = position(ai-1) + p(p为每个数据元素所占存储量)。

4.顺序表的所有数据元素的存储位置均取决于第一个数据元素的存储位置,即position(ai) = position(a1) + (i - 1) * p(position(a1) 为顺序表的基地址,p为每个数据元素所占存储量)

5.顺序表是一个随机存取的结构(存取结构是描述一个数据结构查找操作的时间性能,通常有两种存取结构:随机存取结构、顺序存取结构)。

6.存取结构与存储结构是两个不同的概念,存储结构是数据结构在计算机中的表示(例如:表示数据和关系)

7.随机存取结构和顺序存取结构:

(1)随机存取结构:在一个数据结构上进行查找的时间性能是O(1),即查找线性表中的任意一个数据元素的时间是相等的,均为常数时间。顺序表就是一种随机存取结构。 

(2)顺序存取结构:在一个数据结构上进行查找的时间性能是O(n),即查找线性表中的任意一个数据元素的时间复杂度是线性的,与该元素在结构中的位置有关。单链表就是一种顺序存取结构。

8.线性表操作的实现:

(1)initList(&L):构造一个空表,因为本操作是对表的一个加工型操作,故L设为引用参数,首先动态分配存储空间,然后将length置为0,表示初始表中没有数据元素。描述如下:

void initList(Sqlist &L)

{

  L.elem = (ElemType*)malloc(sizeof(ElemType) * LISTINITSIZE);

  if (!L.elem)

  {

    error; //存储分配失败

  }

  L.length = 0;

  L.listSize = LISTINITSIZE; //初始线性表存储容量

}

(2)locateElem(L, target, equal()):线性表中的按值查找是在线性表中查找与给定值target相等的数据元素。从第一个元素开始依次和target值进行比较,直到找到一个与target相等的数据元素,返回它在顺序表中存储的下标或序号(二者差1),或者查遍整个线性表都没有找到与target相等的元素,返回NONE。描述如下:

int locateElem(Sqlist L, ElemType target)

{

  i = 0;

  while (i <= L.length - 1 && L.elem[i] != target)

  {

    i++;

  }

  return (i > L.length - 1) ? NONE : i; //若线性表中有与target相等的元素返回存储位置

}

本算法主要是比较运算,比较次数与target在表中位置有关,也与表长有关。按值查找的平均比较次数为(n+1)/2,时间性能为O(n)。

(3)listInsert(&L, i, elem):插入elem元素后(a1, ..., ai-1, ai, ..., an)变为(a1, ..., ai-1, e, ai, ..., an)

<ai-1, ai>   --->   <ai-1, e>, <e, ai>,线性表的长度增加1,描述如下:

void listInsert(Sqlist &L, int i, ElemType elem) //在顺序表L的第i个位置插入新元素elem,i的合法范围为1 ~ L.length+1

{

  if ((i < 1 || i > L.length + 1) || (L.length >= L.listsize))

  {

    return; //插入位置不合法或当前存储空间已满则返回

  }

  position = &(L.elem[i-1]); //position:插入位置

  for (q = &(L.elem[L.length-1]); q >= position; --q)

  {

    *(q + 1) = *q; //插入位置的及之后的元素右移一位

  }

  *position = elem; //插入元素elem

  L.length++; //线性表长度加1

} //算法时间复杂度为:O(ListLength(L))

(4)listDelete(&L, i):删除第i个元素后(a1, ..., ai-1, ai, ai+1, ..., an)变为(a1, ..., ai-1, ai+1, ..., an)

<ai-1, ai>, <ai, ai+1>   --->   <ai-1, ai+1>,线性表的长度减1。描述如下:

void listDelete(Sqlist &L, int i)

{

  if ((i < 1) || (i > L.length))

  {

    return; //删除位置不合法

  }

  position = &(L.elem[i - 1]); //position为被删除元素的位置

  tail = L.elem + L.length - 1; //表尾元素的位置

  for (++position; position <= tail; ++position)

  {

    *(position-1) = *position; //被删除元素之后的元素左移

  }

  L.length--; //表长度减1

} //算法时间复杂度为:O(ListLength(L))

posted @ 2018-10-29 11:18  H36Phaeton  阅读(363)  评论(0编辑  收藏  举报