C语言深入浅出讲解顺序表的实现

目录
  • 1.线性表
  • 2.顺序表
    • 2.1 概念及结构
    • 2.2 提供接口
    • 2.3 接口实现

今天起开始编写数据结构中的各种数据结构及算法的实现,说到顺序表,我们首先得了解下线性表。

1.线性表

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

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

2.顺序表

2.1 概念及结构

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

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

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

//顺序表的静态存储
#define N 100
struct SeqList
{
	int a[N];//定长存储
	int size;//有效数据的个数
};
//顺序表的动态存储
typedef struct SeqList
{
	SeqDataType* a;//指向动态开辟的数组
	int size;	  //有效数据个数
	int capacity; //容量
}SeqList;

顺序表本质上是数组,在数组上增加了两个要求:

1.插入数据的过程中,可以动态增长

2.并且要求里面存储的数据必须是从左往右,是连续的

顺序表的缺陷

1.动态增容有性能消耗

2.头部插入数据时,需要挪动数据

2.2 提供接口

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

首先在头文件<SeqList.h>中提供接口:

typedef int SeqDataType; //需要插入什么类型的数据,就改成对应类型

typedef struct SeqList
{
	SeqDataType* a;//指向动态开辟的数组
	int size;	  //有效数据个数
	int capacity; //容量
}SeqList;

//内存中管理数据结构 提供增删查改的接口
//顺序表初始化
void SeqListInit(SeqList* pq);
//顺序表销毁
void SeqListDestory(SeqList* pq);
//顺序表打印
void SeqListPrint(SeqList* pq);//打印数组
//检查空间,如果满了,进行增容
void SeqCheckCapacity(SeqList* pq)
//顺序表尾插
void SeqListPushBack(SeqList* pq, SeqDataType x);
//顺序表头插
void SeqListPushFront(SeqList* pq, SeqDataType x);
//顺序表尾删
void SeqListPopBack(SeqList* pq);
//顺序表头删
void SeqListPopFront(SeqList* pq);
//顺序表查找x
int SeqListFind(SeqList* pq, SeqDataType x);//查找 查到返回下标,没查到返回-1
//顺序表在指定位置插入数据
void SeqListInsert(SeqList* pq, int pos, SeqDataType x);//在下标pos位置处插入数据
//顺序表在指定位置删除数据
void SeqListErase(SeqList* pq, int pos);//把下标为pos位置处的数据删除
//顺序表在指定位置替换数据
void SeqListModify(SeqList* pq, int pos, SeqDataType x);//把小标为pos位置的值改为x

2.3 接口实现

在源文件SeqList.c中实现接口功能

(1)顺序表初始化

void SeqListInit(SeqList* pq)
{
	assert(pq != NULL);//或者 assert(pq); 断言 防止传入空指针
	pq->a = NULL;
	pq->size = 0;
	pq->capacity = 0;
}

(2)顺序表销毁

void SeqListDestory(SeqList* pq)
{
	assert(pq);
	free(pq->a);
	pq->a = NULL;
	pq->size = 0;
	pq->capacity = 0;
}

(3)顺序表打印

void SeqListPrint(SeqList* pq)
{
	assert(pq);
	for (int i = 0; i < pq->size; ++i)
	{
		printf("%d ", pq->a[i]);
	}
	printf("\n");
}

(4)检查空间,如果满了,进行增容

//检查是否需要扩容
void SeqCheckCapacity(SeqList* pq)
{
	//满了,需要增容
	if (pq->size == pq->capacity)
	{
		int newcapacity = (pq->capacity == 0 ? 4 : pq->capacity * 2);

		//realloc接收的地址如果为空,将像malloc一样,开辟一块新空间
		SeqDataType* newA = realloc(pq->a, sizeof(SeqDataType) * newcapacity);//realloc返回 开辟的新空间的地址
		if (newA == NULL)
		{
			printf("realloc fail\n");
			exit(-1);//失败了就退出
		}
		pq->a = newA;
		pq->capacity = newcapacity;
	}
}

(5)顺序表尾插

void SeqListPushBack(SeqList* pq, SeqDataType x)//尾插
{
	assert(pq);

	SeqCheckCapacity(pq);

	pq->a[pq->size] = x;
	pq->size++;
}

(6)顺序表头插

void SeqListPushFront(SeqList* pq, SeqDataType x)
{
	assert(pq);

	SeqCheckCapacity(pq);

	int end = pq->size - 1;
	while (end >= 0)
	{
		pq->a[end + 1] = pq->a[end];
		end--;
	}
	pq->a[0] = x;
	pq->size++;
}

(7)顺序表尾删

void SeqListPopBack(SeqList* pq)
{
	assert(pq);
	assert(pq->size > 0);
	pq->size--;
}

(8)顺序表头删

void SeqListPopFront(SeqList* pq)
{
	assert(pq);
	assert(pq->size > 0);

	int begin = 0;
	while (begin < pq->size - 1)
	{
		pq->a[begin] = pq->a[begin + 1];
		begin++;
	}
	pq->size--;
}

(9)顺序表查找x

int SeqListFind(SeqList* pq, SeqDataType x)
{
	assert(pq);
	for (int i = 0; i < pq->size; ++i)
	{
		if (pq->a[i] == x)
		{
			return x;
		}
	}
	return -1;//没找到
}

(10)顺序表在指定位置插入数据

void SeqListInsert(SeqList* pq, int pos, SeqDataType x){<!--{C}%3C!%2D%2D%20%2D%2D%3E-->assert(pq);assert(pos >= 0 && pos < pq->size);SeqCheckCapacity(pq);//检查是否需要扩容int end = pq->size - 1;while (end >= pos){<!--{C}%3C!%2D%2D%20%2D%2D%3E-->pq->a[end + 1] = pq->a[end];end--;}pq->a[pos] = x;pq->size++;}void SeqListInsert(SeqList* pq, int pos, SeqDataType x)
{
	assert(pq);
	assert(pos >= 0 && pos < pq->size);

	SeqCheckCapacity(pq);//检查是否需要扩容

	int end = pq->size - 1;
	while (end >= pos)
	{
		pq->a[end + 1] = pq->a[end];
		end--;
	}
	pq->a[pos] = x;
	pq->size++;
}

(11)顺序表在指定位置删除数据

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

(12)顺序表在指定位置替换数据

void SeqListModify(SeqList* pq, int pos, SeqDataType x)
{
	assert(pq);
	assert(pos >= 0 && pos < pq->size);

	pq->a[pos] = x;
}

主函数的设计大家可以自由发挥,做个简单的测试功能调用函数或是创建菜单栏实现交互都可以。我水平有限,请朋友们谅解!写的不好的地方还请大佬们指出。

下期预告——单链表

到此这篇关于C语言深入浅出讲解顺序表的实现的文章就介绍到这了,更多相关C语言 顺序表内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • C语言数据结构深入探索顺序表

    目录 1.线性表 2.顺序表 2.1概念及结构 2.2 接口实现 2.2.1初始化 2.2.2 检查容量 2.2.3 顺序表打印 2.2.4 顺序表尾插 2.2.5 顺序表尾删 2.2.6 顺序表头插 2.2.7 顺序表头删 2.2.8 顺序表在pos位置插入x 2.2.9 顺序表删除pos位置的值 2.2.10 尾插.尾删.头插.头删的改进 2.2.11 顺序表查找 2.2.12 顺序表销毁 2.3 数组相关面试题 2.4 顺序表的问题及思考 1.线性表 线性表(linear list)是n个

  • C语言经典顺序表真题演练讲解

    目录 1.移除元素 2.删除有序数组中的重复项 3.合并两个有序数组 1.移除元素 链接直达: https://leetcode-cn.com/problems/remove-element/ 题目: 思路: 法一:依次挪动数据进行覆盖 从第一个数据开始进行依次遍历,如同示例1,依次遍历数组,找到移除的元素2就把后面的数据往前挪动进行覆盖,如图所示: 此法有个缺陷,题目中明确指出使用空间复杂度O(1)的方法解决此问题,而此法的空间复杂度刚好为O(1),可以解决,不过考虑周全些,时间复杂度在情况最

  • C语言实现顺序表的全操作详解

    目录 线性表 顺序表 顺序表接口实现 1.顺序表初始化 2.顺序表空间增容 3.顺序表打印 4.尾插数据 5.尾删数据 6.头插数据 7.头删数据 8.在pos下标处插入数据 9.删除pos下标处数据 10.数据查找 11.顺序表摧毁 线性表 线性表(linear list)是n个具有相同特性的数据元素的有限序列.线性表是一种在实际中广泛使用的数据结构,常见的线性表有:顺序表.链表.栈.队列.字符串等. 线性表在逻辑上是线性结构,也就是连续的一条直线.但在物理结构上并不一定是连续的,线性表在物理

  • C语言数据结构顺序表的进阶讲解

    目录 前言 一.顺序表的构造VS功能 1.顺序表的构造 2.接口实现(功能) 二.功能具体分析 1.初始化 2.销毁 3.检查size与capacity是否溢出 4.尾增功能(实现) 5.打印 三.实现具体功能代码页(SeqList.c) 四.总结 前言 在学习链表之前先掌握顺序表 什么是顺序表? 顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构一般情况下采用数组存储,在数组上完成数据的增删查改. 顺序表一般可分为: 1.静态顺序表:使用定长数组存储. 2.动态顺序表:使用动态开辟

  • C语言的线性表之顺序表你了解吗

    目录 线性表 —— 顺序表 (C语言) 1. 顺序表的储存结构 2. 顺序表的基本操作 2.1 顺序表的插入 2.2 顺序表的查找 2.3 顺序表的删除 总结 线性表 —— 顺序表 (C语言) 概念 线性表的顺序表示指的是用一组地址连续的存储单元依次存储线性表中的数据元素,这种表示也称做线性表的顺序储存结构或顺序映像.通常,称这种存储结构的线性表为顺序表 (Sequential List) .其特点是,逻辑上相邻的数据元素,其物理次序也是相邻的. 1. 顺序表的储存结构 #include <st

  • C语言线性表中顺序表超详细理解

    目录 一.本章重点 二.线性表 三.顺序表 四.静态顺序表接口实现 4.1顺序表初始化 4.2顺序表打印 4.3顺序表尾插 4.4顺序表尾删 4.5顺序表头插 4.6顺序表头删 4.7顺序表任意位置插入 4.8顺序表任意位置删除 五.动态顺序表接口实现 5.1顺序表的初始化 5.2顺序表打印 5.3顺序表尾插 5.4顺序表尾删 5.5顺序表头插 5.6顺序表头删 5.7顺序表任意位置插入 5.8顺序表任意位置删除 六.在线0j练习 一.移除元素(力扣) 二.合并两个有序数组(力扣) 一.本章重点

  • C语言 超详细顺序表的模拟实现实例建议收藏

    目录 概念及结构 接口实现 1 顺序表的动态存储 2 顺序表初始化 3 顺序表的销毁 4 顺序表的尾插 5 顺序表的尾删 6 顺序表的头插 7 顺序表的头删 8 顺序表容量的检查与扩容 9 顺序表任意位置的插入 10 顺序表任意位置的删除 11 顺序表的打印 12 顺序表元素的查找 13 顺序表元素的修改 概念及结构 顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储.在数组 上完成数据的增删查改. 顺序表一般可以分为: 静态顺序表:使用定长数组存储元素,元素

  • C语言全面讲解顺序表使用操作

    目录 一.顺序表的结构定义 二.顺序表的结构操作 1.初始化 2.插入操作 3.删除操作 4.扩容操作 5.释放操作 6.输出 三.示例 编程环境为 ubuntu 18.04. 顺序表需要连续一片存储空间,存储任意类型的元素,这里以存储 int 类型数据为例. 一.顺序表的结构定义 size 为容量,length 为当前已知数据表元素的个数 typedef struct Vector{ int *data; //该顺序表这片连续空间的首地址 int size, length; } Vec; 二.

  • C语言深入浅出讲解顺序表的实现

    目录 1.线性表 2.顺序表 2.1 概念及结构 2.2 提供接口 2.3 接口实现 今天起开始编写数据结构中的各种数据结构及算法的实现,说到顺序表,我们首先得了解下线性表. 1.线性表 线性表(linear list)是n个具有相同特性的数据元素的有限序列. 线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表.链表.栈.队列.字符串… 线性表在逻辑上是线性结构,也就说是连续的一条直线.但是在物理结构上并不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储. 2.顺序表

  • C语言超详细讲解顺序表的各种操作

    目录 顺序表是什么 顺序表的结构体 顺序表的接口函数 顺序表相关操作的菜单 顺序表的初始化 添加元素 陈列元素 往最后加元素 往前面加元素 任意位置加元素 删除最后元素 删除前面元素 删除任意元素 整体代码(fun.h部分) 整体代码(fun.cpp部分) 整体代码(主函数部分) 结果展示 顺序表是什么 顺序表是在计算机内存中以数组的形式保存的线性表,线性表的顺序存储是指用一组地址连续的存储单元依次存储线性表中的各个元素.使得线性表中在逻辑结构上相邻的数据元素存储在相邻的物理存储单元中,即通过数

  • C语言深入浅出讲解直接插入排序算法的实现

    目录 直接插入排序 1.基本思想 2.算法实现 3.时间复杂度 插入排序分为两种:直接插入排序&希尔排序 直接插入排序 1.基本思想 直接插入排序是一种简单的插入排序算法,其基本思想是: 把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完为止,得到一个新的有序序列 . 说得通俗一点就是: 假设区间[0, end]有序,将end+1位置的值插入到[0, end]中,保持区间[0, end+1]依旧有序. 生活中我们玩扑克牌时,就用了插入排序的思想. 在这里,

  • C语言实现动态顺序表的实现代码

    C语言实现动态顺序表的实现代码 顺序表是在计算机内存中以数组的形式保存的线性表,是指用一组地址连续的存储单元依次存储数据元素的线性结构.线性表采用顺序存储的方式存储就称之为顺序表.顺序表是将表中的结点依次存放在计算机内存中一组地址连续的存储单元中. 静态实现:结构体内部只需两个成员,其中一个为固定大小(MAX)的数组,用来存放我们的数据.数组大小我们可以通过在头文件中改变MAX的值来改变. 动态实现:在内存中开辟一块空间,可以随我们数据数量的增多来扩容. 来看看动态的顺序表实现: 1.seqli

  • C语言实现静态顺序表的实例详解

    C语言实现静态顺序表的实例详解 线性表 定义一张顺序表也就是在内存中开辟一段连续的存储空间,并给它一个名字进行标识.只有定义了一个顺序表,才能利用该顺序表存放数据元素,也才能对该顺序表进行各种操作. 接下来看看静态的顺序表,直接上代码: SeqList.h #define _CRT_SECURE_NO_WARNINGS 1 #ifndef __SEQLIST_H__ #define __SEQLIST_H__ #include <stdio.h> #include <stdlib.h&g

  • C语言数据结构之顺序表和单链表

    一.顺序表的创建.删除和插入 #define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> struct sqlist { int date[10]; int length; }; void InitList(sqlist& L) { for (int i = 0;i < 10;i++) { L.date[i] = 0; } L.length = 0; } void charu(sqlist& L) { for (int j =

  • 新手向超详细的C语言实现动态顺序表

    目录 一.各个函数接口的实现 1.1 不太好''李姐''的"容量检测函数" 1.2 在任意位置插入的函数"坑!" 1.3 在任意位置删除数据的函数 1.4 其余简单的接口函数 二.顺序表结构体声明与定义 三.头文件的调用 一.各个函数接口的实现 1.1 不太好''李姐''的"容量检测函数" 对顺序表进行插入数据时,需要判断顺序表的容量是否充足,增加数据的同时需要反复地检测容量,所以推荐直接将以上步骤封装成一个函数. 函数实现算法:若容量大小 ==

  • C++ 数据结构超详细讲解顺序表

    目录 前言 一.顺序表是什么 概念及结构 二.顺序表的实现 顺序表的缺点 几道练手题 总结 (●’◡’●) 前言 线性表是n个具有相同特性的数据元素的有限序列.线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表.链表.栈.队列.字符串. 线性表在逻辑上是线性结构,也就是说连续的一条直线,但是在物理结构并不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储. 本章我们来深度初体验顺序表 一.顺序表是什么 概念及结构 顺序表是一段物理地址连续的存储单元依次存储数据元素的线性

随机推荐