数据结构——顺序表(C语言)

简介: 数据结构——顺序表(C语言)

1.线性表

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

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

2.顺序表

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

在这里,我将给大家讲动态顺序表是怎么实现的。


(1).我先定义了一个结构体,因为顺序表是具有相同特性的数据元素的有限列表。所以我用SeqListDateType来typedef 了,这样我们如果是double 或者float这样的类型的话,我们就只用改变宏这里一处。

(2).因为是动态的,所以我就用指针,size就代表了顺序表中有多少个元素,capacity代表了是有多少的空间。


#define SeqListDateType int
typedef struct SeqList
{
  SeqListDateType* arr;
  int size;
  int capacity;
}SeqList;

顺序表的初始化:

第一个函数就是度顺序表的初始化,这里我是直接把ps->arr置位了NULL,size和capacity一开始是0。

void SeqListInit(SeqList* ps)
{
  ps->arr = NULL;
  ps->size = ps->capacity = 0;
}

顺序表的扩容:

因为我们是实现动态的顺序表,所以我们要处理一下,当size和capacity相等的时候,有2种情况,一种情况:一开始为0的时候,第二种情况:当空间不够的时候

这里,我用三目来实现了,如果是一开始我就给了4个int大小的空间,如果是第二种情况的话我就用扩二倍的思想来处理.

void SeqListCheckCapacity(SeqList* ps)
{
  if (ps->size == ps->capacity)
  {
    int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
    SeqListDateType* tmp = (SeqListDateType*)realloc(ps->arr, newcapacity*sizeof(SeqListDateType)*2);
    if (tmp == NULL)
    {
      perror("realloc fail\n");
      exit(-1);
    }
    ps->capacity = newcapacity;
    ps->arr = tmp;
  }
}

顺序表的尾插:

一开始,我们开辟了4个int大小的空间,所以size一开始是0,然后就插入,然后size++就可以实现了,不过在我们插入的时候我们要考虑扩容的问题,如果空间满了,是要扩容的。


void SeqListPushBack(SeqList* ps, int x)
{
  assert(ps);
  SeqListCheckCapacity(ps);
  ps->arr[ps->size] = x;
  ps->size++;
  //SeqListInsert(ps, ps->size,x);
}

顺序表的头插:


思路:可以用迭代的思路走,但我们想一想,如果是从前面迭代的话,就会形成对数据的覆盖,所以要从后面迭代走。

我定义了end指向了4的位置,然后4要到后面的位置去,然后end--,这样当我们迭代完,顺序表0的位置就空了出来,直接把数据插入进去就可以了。

void SeqListPushFront(SeqList* ps,int x)
{
  assert(ps);
  SeqListCheckCapacity(ps);
  int end = ps->size - 1;
  while (end >=0)
  {
    ps->arr[end + 1] = ps->arr[end];
    end--;
  }
  ps->arr[0] = x;
  ps->size++;
  //SeqListInsert(ps,0,x);
}

顺序表的尾删:

顺序表尾删更简单,直接让size--就可以实现了。因为,我们打印的数据就是size范围内的数据,size减了过后就没有这个数据了。

void SeqListPopBack(SeqList* ps)
{
  assert(ps);
  ps->size--;
  //SeqListErqse(ps, ps->size-1);
}

顺序表的头删:


思路:先定义一个begin来指向第一个位置,我们迭代让后面的数据覆盖掉前面的数据就可以了。最后size--就实现了顺序表的头删。

 

void SeqListPopFront(SeqList* ps)
{
  assert(ps);
  int begin = 0;
  while (begin < ps->size - 1)
  {
    ps->arr[begin] = ps->arr[begin+1];
    ++begin;
  }
  ps->size--;
  //SeqListErqse(ps, 0);
}

顺序表的最后处理:

我们直接free掉动态开辟的空间就可以了,然后把size和capacity置为0.

void SeqListDestory(SeqList* ps)
{
  free(ps->arr);
  ps->arr = NULL;
  ps->size = ps->capacity = 0;
}

我们想一个问题,如果是在面试中,给了我们10分钟来实现顺序表,如果这样处理时间是不是可能不够呢??所以,我给大家带来另外2个函数,这样我们就可以复用这2个函数对顺序表的头插、尾插..就可以直接复用,大大节约了时间。话不多说,直接放码!!!

顺序表的指定位置插入:


思路:假设pos=2,我定义了end来指向最后一个元素,只需要将最后一个元素往后移动一位,然后end--,这样就迭代了起来,最终就可以把pos的位置空出来,然后在pos位置插入想要的元素。

void SeqListInsert(SeqList* ps, int pos, int x)
{
  assert(pos <= ps->size && pos>=0);
  SeqListCheckCapacity(ps);
  int end = ps->size - 1;
  while (end >= pos)
  {
    ps->arr[end+1] = ps->arr[end];
    end--;
  }
  ps->arr[pos] = x;
  ps->size++;
}

顺序表的指定位置删除:

思路:删除的话,其实也是一个覆盖的过程,将pos+1的位置覆盖掉pos的位置,然后迭代,临界位置就是size-1的时候,最后size--就实现了对指定位置的删除。

void SeqListErase(SeqList* ps, int pos)
{
  assert(pos >=0 && pos <= ps->size-1);
  int begin = pos+1;
  while (begin <= ps->size-1)
  {
    ps->arr[begin-1] = ps->arr[begin];
    begin++;
  }
  ps->size--;
}

这样,就可以用这两个元素来复用了!

尾插:尾插其实就是对顺序表最后的位置插入元素(注意,在最后一个位置插入的时候size已经++了,所以是ps->size)

SeqListInsert(ps, ps->size,x);

头插:头插就是对0的位置插入元素

SeqListInsert(ps,0,x);

尾删:尾删也是和尾插一样的,对最后的位置删除

SeqListErase(ps, ps->size-1);

头删:头删是对0的位置开始删除

SeqListErase(ps, 0);


相关文章
|
14天前
|
C语言
【数据结构】栈和队列(c语言实现)(附源码)
本文介绍了栈和队列两种数据结构。栈是一种只能在一端进行插入和删除操作的线性表,遵循“先进后出”原则;队列则在一端插入、另一端删除,遵循“先进先出”原则。文章详细讲解了栈和队列的结构定义、方法声明及实现,并提供了完整的代码示例。栈和队列在实际应用中非常广泛,如二叉树的层序遍历和快速排序的非递归实现等。
90 9
|
28天前
|
存储 算法 C语言
通义灵码在考研C语言和数据结构中的应用实践 1-5
通义灵码在考研C语言和数据结构中的应用实践,体验通义灵码的强大思路。《趣学C语言和数据结构100例》精选了五个经典问题及其解决方案,包括求最大公约数和最小公倍数、统计字符类型、求特殊数列和、计算阶乘和双阶乘、以及求斐波那契数列的前20项和。通过这些实例,帮助读者掌握C语言的基本语法和常用算法,提升编程能力。
|
13天前
|
存储 搜索推荐 算法
【数据结构】树型结构详解 + 堆的实现(c语言)(附源码)
本文介绍了树和二叉树的基本概念及结构,重点讲解了堆这一重要的数据结构。堆是一种特殊的完全二叉树,常用于实现优先队列和高效的排序算法(如堆排序)。文章详细描述了堆的性质、存储方式及其实现方法,包括插入、删除和取堆顶数据等操作的具体实现。通过这些内容,读者可以全面了解堆的原理和应用。
56 16
|
13天前
|
C语言
【数据结构】二叉树(c语言)(附源码)
本文介绍了如何使用链式结构实现二叉树的基本功能,包括前序、中序、后序和层序遍历,统计节点个数和树的高度,查找节点,判断是否为完全二叉树,以及销毁二叉树。通过手动创建一棵二叉树,详细讲解了每个功能的实现方法和代码示例,帮助读者深入理解递归和数据结构的应用。
62 8
|
15天前
|
存储 C语言
【数据结构】手把手教你单链表(c语言)(附源码)
本文介绍了单链表的基本概念、结构定义及其实现方法。单链表是一种内存地址不连续但逻辑顺序连续的数据结构,每个节点包含数据域和指针域。文章详细讲解了单链表的常见操作,如头插、尾插、头删、尾删、查找、指定位置插入和删除等,并提供了完整的C语言代码示例。通过学习单链表,可以更好地理解数据结构的底层逻辑,提高编程能力。
43 4
|
17天前
|
存储 算法 安全
2024重生之回溯数据结构与算法系列学习之顺序表【无论是王道考研人还真爱粉都能包会的;不然别给我家鸽鸽丢脸好嘛?】
顺序表的定义和基本操作之插入;删除;按值查找;按位查找等具体详解步骤以及举例说明
|
17天前
|
存储 C语言
【数据结构】顺序表(c语言实现)(附源码)
本文介绍了线性表和顺序表的基本概念及其实现。线性表是一种有限序列,常见的线性表有顺序表、链表、栈、队列等。顺序表是一种基于连续内存地址存储数据的数据结构,其底层逻辑是数组。文章详细讲解了静态顺序表和动态顺序表的区别,并重点介绍了动态顺序表的实现,包括初始化、销毁、打印、增删查改等操作。最后,文章总结了顺序表的时间复杂度和局限性,并预告了后续关于链表的内容。
46 3
|
17天前
|
存储 算法 C语言
C语言数据结构(2)
【10月更文挑战第21天】
|
17天前
|
算法 安全 NoSQL
2024重生之回溯数据结构与算法系列学习之顺序表习题精讲【无论是王道考研人还真爱粉都能包会的;不然别给我家鸽鸽丢脸好嘛?】
顺序表的定义和基本操作之插入;删除;按值查找;按位查找习题精讲等具体详解步骤以及举例说明
|
28天前
|
存储 算法 C语言
【趣学C语言和数据结构100例】
《趣学C语言和数据结构100例》精选5个编程问题,涵盖求最大公约数与最小公倍数、字符统计、特殊序列求和及阶乘计算等,通过实例讲解C语言基础与算法思维,适合初学者实践学习。