顺序表的基本操作(及动态扩容)

顺序表是在计算机内存中以数组的形式保存的线性表,线性表的顺序存储是指用一组地址连续的存储单元依次存储线性表中的各个元素、使得线性表中在逻辑结构上相邻的数据元素存储在相邻的物理存储单元中,即通过数据元素物理存储的相邻关系来反映数据元素之间逻辑上的相邻关系,采用顺序存储结构的线性表通常称为顺序表。顺序表是将表中的结点依次存放在计算机内存中一组地址连续的存储单元中。顺序表的存储特点是:只要确定了起始位置,表中任一元素的地址都通过下列公式得到:LOC(ai)=LOC(a1)+(i-1)*L  1≤i≤n 其中,L是元素占用存储单元的长度。

基本操作

编写一个完整的程序,实现顺序表的建立、插入、删除、输出等基本运算。
1.顺序表的初始化
2.在pos位置插入val值
3.查找key值
4.删除pos位置的值
5.删除key值
6.得到pos下标的值
7.得到顺序表长度
8.清除顺序表
9.打印顺序表
在对顺序表操作之前,我们应先定义一个结构体来得到该顺序表Sqlist。

#define SIZE 10
typedef struct Sqlist
{
 int elem[SIZE];//定义结构体
 int length;//有效数据个数
}Sqlist, * PSqlist;

1初始化顺序表

void InitSqlist(PSqlist Psq)//初始化
{
 assert(Psq != NULL);
 if (Psq == NULL)
 {
  return;
 }
 Psq->length = 0;
}
static bool IsFULL(PSqlist Psq)//判断顺序表是否满
{
 if (Psq->length == SIZE)
 {
  return true;
 }
 return false;
}

2.在pos位置插入val值

bool Insert(PSqlist Psq, int pos, int val)//在pos位置插入val值
{
 if (IsFULL(Psq))//判断顺序表是否满
 {
  return false;
 }
 if (pos<0 || pos>Psq->length)
 {
  return false;
 }
 for (int i = Psq->length - 1; i >= pos; i--)
 {
  Psq->elem[i + 1] = Psq->elem[i];
 }
 Psq->elem[pos] = val;
 Psq->length++;
 return true;
}

3.查找key值

int Search(PSqlist Psq, int pos, int key)//查找key值  返回下标
{
 if (pos < 0 || pos >= Psq->length)
 {
  return -1;
 }
 for (int i = pos; i < Psq->length; i++)
 {
  if (Psq->elem[i] == key)
  {
   return i;
  }
 }
 return -1;
}

4.删除pos位置的值

bool DeletePos(PSqlist Psq, int pos, int* rtv)//删除pos位置的值
{
 if (pos < 0 || pos >= Psq->length)
 {
  return false;
 }
 if (rtv != NULL)
 {
  *rtv = Psq->elem[pos];
 }
 for (int i = pos; i < Psq->length - 1; i++)
 {
  Psq->elem[i] = Psq->elem[i + 1];
 }
 Psq->length--;
 return true;
}

5.删除key值

//pos:从pos位置开始的第一个key值
bool Delete(PSqlist Psq, int pos, int key)//删除key值
{
 //1 查找是否有key值
 int index = Search(Psq, pos, key);
  if (index < 0)
  {
   return false;
  }
 //2 删除pos位置的值
  return DeletePos(Psq, index, NULL);
}

6.得到pos下标的值

bool GetElem(PSqlist Psq, int pos, int* rtv)//得到pos下标的值
{
 if (pos < 0 || pos >= Psq->length)
 {
  return false;
 }
 if (rtv != NULL)
 {
  *rtv = Psq->elem[pos];
 }
 return true;
}

7.得到顺序表长度

int GetLength(PSqlist Psq)//得到顺序表长度
{
 return Psq->length;
}

8.清除以及摧毁顺序表

void Clear(PSqlist Psq)//清除
{
 Psq->length = 0;
}
void Destory(PSqlist Psq)//摧毁
{
 Clear(Psq);
}

9.打印顺序表

void Show(PSqlist Psq)//打印
{
 for (int i = 0; i < Psq->length; i++)
 {
  printf("%d",Psq->elem[i]);
 }
 printf("\n");
}
动态扩容

在此顺序表中有一个很大的缺点,那就是限定了该顺序表的大小为10,也就是只能顺序存储十个数据,想要存储超过十个数据就需要对该顺序表进行优化,使之可以进行动态扩容。
1.在定义该结构体时加入一个元素记录已使用数据个数。

#define INIT_SIZE 10//初始大小 
typedef struct Sqlist
{
 int* elem;//存储数据的内存
 int usedsize;//有效数据个数
 int size;//总单元个数
}DSqlist, * PDSqlist;

当有效数据个数usedsize达到总单元个数size时,使用realloc函数进行动态扩容。到这样会存在内存块泄漏问题,需要我们对内存块泄漏进行处理。

void Inc(PDSqlist psq)
{
 //psq->elem  扩容对象   psq->size * sizeof(int)* 2  扩容2倍
 assert(psq != NULL);
 psq->elem = (int*)realloc(psq->elem , psq->size * 2 * sizeof(int));//(内存块泄露)
 assert(psq->elem != NULL);
 psq->size *= 2;
}
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Java中,顺序表可以使用数组来实现。当顺序表中的元素个数超过了数组的容量时,需要进行扩容操作,以保证能够继续添加元素。反之,当顺序表中的元素个数变得很少时,可以进行缩容操作,以节约内存空间。 下面是Java中顺序表扩容和缩容实现方法: 1. 扩容 在Java中,数组的容量是固定的,无法动态改变。因此,当需要对数组进行扩容时,需要先创建一个新的数组,将原数组中的元素复制到新数组中,然后再将新元素添加进去。具体步骤如下: ```java public void expandCapacity() { // 创建新数组,长度为原数组的两倍 int newCapacity = elements.length * 2; E[] newElements = (E[]) new Object[newCapacity]; // 将原数组中的元素复制到新数组中 for (int i = 0; i < size; i++) { newElements[i] = elements[i]; } // 将新元素添加到新数组中 newElements[size] = element; // 更新顺序表状态 elements = newElements; size++; } ``` 2. 缩容 在Java中,通过设置数组的长度为0来实现缩容操作。具体步骤如下: ```java public void shrinkCapacity() { // 创建新数组,长度为0 E[] newElements = (E[]) new Object[0]; // 将原数组中的元素复制到新数组中 for (int i = 0; i < size; i++) { newElements[i] = elements[i]; } // 更新顺序表状态 elements = newElements; size = 0; } ``` 需要注意的是,在进行缩容操作时,如果新数组长度为0,那么原数组中的元素就会全部被丢弃,因此需要确保在进行缩容操作之前,顺序表中的元素已经被保存到其他地方了。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值