数据结构与算法[1]----线性表

1.定义

由零个或者多个数据元素组成的有限序列,零个元素的是个空表。

  1. 首先是个序列,有先来后到。
  2. 存在多个元素,第一个元素没有前驱,也就是没有前一个元素,最后一个元素没有后继,中间的元素有且仅有一个前驱以及后继。
  3. 线性表强调是有限的,没有无限长度的线性表。
    在这里插入图片描述

1.2 抽象数据类型

定义:是指一个数学模型以及定义在该模型上的一组操作,仅仅取决与它的一组逻辑特性,而与其在计算计算机内部如何表示与实现无关。

例如:1+2=3,这样的操作在不同CPU上的处理是不同的,但是由于其定义的数学特性相同,所以在计算机编程者看来是一致的。

数据类型的定义:指一组性质相同的值的集合以及定义在此集合上的一些操作的总称。整型,浮点型,字符型。

C语言中,按照取值分为两种大类的:

  1. 不可分解的基本类型–原子类型,例如整型,浮点型,字符型
  2. 可分解的类型,由若干个类型组合而成,类似于结构体,数组等等
ADT 抽象数据类型名
{
Data:
数据元素之间逻辑关系的定义;
Operation:
操作1;
操作2...
}

2.线性表

2.1存储结构

线性存储结构

#define MAXSIZE 20
typedeef int ElemType;
typedef struct{
	ElemType data[MAXSIZE];
	int leength;
}SqList;

顺序存储结构封装需要三个属性:

  1. 存储空间的起始位置,数组data的位置即线性表存储空间的存储位置。
  2. 线性表的最大存储容量:数组的长度MaxSize
  3. 线性表当前的长度:length

地址计算方法:

数组从0开始计算,假设ElemType占用的是C个存储单元(字节),那么线性表中第i+1个元素和第i个数据元素的存储位置关系是:Loc(ai+1)=Loc(ai)+C

2.2线性表顺序存储

定义线性表的结构,对象的长度,表长,以及表内元素的类型

typedef struct{
	ElemType *elem;
	int length;
	int listsize;
}List;

定义线性表的方法

1.InitList(&L)
/*操作结果:构造一个空的线性表*/
 
 
2.DestroyList(&L)
/*初始条件:线性表L已存在*/
/*操作结果:销毁线性表L*/
 
 
3.ClearList(&L)
/*初始条件:线性表L已存在*/
/*操作结果:将L重置为空表*/
 
 
4.ListEmpty(L)
/*初始条件:线性表L已存在*/
/*操作结果:若L为空表,则返回TRUE,否则返回FALSE*/
 
5.ListLength(L)
/*初始条件:线性表L已存在*/
/*操作结果:返回L中数据元素个数*/
 
6.GetElem(L,i,&e)
/*初始条件:线性表L已存在,1≤i≤LIST_SIZE*/
/*操作结果:用e返回L中第i个数据元素的值*/
 
7.LocatElem(L,e,compare())
/*初始条件:线性表L已存在,compaer()是数据元素判断函数*/
/*操作结果:返回L中第1个与e满足关系compaer()的数据元素的位序。若这样的数据元素不存在,则返回0*/
 
8.PriorElem(L,cur_e,&pre_e)
/*初始条件:线性表L已存在*/
/*操作结果:若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前驱,否则操作失败,pre_e无定义*/
  
9.NextElem(L,cur_e,&next_e)
/*初始条件:线性表L已存在*/
/*操作结果:若cur_e是L的数据元素,且不是最后一个,则用next_e返回它的后续,否则操作失败,next_e无定义*/
 
10.ListInsert(&L,i,e)
/*初始条件:线性表L已存在*/
/*操作结果:在L中第i个位置之前插入新的数据元素e,L的长度加1*/
 
11.ListDelete(&L,i,&e)
/*初始条件:线性表L已存在*/
/*操作结果:删除L的第i个数据元素,并用e返回其值,L的长度减1*/

2.2.1 GetElem()

typedef int Status;
Status GetElem(SqList L, int i ,ElemType *e)
{
	if (L.length==0 || i<1 || i>L.length)
	{
		return 0;
	}
	*e=L.data[i-1];
	return 1;
}

2.2.2 ListInsert()

Status ListInsert(List &L,int i,ElemType e)
{
	int k;
	if(L->length==MAXSIZE)
	{
		return 0;
	}
	if(i<1 || i>L->length+1)
	{
		return 0;
	}
	if(i<=L->length)
	{
		for(k=L->length-1;k>=i-1;k--)
		{
			L->data[k+1]=L->data[k];
		}
		
	}
	L-?length[i-1]=e;
	L->legnth++;
	return 1;	
}

2.2.3 ListDelete()

Status ListDeletet(List &L,int i,ElemType e)
{
	int k;
	if(L->length==0)
	{
		return 0;
	}
	if(i<1||i>L->length)
	{
		return 0;
	}
	if(i<L->length)
	{
		for(k=i;k<L->length;k++)
		{
			L->data[k-1]=L->data[k];
		}
		L->length--;
	}
	return 1;
}

2.3 链式存储方式

结构定义:
把存储数据元素信息的域称为数据域,把存储直接后继位置的域称为指针域,指针域中存储的信息成为指针或者链。两部分信息组成数据元素成为存储映像,称之为节点。只包含一个指针域的,称之为单链表,两个指针域称之为双链表。

单链表示意图:
在这里插入图片描述
结构定义:

typedef struct Node
{
	ElemType data;  //数据域
	struct Node* Next; //指针域
}Node;

Typedef struct Node* LinkList;

P->Next->data //即获取下一个节点的数据域。

2.3.1 GetElem()

Status GetElem(LinkList L,int i ,ElemType *e)
{
	int j;
	LinkList p;
	p=L->next;
	j=1;
	while(p && j<i)
	{
		p=p->next;
		++j;
	}
	if(!p || i>i)
	{
		return 0;
	}
	*e=p->data;
	return 1;
}

2.3.2 ListInsert()

Status GetElem(LinkList *L,int i ,ElemType e)
{
	int j;
	LinkList p,s;
	p=*L;
	j=1;
	while(j<i)
	{
		p=p->next;
		j++;
	}
	if( !p || j>i )
	{
		return 0;
	}
	s=(LinkList)malloc(sizeof(Node));
	s->data=e;
	s->next=p->next;
	p->next=s;
	return 1;

}

2.3.3 CreateListhead()

void CreateListhead(Linklist *L ,int n)
{
	LinkList p;
	int i;
	srand(time(0));  //初始化随机种子
	*L=(LinkList)malloc(sizeof(Node));
	(*L)->next=NULL;
	for(i=0;i<n;i++)
	{
		p=(LinkList)malloc(sizeif(Node));
		p->data=rand()%100+1;
		p->next=(*L)->next;
		(*L)->next=p;
	}
}

2.3.4 CreateListTail()

void CreateListTail(LinkList *L,int n)
{
	LinkList p,r;
	int i;
	srand(time(0));
	*L=(LinkList)malloc(sizeof(Node));
	r=*L;
	for(i=0;i<n;i++)
	{
		p=(Node *)malloc(sizeof(Node));
		p->data=rand()%100+1;
		r->next=p;
		r=p;
	}
	r-next=NULL;
}

2.3.5 ClearList()

Status ClearList(LinkList *L)
{
	LinkList p,q;
	p=(*L)->next;
	while(p)
	{
		q=p->next;
		free(p);
		p=q;
	}
	(*L)->next=NULL;
	return 1;
}

3. 优缺点对比

  1. 存储分配方式
  2. 时间性能
  3. 空间性能

3.1 存储分配方式

顺序存储:采用一段连续的存储单元依次存储线性表的数据元素。

单链表:采用链式存储结构,用一组任意的存储单元存放线性表的元素。

单链表可以在任意空余空间进行存储,因为指针域中指向的是地址,可以有效利用碎片的空间,但是由于链表将空间分为指针域和数据域,所以在存储上需要的空间比顺序存储来得大。

3.2 时间性能

查找:
顺序链表:时间复杂度O(1)
单链表:时间复杂度O(n)

插入和删除:
顺序链表:需要平均移动表长一半的元素,时间复杂度为O(n)
单链表:得到某个位置的指针后,插入和删除需要的时间复杂度仅仅为O(1)

3.3 空间性能

顺序存储结构:需要预分配存储空间,预分配和实际大小存在一定的差距。
单链表:不需要分配存储空间,有就可以分配,元素个数不受限制。

单链表可以在任意空余空间进行存储,因为指针域中指向的是地址,可以有效利用碎片的空间,但是由于链表将空间分为指针域和数据域,所以在存储上需要的空间比顺序存储来得大。

4. 结论

如果需要频繁查找,较少进行插入和删除操作,则采用顺序表的存储结构,反之亦然。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值