【数据结构】顺序表

简介: 【数据结构】顺序表

只有毅力才会使我们成功,而毅力的来源又在于毫不动摇,坚决采取为达到成功所需要的手段。                                                                                                       ——车尔尼雪夫斯基

18f1d19c5bfd74345ed49b9fe151eb85_e63838ad4434432d8fb594ab04060122.jpeg

目录


前言:


参数部分:


函数功能:


初始化Seqlist:


销毁Seqlist:


打印Seqlist:


扩容Seqlist:


尾插:


尾删:


头插:


头删:


在任意位置上插入:


删除任意位置:


查找任意位置:


完整代码:


Seqlist.h:


Seqlist.c:


Text.c:



前言:

顺序表:

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

顺序表一般可以分为:

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

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

注:本章讲解动态顺序表

参数部分:

首先是连续存放的数据,我们会想到数组,但是我们的个数不能改变,所以我们需要一个指针a指向malloc开辟一段连续的空间。

然后当我们需要改变这个空间的大小,我们还需要一个变量来表示已有空间容量的大小capacity。

我们如何判断什么时候需要扩容呢?需要一个计算多少个有效数据的个数变量size来判断等于已有空间的大小来决定是否扩容。  

定义结构体 :

typedef int SLDataType;
typedef struct SeqList
{
  SLDataType* a;   //动态数组
  int size;       // 记录存储多少个有效数据
  int capacity;   // 空间容量大小 
}SL;

在这里我分为了三个部分来实现:

  • SeqList.h文件中进行函数声明。
  • SeqList.c函数进行各个函数的实现。
  • Test.c函数进行函数的测试。

函数功能:

初始化Seqlist:

//初始化
void SLInit(SL* ps)
{
  assert(ps);
  ps->a = NULL;
  ps->capacity = ps->size = 0;
}

销毁Seqlist:

//销毁
void SLDestory(SL* ps)
{
  assert(ps);
  if (ps->a)
  {
    free(ps->a);
    ps->a = NULL;
    ps->capacity = ps->size = 0;
  }
}

打印Seqlist:

//打印
void SLPrint(SL* ps)
{
  assert(ps);
  for (int i = 0; i < ps->size; ++i)
  {
    printf("%d ", ps->a[i]);
  }
  printf("\n");
}

扩容Seqlist:

SLCheckCapacity(SL* ps)
{
  //扩容
  assert(ps);
  if (ps->size == ps->capacity)
  {
    int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
    SLDataType* tmp = (SLDataType*)realloc(ps->a, newCapacity * sizeof(SLDataType));
    if (tmp == NULL)
    {
      perror("realloc fail :");
      exit(-1);
    }
    ps->a = tmp;
    ps->capacity = newCapacity;
  }
}

尾插:

//尾插
void SLPushBack(SL* ps,SLDataType x)
{
//扩容
  SLCheckCapacity(ps);
  ps->a[ps->size] = x;
  ps->size++;
  //SLInsert(ps, ps->size,x);
}


尾删:

//尾删
void SLPopBack(SL* ps)
{
  assert(ps);
  assert(ps->size > 0);
  ps->size--;
  //SLErase(ps, ps->size - 1);
}

头插:

//头插
void SLPushFront(SL* ps, SLDataType x)
{
  SLCheckCapacity(ps);
  //挪动数据
  int end = ps->size - 1;
  while (end>=0)
  {
    ps->a[end + 1] = ps->a[end];
    end--;
  }
  ps->a[0] = x;
  ps->size++;
  //SLInsert(ps, 0, x);
}

头删:

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

在任意位置上插入:

//从中间位置插入
void SLInsert(SL* ps, int pos, SLDataType x)
{
  assert(ps);
  assert(pos >= 0);
  assert(pos <= ps->size);
  SLCheckCapacity(ps);
  int end = ps->size - 1;
  while (pos <= end)
  {
    ps->a[end + 1] = ps->a[end];
    end--;
  }
  ps->a[pos] = x;
  ps->size++;
}

删除任意位置:

// 删除pos位置数据
void SLErase(SL* ps, int pos)
{
  assert(ps);
  assert(pos >= 0);
  assert(pos < ps->size);
  int begin = pos;
  int end = ps->size - 1;
  while (begin <= end)
  {
    ps->a[begin - 1] = ps->a[begin];
    begin++;
  }
  ps->size--;
}

查找任意位置:

// begin查找x的起始位置
int SLFind(SL* ps, SLDataType x, int begin)
{
  assert(ps);
  for (int i=0 ; i < ps->size; i++)
  {
    if (x == ps->a[i])
    {
      printf("%d\n", i);
      return i;
    }
  }
  return -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;   // 空间容量大小 
}SL;
//初始化
void SLInit(SL* ps);
//尾插尾删
void SLPushBack(SL* ps,SLDataType x);
void SLPopBack(SL* ps);
//销毁
void SLDestory(SL* ps);
//初始化
void SLPrint(SL* ps);
//头插头删
void SLPushFront(SL* ps, SLDataType x);
void SLPopFront(SL* ps);
// 中间插入删除
// 在pos位置插入数据
void SLInsert(SL* ps, int pos, SLDataType x);
// 删除pos位置数据
void SLErase(SL* ps, int pos);
//int SLFind(SL* ps, SLDataType x);
// begin查找x的起始位置
int SLFind(SL* ps, SLDataType x, int begin);

Seqlist.c:

#define _CRT_SECURE_NO_WARNINGS 1
#include"Seqlist.h"
SLCheckCapacity(SL* ps)
{
  //扩容
  assert(ps);
  if (ps->size == ps->capacity)
  {
    int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
    SLDataType* tmp = (SLDataType*)realloc(ps->a, newCapacity * sizeof(SLDataType));
    if (tmp == NULL)
    {
      perror("realloc fail :");
      exit(-1);
    }
    ps->a = tmp;
    ps->capacity = newCapacity;
  }
}
//尾插
void SLPushBack(SL* ps,SLDataType x)
{/*
  SLCheckCapacity(ps);
  ps->a[ps->size] = x;
  ps->size++;*/
  SLInsert(ps, ps->size,x);
}
//打印
void SLPrint(SL* ps)
{
  assert(ps);
  for (int i = 0; i < ps->size; ++i)
  {
    printf("%d ", ps->a[i]);
  }
  printf("\n");
}
//初始化
void SLInit(SL* ps)
{
  assert(ps);
  ps->a = NULL;
  ps->capacity = ps->size = 0;
}
//销毁
void SLDestory(SL* ps)
{
  assert(ps);
  if (ps->a)
  {
    free(ps->a);
    ps->a = NULL;
    ps->capacity = ps->size = 0;
  }
}
//尾删
void SLPopBack(SL* ps)
{
  /*assert(ps);
  assert(ps->size > 0);
  ps->size--;*/
  SLErase(ps, ps->size - 1);
}
//头插
void SLPushFront(SL* ps, SLDataType x)
{
  //SLCheckCapacity(ps);
  挪动数据
  //int end = ps->size - 1;
  //while (end>=0)
  //{
  //  ps->a[end + 1] = ps->a[end];
  //  end--;
  //}
  //ps->a[0] = x;
  //ps->size++;
  SLInsert(ps, 0, x);
}
void SLPopFront(SL* ps)
{
  //assert(ps);
  //assert(ps->size > 0);
  //int begin = 1;
  //while (begin<ps->size)
  //{
  //  ps->a[begin - 1] = ps->a[begin];
  //  begin++;
  //}
  //ps->size--;
  SLErase(ps, 0);
}
//从中间位置插入
void SLInsert(SL* ps, int pos, SLDataType x)
{
  assert(ps);
  assert(pos >= 0);
  assert(pos <= ps->size);
  SLCheckCapacity(ps);
  int end = ps->size - 1;
  while (pos <= end)
  {
    ps->a[end + 1] = ps->a[end];
    end--;
  }
  ps->a[pos] = x;
  ps->size++;
}
// 删除pos位置数据
void SLErase(SL* ps, int pos)
{
  assert(ps);
  assert(pos >= 0);
  assert(pos < ps->size);
  int begin = pos;
  int end = ps->size - 1;
  while (begin <= end)
  {
    ps->a[begin - 1] = ps->a[begin];
    begin++;
  }
  ps->size--;
}
// begin查找x的起始位置
int SLFind(SL* ps, SLDataType x, int begin)
{
  assert(ps);
  for (int i=0 ; i < ps->size; i++)
  {
    if (x == ps->a[i])
    {
      printf("%d\n", i);
      return i;
    }
  }
  return -1;
}

Text.c:

#define _CRT_SECURE_NO_WARNINGS 1
#include"Seqlist.h"
TextSeqList1()
{
  SL sl;
  SLInit(&sl);
  SLPushBack(&sl, 1);
  SLPushBack(&sl, 2);
  SLPushBack(&sl, 3);
  SLPushBack(&sl, 4);
  SLPrint(&sl);
  SLDestory(&sl);
}
TextSeqList2()
{
  SL sl;
  SLInit(&sl);
  SLPushFront(&sl, 1);
  SLPushFront(&sl, 2);
  SLPushFront(&sl, 3);
  SLPushFront(&sl, 4);
  SLPushFront(&sl, 5);
  SLPushFront(&sl, 6);
  SLPushFront(&sl, 7);
  SLPrint(&sl);
  SLPopFront(&sl);
  SLPopFront(&sl);
  SLPopFront(&sl);
  SLPopFront(&sl);
  SLPrint(&sl);
  SLDestory(&sl);
}
TextSeqList3()
{
  SL sl;
  SLInit(&sl);
  SLPushFront(&sl, 1);
  SLPushFront(&sl, 2);
  SLPushFront(&sl, 3);
  SLPushFront(&sl, 4);
  SLPushFront(&sl, 5);
  SLPrint(&sl);
  SLInsert(&sl, 3, 100);
  SLPrint(&sl);
   SLFind(&sl, 100, 0);
  /*if (pos != -1)
  {
    SLErase(&sl, pos);
  }*/
   SLErase(&sl,2);
   SLPrint(&sl);
  SLDestory(&sl);
}
int main()
{
  TextSeqList3();
  return 0;
}








相关文章
|
2月前
|
存储 编译器 C语言
数据结构-顺序表详解(看这篇就足够了,哈哈哈)
数据结构-顺序表详解(看这篇就足够了,哈哈哈)
55 2
|
1月前
|
存储 算法 安全
2024重生之回溯数据结构与算法系列学习之顺序表【无论是王道考研人还真爱粉都能包会的;不然别给我家鸽鸽丢脸好嘛?】
顺序表的定义和基本操作之插入;删除;按值查找;按位查找等具体详解步骤以及举例说明
|
1月前
|
存储 C语言
【数据结构】顺序表(c语言实现)(附源码)
本文介绍了线性表和顺序表的基本概念及其实现。线性表是一种有限序列,常见的线性表有顺序表、链表、栈、队列等。顺序表是一种基于连续内存地址存储数据的数据结构,其底层逻辑是数组。文章详细讲解了静态顺序表和动态顺序表的区别,并重点介绍了动态顺序表的实现,包括初始化、销毁、打印、增删查改等操作。最后,文章总结了顺序表的时间复杂度和局限性,并预告了后续关于链表的内容。
61 3
|
1月前
|
算法 安全 NoSQL
2024重生之回溯数据结构与算法系列学习之顺序表习题精讲【无论是王道考研人还真爱粉都能包会的;不然别给我家鸽鸽丢脸好嘛?】
顺序表的定义和基本操作之插入;删除;按值查找;按位查找习题精讲等具体详解步骤以及举例说明
|
2月前
|
存储 Java
数据结构第二篇【关于java线性表(顺序表)的基本操作】
数据结构第二篇【关于java线性表(顺序表)的基本操作】
33 6
|
2月前
|
存储 安全 Java
【用Java学习数据结构系列】探索顺序表和链表的无尽秘密(附带练习唔)pro
【用Java学习数据结构系列】探索顺序表和链表的无尽秘密(附带练习唔)pro
25 3
|
2月前
|
存储 C语言
探索C语言数据结构:利用顺序表完成通讯录的实现
本文介绍了如何使用C语言中的顺序表数据结构实现一个简单的通讯录,包括初始化、添加、删除、查找和保存联系人信息的操作,以及自定义结构体用于存储联系人详细信息。
25 2
|
2月前
|
存储 算法 索引
【数据结构】——顺序表
【数据结构】——顺序表
|
2月前
|
存储
【数据结构】线性表和顺序表
【数据结构】线性表和顺序表
22 1
|
2月前
|
存储
数据结构1——顺序表
数据结构1——顺序表
18 1