数据结构--线性表

逻辑结构

集合结构、线性结构、树形结构、图形结构;

物理结构

顺序存储结构、链式存储结构;

算法的特性

输入:算法具有0个或多个输入,对绝大多数算法而言输入参数都是必要的;

输出:算法至少有1个或多个输出,算法一定有输出;

有穷性:算法在执行有限的步骤之后,自动结束而不会出现无限循环,并且每一个步骤在可接受的时间内完成;

确定性:算法的每一个步骤都有明确的含义,不会出现二义性;算法在一定条件下,只有一条执行路径,相同的输入只能有唯一的输出结果;

可行性:算法的每一步都能够通过执行有限的次数完成;

算法设计的要求

正确性、可读性、健壮性、时间效率高和存储量低;

时间复杂度和空间复杂度

算法效率的度量方法:

事后统计方法、事前分析估算方法;

结论:判断一个算法的效率时,函数中的常数和其他次要项常常可以忽略,而更应该关注主项(最高项)的阶数;


常数阶O(1)、线性阶O(n)、平方阶O(n^2)、对数阶O(logn)【2^x=n  》 x=log(2)n】

函数调用的时间复杂度分析:

O(1)<O(logn)<O(n)<O(nlogn)<O(n^2)<O(n^3)<O(2^n)<O(n!)<O(n^n);

最坏情况和平均情况;

算法的空间复杂度:


线性表(List)

定义:由0个或多个数据元素组成的有限序列。


数据类型:是指一组性质相同的值的集合及定义在此集合上的一些操作的总称。

——原子类型:不可再分解的基本类型,例如整型、浮点型、字符型;

——结构类型:由若干个类型组合而成,是可以在分解的,例如整型数组是由若干整型数据组成的;

抽象数据类型(Abstract Data Type,ADT)是指一个数学模型及定义在该模型上的一组操作。抽象数据类型的定义仅取决于它的一组逻辑特性,而与其在计算机内部如何表示和实现无关。


ADT List

Data 

{a1,a2,...,an}

Operation


//La表示A集合,Lb表示B集合。
void unionL(List *La,List Lb)
{
	int La_len,Lb_len,i;
	ElemType e;
	La_len = ListLength(*La)
	Lb_len = ListLength(Lb)
	for(i=1;i<=Lb_len;i++)
	{
		GetElem(Lb,i,&e);
		if(!LocateElem(*La,e))
		{
			ListInsert(La,++La_len,e);
		}
	}
}
线性表的顺序存储结构和链式存储结构

#define MAXSIZE 20
typedef int ELemType;
typedef struct
{
	ElemType data[MAXSIZE]
	int length;	//线性表当前长度
}	SqList;

对数组进行封装,增加了当前长度的变量。

——存储空间的起始位置,数组data,它的存储位置就是线性表存储空间的存储位置;

——线性表的最大存储容量:数组的长度MaxSize;

——线性表的当前长度:length。

地址计算方法:LOC(ai)=LOC(a1)+(i-1)*c

//getElem.c
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
typedef int Status;
//Status是函数的类型,其值是函数结果状态代码,如OK等;
//初识条件:顺序线性表L已存在,1<=i<=ListLength(L)
//操作结果:是用e返回L中第i个数据元素的值
Status GetElem(SqList L,int i,ElemType *e)
{
	if(L.length==0||i<1||i>L.length)
	{
		return ERROR;
	}
	*e=L.data[i-1];
	return OK;
}

/*初始条件:顺序线性表L已存在,1<=i<=Listlength(L)*/
/*操作结果:在L中第i个位置之前插入新的数据元素e,L的长度+1*/
Status ListInsert(SqList *L,int i,ElemType e)
{
	int k;
	if(L->length==MAXSIZE)	//顺序线性表已经满了
	{
		return ERROR;
	}
	if(i<1||i>L->length+1)	//当i不在范围内时
	{
		return ERROR;	
	}
	if(i<=L->length)	//若插入数据位置不在表尾
	{
		/*将要插入位置后数据元素向后移动一位*/
		for(k=L->length-1;k>=i-1;k--)
		{
			L->data[k+1]=L->data[k];
		}
	}
	L->data[i-1]=e;	//将新元素插入
	L->length++;
	return OK;
}

/*初始条件:顺序线性表L已存在,1<=i<=Listlength(L)*/
/*操作结果:删除L的第i个元素,并用e返回其值,L的长度-1*/
Status ListDelete(SqList *L,int i,ElemType e)
{
	int k;
	if(L->length==0)	//顺序线性表为空
	{
		return ERROR;
	}
	if(i<1||i>L->length)	//当i不在范围内时
	{
		return ERROR;	
	}
	*e = L->data[i-1];
	if(i < L->length)	//若删除数据位置不在表尾
	{
		/*将要删除位置后数据元素向前移动一位*/
		for(k=i;k<L->length;;k++)
		{
			L->data[k-1]=L->data[k];
		}
	}	
	L->length--;
	return OK;
}

时间复杂度:

最好情况O(1)

最坏情况O(n)

平均情况[O(1)+O(n)]/2


头指针与头结点的异同




结构指针描述单链表

typedef struct Node
{
	ElemType data;   //数据域
	struct Node* Next;  //指针域
} Node;
typedef struct Node* LinkList;
/*初始条件:顺序线性表L已存在,1<=i<=ListLength(L)*/
/*操作结果:用e返回L中第i个数据元素的值*/
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 || j>i)
	{
		return ERROR;
	}
	*e = P->data;
	return OK;
}
单链表的插入

/*初始条件:顺序线性表L已存在,1<=i<=ListLength(L)*/
/*操作结果:在L中的第i个位置之前插入新的数据元素e,L的长度加1*/
Status ListInsert(LinkList *L,int i,ElemType e)
{
	int j;
	LinkList p,s;
	p=*L;
	j=1;
	while(p&&j<i)	//用于寻找第i个结点
	{
		p=p->next;
		j++;
	}
	if(!p || j>i)
	{
		return ERROR;
	}
	s=(LinkList)malloc(sizeof(Node));
	s->data=e;
	s->next=p->next;
	p->next=s;
	return OK;
}

/*初始条件:顺序线性表L已存在,1<=i<=ListLength(L)*/
/*操作结果:删除L中的第i个数据元素,并用e返回其值,L的长度-1*/
Status ListInsert(LinkList *L,int i,ElemType e)
{
	int j;
	LinkList p,q;
	p=*L;
	j=1;
	while(p->next && j<i)	//用于寻找第i个结点
	{
		p=p->next;
		j++;
	}
	if(!(p->next) || j>i)
	{
		return ERROR;
	}
	q=p->next;
	p->next=q->next;
	*e=q->data;
	free(q);
	return OK;
}
头插法建立单链表

/*头插法建立单链表示例*/
void CreateListHead(LinkList *L,int n)
{
	LinkList p;
	int i;
	srand(time(0));	//初始化随机数种子
	(*L)->next=NULL;
	for(i=0;i<n;i++)
	{
		p=(LinkList)malloc(sizeof(Node));	//生成新结点
		p->data=rand()%100+1;
		p->next=(*L)->next;
		(*L)->next=p;
	}
}
尾插法建立单链表

/*尾插法建立单链表示例*/
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;
}















































  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值