数据结构自学笔记003(线性表1)

数据结构自学笔记003(线性表)

1、线性表定义

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

(a1,a2,…ai-1,ai,ai+1,…,an)
a1:线性起点(起始结点)
an:线性终点(终端结点)
a2~an-1:数据元素
ai-1:ai的直接前趋
ai+1:ai的直接后继
下标:是元素的序号,表示元素在表中的位置
n:元素的总个数,称为表长
n=0时称为空表

总结;:
1)线性表中的数据元素的类型可以为简单类型,也可以是复杂类型;
2)许多实际应用所涉及的基本操作有很大相似性,不应为每个人具体应用大度编写一个程序;
3)从具体应用中抽象出共性的逻辑结构和基本操作(抽象数据类型),然后实现其存储结构和操作。

3、线性表的抽象数据类型定义:

抽象数据类型线性表的定义如下:(以下全部为伪代码,不能够在任何编译环境中运行)

ADT List{
	数据对象:D={ai|ai属于Element,(i=1,2,...,n;n>=0)}
	数据关系:R={<ai-1,ai>|ai-1,ai属于D,(i=2,3,...,n)}
	基本操作:
	InitList(&l);
	DestroyList(&L);
	ListUnsert(&l,i,e);
	ListDelete(&l,i,&e);
	........
}ADT List

(1)基本操作1:
1)InitList(&L) (Initialization List)
操作结果:构造一个空的线性表L。
2)DestroyList(&l)
初始条件:线性表已经存在
操作结果:销毁线性表L
3)ClearList(&L)
初始条件:线性表L已经存在
操作结果:将线性表L重置为空表
(2)基本操作2:
1)ListEmpty(L)
初始条件:线性表已经存在
操作结果:若线性表L为空表,则返回TRUE,否则返回FALSE
2)ListLength(L)
初始条件:线性表L已经存在
操作结果:返回线性表L的数据元素个数
(3)基本操作3
1)GetElem(L,i,&e)
初始条件:线性表L已经存在,1<=i<=ListLength(L)
操作结果:用e返回线性表L中的第i个数据元素的值
2)LocateElement(L,e,compare())
初始条件:线性表L已经存在,compare()是数据元素判定函数
操作结果:返回L中第1个与e满足compare()函数的数据元素的位序,若这样的数据元素不存在则返回值为0
(4)基本操作4
1)PriorElem(L,cur_e,&pre_e)
初始条件:线性表L已经存在
操作结果:若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前驱,否则操作失败,pre_e无意义
2)NextElem(L,cur_e,&next_e)
初始条件:线性表L已经存在
操作结果:若cu_e是L的数据元素,且不是最后一个,则用next_e返回它的后继,否则操作失败,next_e无意义。
(5)基本操作5:
ListInsert(&L,i,e)
初始条件:线性表L已经存在,1<=i<=ListLebgth(l)+1
操作结果:在L的第i个位置之前插入新的数据元素e,L的长度加一
(6)基本操作(六)
ListDelete(&L,i&e)
初始条件:线性表已经存在,1<=i<=ListLength(l)
操作结果:删除L的第i个数据元素,并用e的返回值,L的长度减一
ListTraverse(&L,vistedO()) (所谓的遍历函数)
初始条件:线性表已经存在
操作结果:依次对线性表中的每个元素进行调用Visited()

4、线性表的顺序表示和实现(顺序存储结构的表示与实现)

(1)线性表的顺序表示称为顺序存储结构或或者顺序映像。
顺序存储定义:把逻辑上相邻的数据元素存储在物理上相邻的存储单元中的存储结构。
线性表顺序存储结构必须占有一片连续的存储空间,知道某个元素的存储位置就可以计算其他元素的存储位置。

(2)线性存储结构的实现
顺序表(元素)特点:地址连续,依次存储,随即存取,类型相同——>数组(元素)
但是线性表长度可变(删除),而数组的长度是不可变的,为了用C语言进行表示,则定义以下结构体:

#define LIST_INIT_SIZE 100 //线性表存储空间的初始分配量
typedef struct{
	ElemType elem[LIST_INIT_SIZE];
	int Length; //当前长度
}SqList;

实例:图书管理系统中的图书表的顺序存储结构定义:

#define MAXSIZE 1000 //图书表可能达到的最大长度
typedef struct{ //图书信息定义
	char no[20]; //图书ISBN
	char name[50]; //图书名字
	float price; //图书价格
}Book;
typedef struct{
	Book *elem; //存储空间的基地址
	int length; //图书表中当前图书个数
}SqList; //图书表的循序存储结构类型为SqList

5、C语言补充

C语言数组定义解释:

//数组静态分配
typedef struct{
	ElemType data[MaxSize];
	int length;
}SqList; //顺序表类型

//数组动态分配
typedef struct{
	ElemType *data;
	int length;
}SqList;  //顺序表类型

SqList L;
L.data=(ElemType*)malloc(sizeof(ElemType)*MaxSize); //需要加载头文件:<stdlib.h>
以下为解释:
malloc(m)函数,开辟m字节长度的地址空间,并返回这段空间的首地址
sizeof(x)运算:计算变量x的长度
free(p)函数:释放指针p所之变量的存储空间,即彻底删除一个变量
(ElemType*):将开辟的空间以ElemType数据类型的长度为单位进行划分。加上*是转换成以ElemType类型的指针变量

C++的动态分配

new 类型名T(初始值列表)
	功能:
		申请用于存放T类型对象的内容空间,并以初值列表赋以初值
	结果值:
		成功:T类型的指针,只想新分配的内存
		失败:0NULL//例子:
int *p1 = new int;或者
int *p1 = new int(10);

delete 指针P
功能:
	释放指针P所指向的内存,P必须是new操作的返回值。
例子:
delete p1;

传地址方式——C++引用类型说明:

#inclide <iostream.h>
void swap(float& m,float& n)
{
	float temp;
	temp=m;
	m=n;
	n=temp;
}
void main()
{
	float a,b;
	cin>>a>>b;
	swap(a,b);
	cout<<a<<endl;<<b<<endl;
}

引用类型做形参的三点说明:
(1)传递引用给函数与传递指针的效果是一样的,形参变化实参也发生变化;
(2)引用类型作形参,在内存中并没有产生实参的副本,他直接对实参操作,而一般变量作残烛,形参与实参就占用不同的存储单元,所以形参变量的值是实参变量的副本。因此,当参数传递的数据量较大时,引用比一般变量传递参数的时间和空间效率都好。
(3)指针参数虽然也能够达到与使用引用的效果,但在被调用函数中需要重复使用“指针变量名”的形式进行运算,这很容易产生错误且程序的阅读性较低,另一方面,在主调函数的调用点处,必须用变量的地址作为实参。

5、基本操作的实现

//函数结果状态代码
#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 InitList_Sq(SqList &l) //构造一个空的顺序表
{
	L.elem = new ElemType[MAXSIZE]; //为顺序表分配空间
	if(!L.elem) exit(OVERFLOW); //存储分配失败
	L.length = 0; //空表长度为0
	return OK;
}

//2、销毁线性表
void DestoryList(SqList &l)
{
	if(L.elem) delete l.elem; //释放存储空间(这是C++的语法)
}

//3、清空线性表
void ClearList(SqList &L)
{
	L.length = 0;  //线性表的长度为0
}

//4、求线性表L的长度
int GetLength(SqList L)
{
	return(L.length);
}

//5、判断线性表是否为空
int IsEmpty(SaList L)
{
	if(L.length === 0) return 1;
	else return 0;
}

//6、顺序表的取值(根据位置i获取相应位置数据元素的内容)
int GetElem(SqList L,int i,ElemType &e)
{
	if(i<1||i>L.length) return ERROR; //判断i值是否合理,若不和人力,则返回ERROR
	e = L.elem[i-1]; //第i-1的单元存储着第i个数据
	return OK;
}

//7、顺序表的查找
在顺序表L中查找与指定值e相同的数据元素的位置
从表的一端开始,逐个进行记录的关键字和给定值的比较,找到后,返回该元素的位置序号,未找到,则返回0
int LocateElem(SqList L,ElemType e)
{
	for(i = 0;i < L.length;i++)
		if(L.elem[i] == e) return i+1; //查找成功,返回序号
	return 0; //查找失败,返回0
}
//顺序表的查找算法分析:
//平均查找长度ASL(Average Search Length):
//未确定记录在表中的位置,需要与给定值进行比较的关键字的个数的期望值叫做查找算法的平均查找长度。
//  ASL = (n+1)/2

//8、顺序表的插入算法:
算法思想:
1)判断插入位置i是否合法
2)判断顺序表的存储空间是否已满,若已满返回ERROR
3)将第n至第i位的元素依次向后移动一个位置,空出第i个位置
4)将要插入的新元素e放入第i个位置
5)表长加1,插入成功返回OK
Status ListInsert_Sq(SqList &L,int i,ElemType e)
{
	if(i<1||i>L.length+1) return ERROR;
	if(L.length == MAXSIZE) return ERROR;
	for(j = L.length-1;j>=i-1;j--)
		L.elem[j+1]=L.elem[j];
	L.elem[i-1] = e;
	L.length++;
	return OK;
}
插入算法的复杂度分析:
//    ALS = n/2

//9、删除顺序表中的元素:
算法思想:
1)判断删除位置i是否合法(合法的职位==值为1<=i<=n)
2)将欲删除的元素保留在e中
3)将第i+1至n位的元素依次向前移动一个位置
4)表长减1,删除成功返回OK
Status ListDelete_Sq(SqList &L,int i)
{
	if((i<1)||(i>L.length)) return ERROR;
	for(J = i;j<=L,length-1;j++)
		L.length[j-1] = L.elem[j];
		L.length--;
	return OK;
}
算法复杂度:
//     ALS = (n-1)/2
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

仲子_real

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值