数据结构(王卓)

目录

2.1线性表的定义和特点

一.线性表

1.定义

2.特点

2.2线性表案例引入

一.线性表案例

1.顺序存储结构存在问题

二.链式存储结构

 三.总结

2.3线性表的类型定义

一.抽象数据类型线性表

1.定义

 二.线性表的基本操作

1.InitList(&L)

2.DestroyList(&L)

3.ClearList(&L)

4.ListEmpty(L)

5.ListLength(L)

6.GetElem(L,I,&e);

7.LocateElem(L,e,compare())

8.PriorElem(L,cur_e,&pre_e)

9.NextElem(L,cur_e,&next_e)

10.Listlnsert(&L,i,e)

11.ListDelete(&L,i,&e)

12.ListTraverse(&L,visited())

2.4.1线性表的顺序表示和实现

一.线性表的存储结构

1.储存结构分类

2.线性表的顺序存储结构

3.顺序表的顺序存储表示

 补充:类c语言有关操作

一.数组定义

 二.c++的动态存储分配

 三.c++中的参数传递

1.传值方式

2.传地址方式——指针变量作参数

3.传地址方式——数组名作参数

 4.传地址方式——引用类型作参数

5.引用类型作形参的三点说明

2.4.1线性表的顺序表示和实现

一.顺序表示意图

二.补充:操作算法中用到的预定义常量和类型

三.顺序表基本操作的实现

1.线性表的初始化(参数用引用)

2.销毁线性表L

3.清空线性表L

4.求线性表的长度

5.判断线性表是否为空

四.举例

2.4.2顺序表基本操作的实现

一.顺序表基本操作的实现

1.顺序表的查找

 2.平均查找长度ASL

 3.顺序表的插入

 4.顺序表的删除

 二.总结

1.顺序表的特点

2.优点与缺点


2.1线性表的定义和特点

一.线性表

1.定义

线性表是具有相同特性的数据元素的有限序列。

  • 2.特点

  • (1.)相同特性:所有元素属于同一数据类型。

    有限:数据元素个数是有限的。

    序列:数据元素由逻辑序号唯一确定。一个线性表中可以有相同值的元素。

(2.)其中数据元素的个数n定义为表的长度。

(3.)当n=0时称为空表

将非空的线性表(n>0)记作:(a1,a2,...an)

(4.)这里的数据元素ai(1《i《n)只是一个抽象的符号,其具体含义在不同的情况下可以不同。

3.线性表的逻辑特征

(1.)在非空的线性表,有且仅有一个开始结点a1,它没有直接前趋,而仅有一个直接后继a2;

(2.)有且仅有一个终端结点an,它没有直接后继,而仅有一个直接前趋an-1;

(3.)其余的内部结点ai(2《i《n-1)都有且仅有一个直接前趋ai-1和一个直接后继ai+1.

2.2线性表案例引入

一.线性表案例

1.顺序存储结构存在问题

  • 存储空间分配不灵活
  • 运算的空间复杂度高

二.链式存储结构

 三.总结

(1.)线性表中数据元素的类型可以为简单类型,也可以为复杂类型

(2.)从具体应用中抽象出共性的逻辑结构和基本操作(抽象数据类型),然后实现其存储结构和基本操作

2.3线性表的类型定义

一.抽象数据类型线性表

1.定义

 二.线性表的基本操作

1.InitList(&L)

(1)操作结果:构造一个空的线性表L

2.DestroyList(&L)

(1)初始条件:线性表L已经存在

(2)操作结果:销毁线性表L

3.ClearList(&L)

(1)初始条件:线性表L已经存在

(2)操作结果:将线性表L重置为空表

4.ListEmpty(L)

(1)初始条件:线性表L已经存在

(2)操作结果:若线性表L为空表(n=0),则返回TURE;否则返回FALSE

5.ListLength(L)

(1)初始条件:线性表L已经存在

(2)操作结果:返回线性表L中的数据元素个数

6.GetElem(L,I,&e);

(1)初始条件:线性表L已经存在,1<=i<=ListLength(L)

(2)操作结果:用e返回线性表中L中第i个数据源色的值

7.LocateElem(L,e,compare())

(1)初始条件:线性表L已经存在,compare()是数据元素判定函数

(2)操作结果:返回L中第一个与e满足compare()的数据元素的位序。若这样的数据元素不存在则返回值为0

8.PriorElem(L,cur_e,&pre_e)

(1)初始条件:线性表L已经存在

(2)操作结果:若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前趋,否则操作失败;pre_e无意义

9.NextElem(L,cur_e,&next_e)

(1)初始条件:线性表L已经存在

(2)操作结果:若cur_e是且不是最后一个,则用next_e返回他的后继,否则操作失败,next_e无意义

10.Listlnsert(&L,i,e)

(1)初始条件:线性表L已经存在,1<=i<=ListLength(L)+1

(2)操作结果:在L的第i个位置之前插入新的元素e,L的长度加一

11.ListDelete(&L,i,&e)

(1)初始条件:线性表L已经存在,1<=i<=ListLength(L)

(2)操作结果:删除L的第i个数据元素,并用e返回其值,L的长度减一

12.ListTraverse(&L,visited())

(1)初始条件:线性表L已经存在

(2)操作结果:依次对线性表中每个元素调用visited()

2.4.1线性表的顺序表示和实现

一.线性表的存储结构

1.储存结构分类

线性表有两种基本的存储结构:顺序存储结构和链式存储结构

2.线性表的顺序存储结构

(1)线性表的顺序表示又称为顺序存储结构或顺序映像

(2)顺序存储定义:把逻辑上相邻的数据元素存储在物理上相邻的存储单元中的存储结构

 (3)线性表的第一个数据元素a1的存储位置,称作线性表的起始位置或基地址

(4)线性表顺序存储结构占用一片连续的存储空间。知道某个元素的存储位置就可以计算其他元素的存储位置

 (5)优点

  • 以物理位置相邻表示逻辑关系
  • 任一元素均可随机存取

3.顺序表的顺序存储表示

(1)模板

 (2)举例

 

 补充:类c语言有关操作

一.数组定义

 (1)*date(指针变量)表示一个数组,用于存放第一个元素的地址

(2)分配内存

(3) L里面有两个元素:ElemType*data和int length

(4)内存分配函数

 二.c++的动态存储分配

 三.c++中的参数传递

  • 函数调用时传送给形参表的实参必须与形参三个一致

类型,个数,顺序

  • 参数传递有两种方式

传值方式(参数为整数,实型,字符型等)

传地址

  • 参数为指针变量
  • 参数为引用类型
  • 参数为数组名

1.传值方式

把实参的值传送给函数局部工作区相应的副本中,函数使用这个副本执行必要的功能。函数修改的是副本的值,实参的值不变。

 最后释放m和n的值,跟a和b无关,ab的值不变

2.传地址方式——指针变量作参数

(1)形参变化影响实参

  • *m传的是a的内容(3)
  • 最后全部释放*m,*n,a和b的值互换

(2)形参变化不影响实参

  •  交换地址,内容没变(只交换门牌号,没有交换人)

3.传地址方式——数组名作参数

(1)传递的是数组的首地址

(2)对形参数组所做的任何改变都将反映到实参数组中

  •  a输出的值为world
  • char b[]可以写成char *b,*b[]=“world”,因为传递的是指针(是内容),所以a的值变化了

 4.传地址方式——引用类型作参数

(1)引用:它用来给一个对象提供一个替代的名字

  •  &j可以理解为地址(内容),所以会改变

  •  a和m公用一个空间(内容一样),b和n公用一个空间,所以数值会变化

5.引用类型作形参的三点说明

(1)传递引用给函数与传递指针的效果是一样的

(2)引用类型作形参,在内存中并没有产生实参的副本,它直接对实参操作;而一般变量作参数,形参与实参就占用不同的存储单元,所以形参变量的值是实参变量的副本。因此,当参数传递的数据量较大时,用引用比用一般变量传递参数的时间和空间效率都好。

(3)指针参数虽然也能达到与使用的效果,但在被调函数中需要重复使用“*指针变量名”的形式进行运算,这很容易产生错误且程序的阅读性较差;另一方面,在主调函数的调用点处,必须用变量的地址作为实参。

2.4.1线性表的顺序表示和实现

一.顺序表示意图

二.补充:操作算法中用到的预定义常量和类型

//函数结果状态代码
#define TRUE  1
#define FALSE 0
#define OK    1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
//Status 是函数的类型,其值是函数结果状态代码
typedef int Status;
typedef char ElemType;

三.顺序表基本操作的实现

1.线性表的初始化(参数用引用)

Status lnitList_Sq(SqList&L){   //构造一个空的顺序表L
 L.elem=new ElemType[MAXSIZE];  //为顺序表分配空间
 if(!L.elem)exit(OVERFLOW);     //存储分配失败
 L.length=0;
 return OK;
}

2.销毁线性表L

void DestroyList(SqList&L){
 if(L.elem)delete L.elem;  //释放空间,如果本来就是空的就不用删除,if用来判断
}

3.清空线性表L

void ClearList(SqList&L){
 L.length=0;  //将线性表长度设置为0
}

4.求线性表的长度

int GetLength(SqList){
 return(L.length);
}

5.判断线性表是否为空

int LsEmpty(SqList L){
 if (L.length==0)return 1;
 else return 0;
}

四.举例

(1)顺序表的取值(根据位置i获取相应位置数据元素的内容)

int GetElem(SqList L,int i,Elem Type &e){
 if(i<||i>L.length)return ERROR;  \\判断i的值是否合理,若不合理,返回ERROR
 e=L.elem[i-1];
 return OK;
}

2.4.2顺序表基本操作的实现

一.顺序表基本操作的实现

1.顺序表的查找

(1)在线性表L中查找与指定值e相同的数据元素的位置

(2)从表的一端开始,逐个进行记录的关键字和给定值的比较。找到,返回该元素的位置序号,未找到,返回0

int LocateElem(SqList L,ElemType e){
 //在线性表L中查找值为e的数据元素,返回其序号(是第几个元素)
 for(i=0;i<L.length;i++)
   if(L.elem[i]==e)return i+1;  //查找成功,返回序号
 return 0;  //查找失败返回0
}
 

 2.平均查找长度ASL

(1)为确定记录在表中的位置,需要与给定值进行比较的关键字的个数的期望值叫做查找算法的平均查找长度

 3.顺序表的插入

线性表的插入运算是指在表的第i(1《i《n+1)个位置上,插入一个新结点e,使长度为n的线性表(a1,...ai-1,ai,...,an)变成长度为n+1的线性表(a1,...ai-1,e,ai,...an)

算法思想:

  • 判断插入的位置i是否合法
  • 判断顺序表的存储空间是否已满,若已满返回ERROR
  • 将第n至第i位的元素依次向后移动一个位置,空出第i个位置
  • 将要插入的新元素e放入第i个位置
  • 表长加1,插入成功返回OK

 4.顺序表的删除

 线性表的删除运算是指将表的第i(1《i《n)个结点删除使长度为n的线性表(a1,...,ai-1,ai+1,...,an)变成长度为n-1的线性表(a1,...ai-1,ai+1,...,an)

算法思想:

  • 判断删除位置i是否合法(合法值为1《i《n)
  • 将欲删除的元素保留在e中
  • 将第i+1至第n位的元素依次向前移动一个位置
  • 表长减1,删除成功返回OK

 二.总结

1.顺序表的特点

  • 利用数据元素的存储位置表示线性表中相邻数据元素之间的前后关系。即线性表的逻辑结构与存储结构一致
  • 在访问线性表时,可以快速地计算出任何一个数据元素的存储地址。因此可以粗略的认为,访问每个元素所花时间相等
  • 这种存储元素的方法被称为随机存取法

2.优点与缺点

(1)优点

  • 存储密度大
  • 可以随机存取表中任一元素

(2)缺点

  • 在插入,删除某一元素时,需要移动大量元素
  • 浪费存储空间
  • 属于静态存储形式,数据元素的个数不能自由扩充
  • 1
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值