算法通关村———不简单的数组增删查改
线性表基础
- 1 线性表:具有相同特征数据元素的一个有限序列,其中所含元素的个数为线性表的长度,从不同角度看,线性表可以有不同的分类
** 从语言角度**有两种,一体式和分离式
(a)为一体式(b)为分离式
一体式:储存表的信息单元与元素储存区以连续的方式安排在一块存储区里,两部分数据的整体形成一个完整的顺序表对象。这种结构整体性更强,易于管理。但是由于数据元素存储区域是表对象的一部分,顺序表创建后,元素存储区就固定了。c和c++都是一体式结构。
分离式结构:表对象里只保存整个表有关的信息(即容量和元素个数),实际数据元素存放在另一个独立的怨怒是存储区里,通过链接与基本表对象关联。java和python是分离式结构。
**从存储角度 **
有顺序性和链表型,
顺序性:将数据存放在一段固定的区间内,此时访问元素的效率非常高,但是删除和增加元素的代价比较大,如果要扩容只能整体搬迁。
链表型:元素之间是通过地址依次链接,因此访问时必须从头开始逐步向后找,因此查找效率低,而删除和增加元素非常方便,并且也不用考虑扩容问题,链表的常见实现方式又有单链表,循环链表,双向链表。
从访问限制的角度
栈和队列又称为访问受限的线性表,插入和删除受到了限制,只能在固定的位置进行。而Hash比较特殊,其内部真正的储存数据一般是数组,但是访问是通过映射来实现的,因此大部分材料里并不将Hash归结到线性表中,
线性表的常见操作
从扩容角度
采用分离式结构的顺序表,若将数据区更换为存储空间更大的区域,则可以在不改变表对象的前提下对其数据存储区域进行扩充,所有使用这个表的地方都不必修改。只要程序的运行环境还有空闲存储,这种表结构就不会因为满了而导致操作无法进行。人们把采用这种技术实现的顺序表称为动态顺序表,因为其容量可以在使用中动态变化。
扩容策略
1.每次扩充增加固定数目的存储位置,如每次扩充增加10个元素位置,这种策略可称为线性增长。特点:节省空间,但是扩充操作频繁,操作次数多
2.每次扩容加倍,如每次扩充增加一倍的存储空间。== 特点:减少了扩充操作的执行次数,但是可能浪费空间资源,以空间换时间,推荐的方式==
2. 2数组概念
数组是线性表中最基本的结构,特点是元素是一个紧密在一起的序列,相互之间不需要记录彼此的关系就能访问。
注意点:1.是从0开始记录,第一个元素的位置是a[0],2.数组中元素在内存中是连续存储的,且每个元素占用的内存大小相同.3.数组空间不一定是满的,100的空间可能只用了10个,size和length可能不一样
数组基本操作
- 查找元素
int findelement(int arr[],int size, int key)
{
for(int i=0l;i<size;i++)
{
if(arr[i] == key)
{
return i;
}
}
return -1;
}
- 增加一个元素
思路
int addByElementSequence(int arr[],int size,int element)
{
if(size>=sizeof(arr[])/sizeof(arr[0]))//如果插入位置大于数组长度则返回-1
{
return -1;
}
int index = size;
for(int i=0;i<size;i++)
{
if(element<arr[i])
{
int index = i
break;
}
}
for(int j=size;j>index;j--)
{
arr[j]=j[j-1];
}
}
- 删除元素
思路
int removebyelement(int arr[],int size,int key)
{
int index= -1;
for(int i=0;i<size;i++)
{
if(arr[i]==key)
{
index=i;
break;
}
}
if(index!=-1)
{
for(int i=index+1;i<size;i++)
{
arr[i-1]=arr[i];
}
size--;
}
return size;
}