<数据结构> 顺序表

简介: 目录一、顺序表介绍二、准备工作 1、创建顺序表 2、初始化顺序表 3、检测是否需要扩容 4、销毁顺序表 5、打印顺序表三、四大功能 1、增加数据 头插 尾插 指定下标插入 2、删除数据 头删 尾删 指定下标删除

一、顺序表介绍

  • 概念及结构

顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。

顺序表一般可以分为:

1. 静态顺序表:使用定长数组存储元素。

image.png

2. 动态顺序表:使用动态开辟的数组存储。image.png要求:

顺序表要求存储的数据是从0开始,依次连续存储,中间不能有空的。


接口实现

静态顺序表只适用于确定知道需要存多少数据的场景。静态顺序表的定长数组导致N定大了,空间开多了浪费,开少了不够用。所以现实中基本都是使用动态顺序表,根据需要动态的分配空间大小,所以下面我们实现动态顺序表。


注:

本文将创建SeqList.h、SeqList.c、Test.c三个文件夹,分别用于声明,定义,具体实现


正文开始:

二、准备工作

1、创建顺序表

  • SeqList.h文件:
//创建顺序表
typedef int SLDataType; //确保以后想存其它类型的时候方便改动,本文以存放整型数据为例
typedef struct SeqList
{
  SLDataType* a; //动态开辟数组
  int size;    //存储顺序表中有效数据个数
  int capacity;//存储空间个数-->记录最大容量 
}SeqList; 

2、初始化顺序表

  • SeqList.h文件:
1. //初始化顺序表
2. void SeqListInit(SeqList* psl);
  • SeqList.c文件:
//初始化通讯录
void SeqListInit(SeqList* psl)
{
  assert(psl);
  psl->a = NULL;
  psl->size = 0;
  psl->capacity = 0;
}

3、检测是否需要扩容

  • SeqList.h文件:
1. //检测是否需要扩容
2. void SeqListCheckCapacity(SeqList* psl);
  • SeqList.c文件:
//检测是否需要扩容
void SeqListCheckCapacity(SeqList* psl)
{
  assert(psl);
  //如果满了,就要扩容
  if (psl->size == psl->capacity)
  {
    size_t newCapacity = psl->capacity == 0 ? 4 : psl->capacity * 2; //防止原始capacity的容量本身为0,导致后续扩容仍为0
    SLDataType* tmp = realloc(psl->a, sizeof(SLDataType) * newCapacity);
    if (tmp == NULL)
    {
      printf("realloc fail\n");
      exit(-1);
    }
    else
    {
      psl->a = tmp;
      psl->capacity = (int)newCapacity;
    }
  }
}
  • 注意:

当realloc的指针为空时,此时realloc就相当于malloc

4、销毁顺序表

  • SeqList.h文件:
//销毁顺序表
void SeqListDestroy(SeqList* psl);
  • SeqList.c文件:
//销毁顺序表
void SeqListDestroy(SeqList* psl)
{
  assert(psl);
  free(psl->a);
  psl->a = NULL;
  psl->capacity = psl->size = 0;
}

5、打印顺序表

  • 思想:

只需for循环依次打印即可

  • SeqList.h文件:
//打印顺序表
void SeqListPrint(SeqList* psl);
  • SeqList.c文件:
//打印顺序表
void SeqListPrint(SeqList* psl)
{
  assert(psl);
  for (int i = 0; i < psl->size; i++)
  {
    printf("%d ",psl->a[i]);
  }
  printf("\n");
}

三、四大功能

1、增加数据

头插

  • 思想:

比尾插稍微复杂一点,头插就是把最后一个数字往后挪,再把前一个数字往后挪,以此类推,直到把第一个位置给它空出来,但是前提是得确保空间足够,不够就得扩容

  • SeqList.h文件:
//头插
void SeqListPushFront(SeqList* psl, SLDataType x);
  • SeqList.c文件:
//头插
void SeqListPushFront(SeqList* psl, SLDataType x)
{
  assert(psl);
  SeqListCheckCapacity(psl); //检测容量
  int end = psl->size - 1;
  while (end >= 0)
  {
    psl->a[end + 1] = psl->a[end];
    end--;
  }
  psl->a[0] = x;
  psl->size++;
}
  • Test.c文件:
int main()
{
  SeqList s;
  SeqListInit(&s); //一定要加上&,因为形参的改变不会影响实参,要传地址
  //先尾插4个数字
  SeqListPushBack(&s, 1);
  SeqListPushBack(&s, 2);
  SeqListPushBack(&s, 3);
  SeqListPushBack(&s, 4);
  SeqListPrint(&s); //尾插4次后打印
  //头插2个数字
  SeqListPushFront(&s, 0);
  SeqListPushFront(&s, -1);
  SeqListPrint(&s); //头插2次后打印
  return 0;
}
  • 效果如下:image.png

尾插

  • 思想:

其实数组a的下标size就是最后一个数据的下一个位置,尾插只需要在ps->size处插入一个数据即可,不过前提是要先检查容量是否满

  • SeqList.h文件:
//尾插
void SeqListPushBack(SeqList* psl, SLDataType x);
  • SeqList.c文件:
//尾插
void SeqListPushBack(SeqList* psl, SLDataType x)
{
  assert(psl);
  SeqListCheckCapacity(psl); //检测容量
  psl->a[psl->size] = x;
  psl->size++;
}
  • Test.c文件:
int main()
{
  SeqList s;
  SeqListInit(&s); //一定要加上&,因为形参的改变不会影响实参,要传地址
  //尾插5个数字
  SeqListPushBack(&s, 1);
  SeqListPushBack(&s, 2);
  SeqListPushBack(&s, 3);
  SeqListPushBack(&s, 4);
  SeqListPushBack(&s, 5);
  SeqListPrint(&s); //打印
  return 0;
}
  • 效果如下:image.png

指定下标插入

  • 思想:

其实指定位置插入的思想同上文的尾插是很相似的,但是要确保这个指定插入的位置在有效数据size范围内,不然就会出现越界,就不是顺序表了,

  • SeqList.h文件:
//在pos位置插入x
void SeqListInsert(SeqList* psl, size_t pos, SLDataType x);
  • SeqList.c文件:
//在pos位置插入x
void SeqListInsert(SeqList* psl, size_t pos, SLDataType x)
{
  assert(psl);
  //暴力检查
  /*assert(pos <= psl->size && psl);*/
  //温和检查
  if (pos > psl->size)
  {
    printf("pos 越界:%d\n", (int)pos);
    return;
  }
  SeqListCheckCapacity(psl); //检测容量
  int end = psl->size - 1;
  while (end >= (int)pos)
  {
    psl->a[end + 1] = psl->a[end];
    end--;
  }
  psl->a[pos] = x;
  psl->size++;
}
  • Test.c文件:
int main()
{
  SeqList s;
  SeqListInit(&s);
  //先尾插4个数字
  SeqListPushBack(&s, 1);
  SeqListPushBack(&s, 2);
  SeqListPushBack(&s, 3);
  SeqListPushBack(&s, 4);
  SeqListPrint(&s); //尾插4次后打印
  //指定下标插入2个数字
  SeqListInsert(&s, 10, 100);
  SeqListInsert(&s, 1, 20);
  SeqListPrint(&s); //插入成功后打印
  SeqListDestroy(&s);
  return 0;
}
  • 效果如下:image.png注意:

当我们实现完指定下标插入时,我们发现当pos=size时,实现的就是尾插

//尾插
void SeqListPushBack(SeqList* psl, SLDataType x)
{
  assert(psl);
//法一:
  /*SeqListCheckCapacity(psl); //检测容量
  psl->a[psl->size] = x;
  psl->size++;*/
//法二:
  SeqListInsert(psl, psl->size, x);
}

类似的,当pos=0时,实现的就是头插,如下:

//头插
void SeqListPushFront(SeqList* psl, SLDataType x)
{
  assert(psl);
//法一:
  /*SeqListCheckCapacity(psl); //检测容量
  int end = psl->size - 1;
  while (end >= 0)
  {
    psl->a[end + 1] = psl->a[end];
    end--;
  }
  psl->a[0] = x;
  psl->size++;*/
//法二:
  SeqListInsert(psl, 0, x);
}

2、删除数据

头删

  • 思想:

头删不需要考虑扩容,头删需要把第二个数字往前挪,再把下一个数字往前挪,以此类推,注意,再删数据时要确保有效数据size恒>=0,以保证后续能够正常加数据。

  • SeqList.h文件:
//头删
void SeqListPopFront(SeqList* psl);
  • SeqList.c文件:
//头删
void SeqListPopFront(SeqList* psl)
{
  assert(psl);
  if (psl->size > 0)
  {
    int begin = 1;
    while (begin < psl->size)
    {
      psl->a[begin - 1] = psl->a[begin];
      begin++;
    }
    psl->size--;
  }
}
  • Test.c文件:
int main()
{
  SeqList s;
  SeqListInit(&s);
  //尾插10个数字
  for (int i = 1; i <= 10; i++)
  {
    SeqListPushBack(&s, i);
  }
  SeqListPrint(&s); //尾插10个数字后打印
  //头删12次数据
  for (int i = 1; i <= 12; i++)
  {
    SeqListPopFront(&s);
  }
  SeqListPrint(&s); //头删12次后打印
  //头插5个数字
  for (int i = -5; i <= -1; i++)
  {
    SeqListPushFront(&s, i);
  }
  SeqListPrint(&s); //头插5次后打印
  return 0;
}
  • 效果如下:image.png尾删

思想:

这里size就是统计开辟的数组中有效数据的个数,只需要把有效数据的个数-1,打印的时候自然会把原本最后一个数据给删掉,但是要注意,如果删除次数过多,有效数据size可能会变成负的,为了避免这一现象,只需要确保在size>0时再减减即可,同样为了防止传入空指针,只需要assert断言即可。


SeqList.h文件:

//尾删
void SeqListPopBack(SeqList* psl);
  • SeqList.c文件:
//尾删
void SeqListPopBack(SeqList* psl)
{
  assert(psl);
  if (psl->size > 0)
  {
    psl->size--;
  }
}
  • Test.c文件:
int main()
{
  SeqList s;
  SeqListInit(&s); //一定要加上&,因为形参的改变不会影响实参,要传地址
  //尾插5个数字
  SeqListPushBack(&s, 1);
  SeqListPushBack(&s, 2);
  SeqListPushBack(&s, 3);
  SeqListPushBack(&s, 4);
  SeqListPushBack(&s, 5);
  SeqListPrint(&s); //尾插5次后打印
  //尾删6个数字
  SeqListPopBack(&s);
  SeqListPopBack(&s);
  SeqListPopBack(&s);
  SeqListPopBack(&s);
  SeqListPopBack(&s);
  SeqListPopBack(&s);
  SeqListPopBack(&s);
  SeqListPrint(&s); //尾删6次后打印
  //再尾插2个数字
  SeqListPushBack(&s, 6);
  SeqListPushBack(&s, 7);
  SeqListPrint(&s); //再尾插2次打印
  return 0;
}
  • 效果如下:image.png指定下标删除

思想:

其实思想并不复杂,首先要断言不是空指针,其次要确保下标pos<size,不能=size,因为下标size的值是空的,并非有效数据,若=size则删除一个无意义的数,接下来就跟头删类似了,把pos后一个位置挪到前一个,再换下一个,依次类推


SeqList.h文件:

//删除pos位置的数据
void SeqListErase(SeqList* psl, size_t pos);
  • SeqList.c文件:
//删除pos位置的数据
void SeqListErase(SeqList* psl, size_t pos)
{
  assert(psl);
  assert(pos < psl->size);
  size_t begin = pos + 1;
  while (begin < psl->size)
  {
    psl->a[begin - 1] = psl->a[begin];
    ++begin;
  }
  psl->size--;
}
  • Test.c文件:
int main()
{
  SeqList s;
  SeqListInit(&s);
  //先尾插4个数字
  SeqListPushBack(&s, 1);
  SeqListPushBack(&s, 2);
  SeqListPushBack(&s, 3);
  SeqListPushBack(&s, 4);
  SeqListPrint(&s); //尾插4次后打印
  //删除2个指定下标的数字
  SeqListErase(&s, 3);//下标3
  SeqListErase(&s, 1);//下标1
  SeqListPrint(&s); //删除后打印
  return 0;
}
  • 效果如下:image.png 注意:

当pos=size-1时,删除的就是最后一个数字,实现的就是尾删,所以尾删可以这样写:

//尾删
void SeqListPopBack(SeqList* psl)
{
  assert(psl);
  /*if (psl->size > 0)
  {
    psl->size--;
  }*/
  SeqListErase(psl, psl->size - 1);
}

当pos=0时,删除的就是第一个数字,实现的就是头删,所以头删也可以这样解决

//头删
void SeqListPopFront(SeqList* psl)
{
  assert(psl);
//法一:
  /*if (psl->size > 0)
  {
    int begin = 1;
    while (begin < psl->size)
    {
      psl->a[begin - 1] = psl->a[begin];
      begin++;
    }
    psl->size--;
  }*/
//法二:指定下标删除法
  SeqListErase(psl, 0);
}

3、查找数据

  • 思想:

遍历数组即可。

  • SeqList.h文件:
//查找指定数字
int SeqListFind(SeqList* psl, SLDataType x);
  • SeqList.c文件:
//查找指定数字
int SeqListFind(SeqList* psl, SLDataType x)
{
  assert(psl);
  for (int i = 0; i < psl->size; i++)
  {
    if (psl->a[i] == x)
    {
      return i;
    }
  }
  return -1;
}
  • Test.c文件:
int main()
{
  SeqList s;
  SeqListInit(&s);
  //先尾插4个数字
  SeqListPushBack(&s, 1);
  SeqListPushBack(&s, 2);
  SeqListPushBack(&s, 3);
  SeqListPushBack(&s, 4);
  SeqListPrint(&s); //尾插4次后打印
  int pos = SeqListFind(&s, 3);
  if (pos != -1)
    printf("找到了,下标是:%d", pos);
  else
    printf("找不到\n");
  return 0;
}
  • 效果如下:image.png

4、修改数据

  • 思想:

只需要把指定下标的数字进行修改即可,前提是修改的数字是有效数据

  • SeqList.h文件:
//修改指定下标数字
void SeqListModify(SeqList* psl, size_t pos, SLDataType x);
  • SeqList.c文件:
//修改指定下标数字
void SeqListModify(SeqList* psl, size_t pos, SLDataType x)
{
  assert(psl);
  assert(pos < psl->size);
  psl->a[pos] = x;
}
  • Test.c文件:
int main()
{
  SeqList s;
  SeqListInit(&s);
  //先尾插4个数字
  SeqListPushBack(&s, 1);
  SeqListPushBack(&s, 2);
  SeqListPushBack(&s, 3);
  SeqListPushBack(&s, 4);
  SeqListPrint(&s); //尾插4次后打印
  SeqListModify(&s, 1, 5);
  SeqListPrint(&s); //修改后打印
  int pos = SeqListFind(&s, 3);
  if (pos != -1)
  {
    SeqListModify(&s, pos, 5000);
    SeqListPrint(&s); //查找再修改后打印
  }
  return 0;
}
  • 效果如下:image.png

四、总代码

1、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;//存储空间个数-->记录最大容量 
}SeqList;
//初始化顺序表
void SeqListInit(SeqList* psl);
//检测是否需要扩容
void SeqListCheckCapacity(SeqList* psl);
//打印顺序表
void SeqListPrint(SeqList* psl);
//销毁顺序表
void SeqListDestroy(SeqList* psl);
//尾插
void SeqListPushBack(SeqList* psl, SLDataType x);
//尾删
void SeqListPopBack(SeqList* psl);
//头插
void SeqListPushFront(SeqList* psl, SLDataType x);
//头删
void SeqListPopFront(SeqList* psl);
//在pos位置插入x
void SeqListInsert(SeqList* psl, size_t pos, SLDataType x);
//删除pos位置的数据
void SeqListErase(SeqList* psl, size_t pos);
//查找指定数字
int SeqListFind(SeqList* psl, SLDataType x);
//修改指定下标数字
void SeqListModify(SeqList* psl, size_t pos, SLDataType x);

2、SeqList.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"SeqList.h"
//初始化通讯录
void SeqListInit(SeqList* psl)
{
  assert(psl);
  psl->a = NULL;
  psl->size = 0;
  psl->capacity = 0;
}
//检测是否需要扩容
void SeqListCheckCapacity(SeqList* psl)
{
  assert(psl);
  //如果满了,就要扩容
  if (psl->size == psl->capacity)
  {
    size_t newCapacity = psl->capacity == 0 ? 4 : psl->capacity * 2; //防止原始capacity的容量本身为0,导致后续扩容仍为0
    SLDataType* tmp = realloc(psl->a, sizeof(SLDataType) * newCapacity);
    if (tmp == NULL)
    {
      printf("realloc fail\n");
      exit(-1);
    }
    else
    {
      psl->a = tmp;
      psl->capacity = (int)newCapacity;
    }
  }
}
//打印顺序表
void SeqListPrint(SeqList* psl)
{
  assert(psl);
  for (int i = 0; i < psl->size; i++)
  {
    printf("%d ", psl->a[i]);
  }
  printf("\n");
}
//销毁顺序表
void SeqListDestroy(SeqList* psl)
{
  assert(psl);
  free(psl->a);
  psl->a = NULL;
  psl->capacity = psl->size = 0;
}
//尾插
void SeqListPushBack(SeqList* psl, SLDataType x)
{
  assert(psl);
  //法一:
    /*SeqListCheckCapacity(psl); //检测容量
    psl->a[psl->size] = x;
    psl->size++;*/
  //法二:指定下标插入
  SeqListInsert(psl, psl->size, x);
}
//尾删
void SeqListPopBack(SeqList* psl)
{
  assert(psl);
  /*if (psl->size > 0)
  {
    psl->size--;
  }*/
  SeqListErase(psl, psl->size - 1);
}
//头插
void SeqListPushFront(SeqList* psl, SLDataType x)
{
  assert(psl);
//法一:
  /*SeqListCheckCapacity(psl); //检测容量
  int end = psl->size - 1;
  while (end >= 0)
  {
    psl->a[end + 1] = psl->a[end];
    end--;
  }
  psl->a[0] = x;
  psl->size++;*/
//法二:指定下标插入法
  SeqListInsert(psl, 0, x);
}
//头删
void SeqListPopFront(SeqList* psl)
{
  assert(psl);
//法一:
  /*if (psl->size > 0)
  {
    int begin = 1;
    while (begin < psl->size)
    {
      psl->a[begin - 1] = psl->a[begin];
      begin++;
    }
    psl->size--;
  }*/
//法二:指定下标删除法
  SeqListErase(psl, 0);
}
//在pos位置插入x
void SeqListInsert(SeqList* psl, size_t pos, SLDataType x)
{
  assert(psl);
  //暴力检查
  /*assert(pos <= psl->size && psl);*/
  //温和检查
  if (pos > psl->size)
  {
    printf("pos 越界:%d\n", (int)pos);
    return;
  }
  SeqListCheckCapacity(psl); //检测容量
  int end = psl->size - 1;
  while (end >= (int)pos)
  {
    psl->a[end + 1] = psl->a[end];
    end--;
  }
  psl->a[pos] = x;
  psl->size++;
}
//删除pos位置的数据
void SeqListErase(SeqList* psl, size_t pos)
{
  assert(psl);
  assert(pos < psl->size);
  size_t begin = pos + 1;
  while (begin < psl->size)
  {
    psl->a[begin - 1] = psl->a[begin];
    ++begin;
  }
  psl->size--;
}
//查找指定数字
int SeqListFind(SeqList* psl, SLDataType x)
{
  assert(psl);
  for (int i = 0; i < psl->size; i++)
  {
    if (psl->a[i] == x)
    {
      return i;
    }
  }
  return -1;
}
//修改指定下标数字
void SeqListModify(SeqList* psl, size_t pos, SLDataType x)
{
  assert(psl);
  assert(pos < psl->size);
  psl->a[pos] = x;
}

3、Test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"SeqList.h"
void test1()
{
  SeqList s;
  SeqListInit(&s); //一定要加上&,因为形参的改变不会影响实参,要传地址
  //尾插5个数字
  SeqListPushBack(&s, 1);
  SeqListPushBack(&s, 2);
  SeqListPushBack(&s, 3);
  SeqListPushBack(&s, 4);
  SeqListPushBack(&s, 5);
  SeqListPrint(&s); //尾插5次后打印
  //尾删6个数字
  SeqListPopBack(&s);
  SeqListPopBack(&s);
  SeqListPopBack(&s);
  SeqListPopBack(&s);
  SeqListPopBack(&s);
  SeqListPopBack(&s);
  SeqListPopBack(&s);
  SeqListPrint(&s); //尾删6次后打印
  //再尾插2个数字
  SeqListPushBack(&s, 6);
  SeqListPushBack(&s, 7);
  SeqListPrint(&s); //再尾插2次打印
}
void TestSeqList2()
{
  SeqList s;
  SeqListInit(&s); //一定要加上&,因为形参的改变不会影响实参,要传地址
  //先尾插4个数字
  SeqListPushBack(&s, 1);
  SeqListPushBack(&s, 2);
  SeqListPushBack(&s, 3);
  SeqListPushBack(&s, 4);
  SeqListPrint(&s); //尾插4次后打印
  //头插2个数字
  SeqListPushFront(&s, 0);
  SeqListPushFront(&s, -1);
  SeqListPrint(&s); //头插2次后打印
}
void TestSeqList3()
{
  SeqList s;
  SeqListInit(&s);
  //先尾插4个数字
  SeqListPushBack(&s, 1);
  SeqListPushBack(&s, 2);
  SeqListPushBack(&s, 3);
  SeqListPushBack(&s, 4);
  SeqListPrint(&s); //尾插4次后打印
  //头删
  SeqListPopFront(&s);
  SeqListPopFront(&s);
  SeqListPopFront(&s);
  SeqListPopFront(&s);
  SeqListPopFront(&s);
  SeqListPopFront(&s);
  SeqListPrint(&s); //头删6次后打印
  //头插2个数字
  SeqListPushFront(&s, 0);
  SeqListPushFront(&s, -1);
  SeqListPrint(&s); //头插2次后打印
}
void TestSeqList4()
{
  SeqList s;
  SeqListInit(&s);
  //尾插10个数字
  for (int i = 1; i <= 10; i++)
  {
    SeqListPushBack(&s, i);
  }
  SeqListPrint(&s); //尾插10个数字后打印
  //头删12次数据
  for (int i = 1; i <= 12; i++)
  {
    SeqListPopFront(&s);
  }
  SeqListPrint(&s); //头删12次后打印
  //头插5个数字
  for (int i = -5; i <= -1; i++)
  {
    SeqListPushFront(&s, i);
  }
  SeqListPrint(&s); //头插5次后打印
}
void TestSeqList5()
{
  SeqList s;
  SeqListInit(&s);
  //先尾插4个数字
  SeqListPushBack(&s, 1);
  SeqListPushBack(&s, 2);
  SeqListPushBack(&s, 3);
  SeqListPushBack(&s, 4);
  SeqListPrint(&s); //尾插4次后打印
  //指定下标插入2个数字
  SeqListInsert(&s, 10, 100);
  SeqListInsert(&s, 1, 20);
  SeqListInsert(&s, 5, 50);
  SeqListPrint(&s); //指定插入2次后打印
  SeqListDestroy(&s);
}
int main()
{
  SeqList s;
  SeqListInit(&s);
  //先尾插4个数字
  SeqListPushBack(&s, 1);
  SeqListPushBack(&s, 2);
  SeqListPushBack(&s, 3);
  SeqListPushBack(&s, 4);
  SeqListPrint(&s); //尾插4次后打印
  SeqListModify(&s, 1, 5);
  SeqListPrint(&s); //修改后打印
  int pos = SeqListFind(&s, 3);
  if (pos != -1)
  {
    SeqListModify(&s, pos, 5000);
    SeqListPrint(&s); //查找再修改后打印
  }
  return 0;
}
相关文章
|
2月前
|
存储 C语言
【数据结构】顺序表
数据结构中的动态顺序表
35 3
【数据结构】顺序表
|
3月前
|
存储
数据结构—顺序表(如果想知道顺序表的全部基础知识点,那么只看这一篇就足够了!)
数据结构—顺序表(如果想知道顺序表的全部基础知识点,那么只看这一篇就足够了!)
|
3天前
|
存储 Java 程序员
【数据结构】初识集合&深入剖析顺序表(Arraylist)
Java集合框架主要由接口、实现类及迭代器组成,包括Collection和Map两大类。Collection涵盖List(有序、可重复)、Set(无序、不可重复),Map则由键值对构成。集合通过接口定义基本操作,具体实现由各类如ArrayList、HashSet等提供。迭代器允许遍历集合而不暴露其实现细节。List系列集合元素有序且可重复,Set系列元素无序且不可重复。集合遍历可通过迭代器、增强for循环、普通for循环及Lambda表达式实现,各有适用场景。其中ArrayList实现了动态数组功能,可根据需求自动调整大小。
24 11
|
3月前
|
存储 缓存 算法
数据结构和算法学习记录——总结顺序表和链表(双向带头循环链表)的优缺点、CPU高速缓存命中率
数据结构和算法学习记录——总结顺序表和链表(双向带头循环链表)的优缺点、CPU高速缓存命中率
38 0
|
11天前
|
存储 C语言 C++
数据结构基础详解(C语言) 顺序表:顺序表静态分配和动态分配增删改查基本操作的基本介绍及c语言代码实现
本文介绍了顺序表的定义及其在C/C++中的实现方法。顺序表通过连续存储空间实现线性表,使逻辑上相邻的元素在物理位置上也相邻。文章详细描述了静态分配与动态分配两种方式下的顺序表定义、初始化、插入、删除、查找等基本操作,并提供了具体代码示例。静态分配方式下顺序表的长度固定,而动态分配则可根据需求调整大小。此外,还总结了顺序表的优点,如随机访问效率高、存储密度大,以及缺点,如扩展不便和插入删除操作成本高等特点。
|
11天前
|
存储 算法 C语言
C语言手撕数据结构代码_顺序表_静态存储_动态存储
本文介绍了基于静态和动态存储的顺序表操作实现,涵盖创建、删除、插入、合并、求交集与差集、逆置及循环移动等常见操作。通过详细的C语言代码示例,展示了如何高效地处理顺序表数据结构的各种问题。
|
1月前
|
存储 算法
【数据结构与算法】顺序表
【数据结构与算法】顺序表
13 0
【数据结构与算法】顺序表
|
1月前
|
存储 算法
【初阶数据结构篇】顺序表和链表算法题
此题可以先找到中间节点,然后把后半部分逆置,最近前后两部分一一比对,如果节点的值全部相同,则即为回文。
|
1月前
|
存储 测试技术
【初阶数据结构篇】顺序表的实现(赋源码)
线性表(linearlist)是n个具有相同特性的数据元素的有限序列。
|
1月前
|
存储 编译器
【数据结构】顺序表(长期维护)
【数据结构】顺序表(长期维护)