动态顺序表的详解(下)

简介: 动态顺序表的详解(下)

顺序表的尾删

有了尾插也一定有尾删,直接看代码。

void SLPopBack(SL* psl)
{
  assert(psl);
  assert(psl->size>0);
  psl->size--;
} 

由于是尾部删除,我们只需要将最后一个数据丢失即可,我们舍弃最后一个数据,只需要通过psl指针找到的size–即可。

顺序表的头删

有了头插也一定有头删,看一下吧。

void SLPopFront(SL* psl)
{
  assert(psl);
  assert(psl->size>0);
  int begin=1;
  while(begin<psl->size)
  {
    psl->a[begin-1]=psl->a[begin];
    begin++;
  }
  psl->size--;
}

首先,依然是断言保证传入指针非空,保证有效数据个数不为0,之后我们需要从开始将第二个元素赋给第一个元素,再把第三个元素赋给第二个元素,这样下去,就能实现头删,我们定义一个begin变量为1,在while循环中将begin个元素赋给begin-1个元素,之后begin++,实现赋值循环。

顺序表的任意位置插入

有了头插和尾插,我们接下里在任意位置插入,直接上代码。

void SLInsert(SL* psl,int pos,SLDataType x)
{
  assert(psl);
  assert(pos>0&&pos<=psl->size);
  SLCheckCapacity(&psl);
  int end=psl->size-1;
  while(end>=pos)
  {
    psl->a[end+1]=psl->a[end];
    end--;
  }
  psl->a[pos]=x;
  psl->size++;
}

首先,我们需要保证传入指针非空,传入pos合法,以及容量足够,之后进行数据移动,和头插十分相似,知识不懂pos位置之前的数据,所以只需要将0替换为pos即可。之后将x存储到第pos个位置中去,psl所指向的size++即可。

顺序表的任意位置删除

有任意位置插入,就可以有任意位置删除,我们直接看代码。

void SLErase(SL* psl, int pos)
{
  assert(psl);
  assert(pos>0&&pos<=psl->size)
  int begin=pos+1;
  while(begin<psl->size)
  {
    psl->a[begin-1]=psl->a[begin];
    begin++;
  }
  psl->size--;
}

首先,依然是断言,保证pos的合法,之后和头删的操作其实很相似,我们把第pos个位置看成首地址去进行头删即可。

顺序表的查找

我们可能会需要查找顺序表的某个元素,来实现一下

void SLFind(SL* psl,SLDataType x)
{
  assert(psl);
  for(int i=0;i<psl->size;i++)
  {
    if(psl->a[i]==x)
    {
      return i;
    }
  }
  return -1;
}

直接,遍历之后找到下表就返回i,没有就返回-1。

代码与总结

顺序表可以帮助我们实现一些信息的管理,有助于我们写一些学生信息管理等等,相信大家都能够做出来这样的系统,就不再展示,以后有机会会展示给大家。

最后给大家看一下,鄙人的代码实现,是封装为3个文件的。

SeqList.h

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef int SLDataType;
typedef struct SeqList
{
  SLDataType* a;
  int size;  //有效数据
  int capacity;  //空间容量
}SL;
void SLInit(SL* psl);//初始化顺序表
void SLDestroy(SL* psl);//销毁顺序表
void SLPushBack(SL* psl, SLDataType x);//头插
void SLPushFront(SL* psl, SLDataType x);//尾插
void SLPrint(SL* psl);//打印顺序表
void SLCheckCapacity(SL* psl);//增容
void SLPopBack(SL* psl);//尾删
void SLPopFront(SL* psl);//头删
// 任意下标位置的插入删除
void SLInsert(SL* psl, int pos, SLDataType x);
void SLErase(SL* psl, int pos);

SeqList.c

#define  _CRT_SECURE_NO_WARNINGS
#include"SeqList.h"
void SLInit(SL* psl)
{
  assert(psl);
  psl->a = NULL;
  psl->size = 0;
  psl->capacity = 0;
}
void SLDestroy(SL* psl)
{
  assert(psl);
  if (psl->a != NULL)
  {
    free(psl->a);
    psl->a = NULL;
    psl->size = 0;
    psl->capacity = 0;
  }
}
void SLPrint(SL* psl)
{
  assert(psl);
  for (int i = 0; i < psl->size; i++)
  {
    printf("%d ", psl->a[i]);
  }
  printf("\n");
}
void SLCheckCapacity(SL* psl)
{
  assert(psl);
  if (psl->size == psl->capacity)
  {
    int newcapacity = psl->capacity == 0 ? 4 : psl->capacity * 2;
    SLDataType* tmp = (SLDataType*)realloc(psl->a,sizeof(SLDataType) * newcapacity);
    if (tmp == NULL)
    {
      perror("realloc fail");
      return;
    }
    psl->a = tmp;
    psl->capacity = newcapacity;
  }
}
void SLPushBack(SL* psl, SLDataType x)
{
  assert(psl);
  SLCheckCapacity(psl);
  psl->a[psl->size] = x;
  psl->size++;
}
void SLPushFront(SL* psl, SLDataType x)
{
  assert(psl);
  SLCheckCapacity(psl);
  int end = psl->size-1;
  while (end >= 0)
  {
    psl->a[end+1] = psl->a[end];
    end--;
  }
  psl->a[0] = x;
  psl->size++;
}
void SLPopBack(SL* psl)
{
  assert(psl);
  assert(psl->size > 0);
  psl->size--;
}
void SLPopFront(SL* psl)
{
  assert(psl);
  assert(psl->size > 0);
  int begin = 1;
  while (begin < psl->size)
  {
    psl->a[begin - 1] = psl->a[begin];
    begin++;
  }
  psl->size--;
}
// 任意下标位置的插入删除
void SLInsert(SL* psl, int pos, SLDataType x)
{
  assert(psl);
  assert(pos > 0 && pos <= psl->size);
  SLCheckCapacity(psl);
  int end = psl->size - 1;
  while (end >=pos)
  {
    psl->a[end+1] = psl->a[end];
    end--;
  }
  psl->a[pos] = x;
  psl->size++;
}
void SLErase(SL* psl, int pos)
{
  assert(psl);
  assert(pos > 0 && pos <= psl->size);
  int begin = pos+1;
  while (begin <psl->size)
  {
    psl->a[begin-1] = psl->a[begin];
    begin++;
  }
  psl->size--;
}

还有一个test.c的文件是用来测试顺序表的,大家自行测试即可,谢谢大家的观看!

目录
相关文章
|
3天前
|
存储 测试技术 C语言
顺序表详解(SeqList)
顺序表详解(SeqList)
41 0
|
7月前
|
存储
【顺序表】
【顺序表】
33 0
|
3天前
动态顺序表
动态顺序表
25 0
|
3天前
|
存储
顺序表讲解
顺序表讲解
25 0
|
3天前
顺序表的实现
顺序表的实现
|
6月前
|
存储
动态顺序表的详解(上)
动态顺序表的详解(上)
68 0
|
6月前
|
测试技术
顺序表(2)
顺序表(2)
530 0
|
6月前
|
存储 C语言
顺序表(1)
顺序表(1)
53 0
|
6月前
|
存储 NoSQL
03 顺序表
03 顺序表
17 0
|
9月前
|
存储 C++
7.2 C/C++ 实现动态链表
动态链表是一种常用的动态数据结构,可以在运行时动态地申请内存空间来存储数据,相比于静态数组和静态链表,更加灵活和高效。在动态链表中,数据元素被组织成一条链表,每个元素包含了指向下一个元素的指针,这样就可以通过指针将所有元素串联起来。使用动态链表存储数据时,不需要预先申请内存空间,而是在需要的时候才向内存申请。当需要添加新的元素时,可以使用`malloc`函数动态地申请内存空间,然后将新的元素插入到链表中;当需要删除元素时,可以使用`free`函数释放元素占用的内存空间,然后将链表中的指针重新连接。
170 0