【数据结构入门】-线性表之顺序表(1)

简介: 【数据结构入门】-线性表之顺序表(1)

1.线性表

线性表(linear list)是n个具有相同特性的数据元素的有限序列。线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串…

线性表在逻辑上是线性结构,也就是说连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储。


线性表最经典的两种形式:一种就是数组,另一种就是链表。

1.png

2.png



2.顺序表的实现

顺表作为最简单的数据结构,作用就是把数据存储起来。比如所我们玩的QQ中的联系人、或者通讯录等等。


概念及结构

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

顺序表一般可以分为:


1.静态顺序表:使用定长数组存储。(即长度是固定的)

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


完整代码

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 SeqListInit(SL* ps);
void SeqListPrint(SL* ps);
void CheckCapacity(SL* ps);
void SeqListPushBack(SL* ps, SLDataType x);
void SeqListPopBack(SL* ps);
void SeqListPushFront(SL* ps, SLDataType x);
void SeqListPopFront(SL* ps);
void SeqListInsert(SL* ps, int pos, SLDataType x);
void SeqListErase(SL* ps, int pos);
void SeqListDestroy(SL* ps);

SeqList.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"Seqlist.h"
void SeqListInit(SL* ps)
{
  assert(ps);
  ps->a = NULL;
  ps->size = 0;
  ps->capacity = 0;
}
void SeqListPrint(SL* ps)
{
  for (int i = 0; i < ps->size; i++)
  {
    printf("%d ", ps->a[i]);
  }
}
void CheckCapacity(SL* ps)
{
  if(ps->size==ps->capacity)
  {
    if (ps->capacity == 0)
    {
      ps->a = (SLDataType*)malloc(sizeof(SLDataType) * 4);
      ps->capacity = 4;
    }
    else
    {
      SLDataType* tmp = (SLDataType*)realloc(ps->a, sizeof(SLDataType) * ps->capacity * 2);
      if (tmp == NULL)
      {
        printf("realloc fail\n");
        exit(-1);
      }
      ps->a = tmp;
      ps->capacity *= 2;
    }   
  }
}
void SeqListPushBack(SL* ps, SLDataType x)
{
  assert(ps);
  CheckCapacity(ps);
  ps->a[ps->size] = x;
  ps->size++;
}
void SeqListPopBack(SL* ps)
{
  assert(ps);
  assert(ps->size > 0);
  ps->size--;
}
void SeqListPushFront(SL* ps, SLDataType x)
{
  assert(ps);
  CheckCapacity(ps);
  for (int i = ps->size; i >= 1; i--)
  {
    ps->a[i] = ps->a[i - 1];
  }
  ps->a[0] = x;
  ps->size++;
}
void SeqListPopFront(SL* ps)
{
  assert(ps);
  assert(ps->size > 0);
  for (int i = 0; i < ps->size - 1; i--)
  {
    ps->a[i] = ps->a[i + 1];
  }
  ps->size--;
}
void SeqListInsert(SL* ps, int pos, SLDataType x)
{
  assert(ps);
  CheckCapacity(ps);
  assert(pos >= 1 && pos <= ps->size);
  for (int i = ps->size; i >= pos; i--)
  {
    ps->a[i] = ps->a[i - 1];
  }
  ps->a[pos - 1] = x;
  ps->size++;
}
void SeqListErase(SL* ps, int pos)
{
  assert(ps);
  assert(pos >= 1 && pos <= ps->size);
  for (int i = pos - 1; i <= ps->size - 1 - 1; i++)
  {
    ps->a[i] = ps->a[i + 1];
  }
  ps->size--;
}
void SeqListDestroy(SL* ps)
{
  assert(ps);
  free(ps->a);
  ps->a = NULL;
  ps->capacity = ps->size = 0;
}

test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"Seqlist.h"
//测试尾插尾删
void SeqListTest1()
{
  SL sl;
  SeqListInit(&sl);
  SeqListPushBack(&sl, 2);
  SeqListPushBack(&sl, 1);
  SeqListPushBack(&sl, 6);
  SeqListPushBack(&sl, 59);
  SeqListPushBack(&sl, 1);
  SeqListPushBack(&sl, 6);
  SeqListPrint(&sl);
  printf("\n");
  SeqListPopBack(&sl);
  SeqListPopBack(&sl);
  SeqListPopBack(&sl);
  SeqListPopBack(&sl);
  SeqListPopBack(&sl);
  SeqListPrint(&sl);
  SeqListDestroy(&sl);
}
//测试头插头删
void SeqListTest2()
{
  SL sl;
  SeqListInit(&sl);
  SeqListPushFront(&sl, 1);
  SeqListPushFront(&sl, 2);
  SeqListPushFront(&sl, 3);
  SeqListPushFront(&sl, 4);
  SeqListPushFront(&sl, 5);
  SeqListPrint(&sl);
  printf("\n");
  SeqListPopFront(&sl);
  SeqListPopFront(&sl);
  SeqListPrint(&sl);
  printf("\n");
  SeqListDestroy(&sl);
}
//测试任意位置插入
void SeqListTest3()
{
  SL sl;
  SeqListInit(&sl);
  SeqListPushFront(&sl, 1);
  SeqListPushFront(&sl, 2);
  SeqListPushFront(&sl, 3);
  SeqListPushFront(&sl, 4);
  SeqListPushFront(&sl, 5);
  SeqListPrint(&sl);
  printf("\n");
  SeqListInsert(&sl, 1, 4);
  SeqListPrint(&sl);
  printf("\n");
  SeqListInsert(&sl, 2, 100);
  SeqListPrint(&sl);
  printf("\n");
  SeqListDestroy(&sl);
}
//测试任意位置删除
void SeqListTest4()
{
  SL sl;
  SeqListInit(&sl);
  SeqListPushFront(&sl, 1);
  SeqListPushFront(&sl, 2);
  SeqListPushFront(&sl, 3);
  SeqListPushFront(&sl, 4);
  SeqListPushFront(&sl, 5);
  SeqListPrint(&sl);
  printf("\n");
  SeqListErase(&sl, 1);
  SeqListPrint(&sl);
  printf("\n");
  SeqListErase(&sl, 4);
  SeqListPrint(&sl);
  printf("\n");
}
int main()
{
  //SeqListTest1();
  //SeqListTest2();
  //SeqListTest3();
  //SeqListTest4();
  return 0;
}

3.png


3.总结

说一下学这的建议吧,这块的内容还是比C语言那块稍微上一个档次的,首先要有比较好的C语言基础,才能在学习数据结构的过程中如鱼得水。多敲代码也是一个很重要的一点。勤思考,多理一下这里面的思路以及常见的一些思考方式。再次强调一下,学习的时候一定要思考,而不是在哪里刷时长感动自己。切记,思考思考再思考!!!

好了,就到这把。

再见啦!!!

目录
相关文章
|
1月前
|
存储 编译器 C语言
数据结构-顺序表详解(看这篇就足够了,哈哈哈)
数据结构-顺序表详解(看这篇就足够了,哈哈哈)
49 2
|
18天前
|
存储 算法 安全
2024重生之回溯数据结构与算法系列学习之顺序表【无论是王道考研人还真爱粉都能包会的;不然别给我家鸽鸽丢脸好嘛?】
顺序表的定义和基本操作之插入;删除;按值查找;按位查找等具体详解步骤以及举例说明
|
18天前
|
存储 C语言
【数据结构】顺序表(c语言实现)(附源码)
本文介绍了线性表和顺序表的基本概念及其实现。线性表是一种有限序列,常见的线性表有顺序表、链表、栈、队列等。顺序表是一种基于连续内存地址存储数据的数据结构,其底层逻辑是数组。文章详细讲解了静态顺序表和动态顺序表的区别,并重点介绍了动态顺序表的实现,包括初始化、销毁、打印、增删查改等操作。最后,文章总结了顺序表的时间复杂度和局限性,并预告了后续关于链表的内容。
50 3
|
18天前
|
算法 安全 NoSQL
2024重生之回溯数据结构与算法系列学习之顺序表习题精讲【无论是王道考研人还真爱粉都能包会的;不然别给我家鸽鸽丢脸好嘛?】
顺序表的定义和基本操作之插入;删除;按值查找;按位查找习题精讲等具体详解步骤以及举例说明
|
1月前
|
存储 Java
数据结构第二篇【关于java线性表(顺序表)的基本操作】
数据结构第二篇【关于java线性表(顺序表)的基本操作】
30 6
|
18天前
|
算法 安全 搜索推荐
2024重生之回溯数据结构与算法系列学习之王道第2.3章节之线性表精题汇总二(5)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
IKU达人之数据结构与算法系列学习×单双链表精题详解、数据结构、C++、排序算法、java 、动态规划 你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!
|
1月前
|
存储
数据结构(顺序表)
数据结构(顺序表)
23 0
|
1月前
|
存储 算法
【数据结构】新篇章 -- 顺序表
【数据结构】新篇章 -- 顺序表
15 0
|
1月前
|
存储 测试技术
探索数据结构:顺序表的实现与应用
探索数据结构:顺序表的实现与应用
|
1月前
|
存储 机器学习/深度学习 算法
探索数据结构:入门及复杂度的解锁
探索数据结构:入门及复杂度的解锁