顺序表的模拟

简介: 顺序表的模拟

前言:

数据结构无论是以后就业还是考研,对于计算机方向的同学来说都是必修的一门课,所以,深入理解各种数据结构是一名合格程序员的基本素养。这里我就先带大家了解最简单的数据结构--顺序表吧。

1.什么是顺序表

顺序表是一种线性数据结构,而且其存储数据的空间是连续的,这一点跟数组非常像。

由于其基本结构式是连续的,我们在查找元素时也就可以用下标映射快速定位到元素的位置,是编写常见算法的常用数据结构之一。

2.顺序表的功能

顺序表的主要操作包括访问、插入、删除和修改等。其中,访问是顺序表最基本的操作之一,可以通过下标(索引)来访问顺序表中的元素,时间复杂度为 O(1)。插入和删除操作都涉及到元素的移动,因此它们的时间复杂度为 O(n)。修改操作和访问类似,时间复杂度也为 O(1)

3.c语言代码模拟实现顺序表

主要思路就是:首先是定义数据类型(我这里是int),然后是定义结构体SeqList(顺序表),这个结构体用一个date指针来指向数据区域(我这里是用malloc动态开辟内存),size表示目前顺序表中的元素,cap表示目前顺序表的容量。

在实现顺序表的增删查改过程中,要注意size的变化,看是否已经达到最大容量,根据实际情况选择扩容(用realloc)。

3.1 SeqList.h头文件

用来声明各种功能函数,定义数据类型等。

代码:

#define _CRT_SECURE_NO_WARNINGS 1
//SeqList.h
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
 
#define INIT_SIZE 4
#define INIT_CAP 10
 
typedef int SLDateType;
 
typedef struct SeqList {
  SLDateType* date;
  int size;
  int cap;
}SeqList;
 
void SeqListInit(SeqList* SL);
//顺序表销毁
void SeqListDestroy(SeqList* SL);
//打印顺序表
void PrintSeqList(SeqList* SL);
//尾插元素
void SeqListPushBack(SeqList* SL, int x);
//头插元素
void SeqListPushFront(SeqList* SL, int x);
//指定位置插入元素
void SeqListInsert(SeqList* SL, int pos, int x);
// 表尾弹出元素
void SeqListPopBack(SeqList* SL);
//表头弹出元素
void SeqListPopFront(SeqList* SL);
//删除指定位置
void SeqListErase(SeqList* SL, int pos);
//查找元素
int SeqListFind(SeqList* SL, int x);

3.2 SeqList.c源文件

实现各种功能函数。

代码:

#define _CRT_SECURE_NO_WARNINGS 1
//SeqList.c
 
 
#include"SeqList.h"
//顺序表初始化
void SeqListInit(SeqList* SL) {
  SL->date = (SLDateType*)malloc(sizeof(SLDateType) * INIT_CAP);
  SL->size = 0;
  SL->cap = INIT_CAP;
}
 
//顺序表销毁
void SeqListDestroy(SeqList* SL) {
  assert(SL);
  free(SL->date);
  SL->size = 0;
  SL->cap = 0;
}
 
//检查顺序表是否已满,如果满了就扩容
static void CheckSLIsMax(SeqList* SL) {
  assert(SL);
  if (SL->size == SL->cap) {
    SeqList* res = SL;
    res = (SeqList*)realloc(SL->date, sizeof(SLDateType) * ((SL->cap) * 2));
    if (res == NULL) {
      perror("realloc:fail");
    }
    SL->date = res;
    (SL->cap) *= 2;
    return;
  }
  return;
}
//打印顺序表
void PrintSeqList(SeqList* SL) {
  assert(SL);
  for (int i = 0; i < SL->size; i++) {
    printf("%d ", SL->date[i]);
  }
  printf("\n");
  printf("该顺序表目前有%d个数据,容量为%d\n", SL->size, SL->cap);
  printf("\n");
  return;
}
 
//尾插元素
void SeqListPushBack(SeqList* SL, int x) {
  assert(SL);
  CheckSLIsMax(SL);
  SL->date[SL->size] = x;
  SL->size++;
}
//头插元素
void SeqListPushFront(SeqList* SL,int x) {
  assert(SL);
  CheckSLIsMax(SL);
  for (int i = SL->size; i >=1; i--) {
    SL->date[i] = SL->date[i - 1];
  }
  SL->date[0] = x;
  SL->size++;
  return;
}
//插入元素到指定位置
void SeqListInsert(SeqList* SL, int pos, int x) {
  assert(SL);
  if (pos >= 0 && pos < SL->size) {
    CheckSLIsMax(SL);
    for (int i = SL->size; i >= pos+1; i--) {
      SL->date[i] = SL->date[i - 1];
    }
    SL->date[pos] = x;
    SL->size++;
  }
  else {
    perror("插入位置有误");
  }
}
// 表尾弹出元素
void SeqListPopBack(SeqList* SL) {
  assert(SL);
  if (SL->size > 0) {
    //SL->date[SL->size - 1];
    SL->size--;
  }
  else {
    perror("SeqListPopBack: failen");
  }
  return;
}
//表头弹出元素
void SeqListPopFront(SeqList* SL) {
  assert(SL);
  if (SL->size > 0) {
    for (int i = 0; i < SL->size-1; i++) {
      SL->date[i] = SL->date[i + 1];
    }
    SL->size--;
  }
  else {
    perror("SeqListPopFront: faile");
  }
  return;
}
//删除指定位置
void SeqListErase(SeqList* SL, int pos) {
  assert(SL);
  if (pos >= 0 && pos < SL->size) {
         for (int i = pos; i < SL->size-1; i++) {
        SL->date[i] = SL->date[i + 1];
      }
    SL->size--;
  }
  else {
    perror("SeqListErase:fail");
  }
}
//查找元素
int SeqListFind(SeqList* SL, int x) {
  assert(SL);
  for (int i = 0; i < SL->size; i++) {
    if (SL->date[i] == x) {
      return i;
    }
  }
  return -1;
}
 
 

3.3test.c

用来存放main()函数,测试各种数据,我这里就简单给出一组测试数据(懒)

代码:

SeqList SL;
void test1() {
  SeqListInit(&SL);
  SeqListPushBack(&SL, 1);
  SeqListPushBack(&SL, 2);
  SeqListPushBack(&SL, 3);
  SeqListPushBack(&SL, 4);
  SeqListPushBack(&SL, 5);
  SeqListPushBack(&SL, 6);
  PrintSeqList(&SL);
  SeqListPushFront(&SL, 4);
  PrintSeqList(&SL);
 
}
 
int main() {
  test1();
  return 0;
}

4.总结

学数据结构一般都是从顺序表开始的,顺序表虽然简单,但是是我们经常使用的一种数据结构,了解并学会顺序表功能的具体实现对以后学习高级数据结构打下基础。总之,对于简单的知识我们要不能轻视,反而要更加重视对于基础的巩固,万丈高楼平地起嘛!


相关文章
|
存储 机器学习/深度学习 算法
模拟实现单链表、双链表、栈、队列——数组模拟
我们在数据结构中都学到过单链表、双链表、栈和队列,当我们实现的时候时使用结构体指针实现的。定义一个结构体,结构体中存储指针变量和存放数值的变量。当然,C++的STL库中已经有实现好的栈和队列,我们可以直接用。但是在做算法题时,有时候我们会发现超出时间限制。原因是我们用STL库中的栈和队列容器时,效率相对来说较慢。我们这时就引出用数组模拟实现栈和队列。用数组模拟实现的使用起来效率更高、更方便。当然,我们也会讲到用数组模拟实现单链表和双链表。
69 0
|
算法 C语言
实现顺序表的各种基本算法
C语言顺序表实现
131 0
|
6月前
|
存储 算法
数据结构和算法学习记录——线性表之单链表(上)-初始单链表及其尾插函数(顺序表缺陷、单链表优点、链表打印)
数据结构和算法学习记录——线性表之单链表(上)-初始单链表及其尾插函数(顺序表缺陷、单链表优点、链表打印)
41 0
|
存储
模拟实现顺序表
模拟实现顺序表
43 0
|
7月前
|
存储 测试技术
单链表的模拟实现
单链表的模拟实现
52 0
|
存储
【数据结构】模拟实现顺序表
【数据结构】模拟实现顺序表
|
机器学习/深度学习 存储 人工智能
顺序表算法练习
顺序表算法练习
229 0
|
存储 算法 API
算法——顺序表(1)
算法——顺序表(1)
90 0
算法——顺序表(1)