【数据结构初阶】二、 线性表里的顺序表(C语言实现顺序表)

这篇具有很好参考价值的文章主要介绍了【数据结构初阶】二、 线性表里的顺序表(C语言实现顺序表)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

=========================================================================

相关代码gitee自取

C语言学习日记: 加油努力 (gitee.com)

 =========================================================================

接上期

【数据结构初阶】一. 复杂度讲解_高高的胖子的博客-CSDN博客

 =========================================================================

                      

1 . 线性表

               

线性表linear list)是n个具有相同特性的数据元素的有限序列

线性表是一种在实际中广泛使用的数据结构

常见线性表顺序表链表队列字符串...

顺序表示例:

【数据结构初阶】二、 线性表里的顺序表(C语言实现顺序表),CCC全是C,数据结构,c语言

              

              

线性表逻辑上线性结构,也就说是连续的一条直线

但是在物理结构上并不一定是连续的

线性表物理上存储时,通常以数组链式结构形式存储

链表示例:

【数据结构初阶】二、 线性表里的顺序表(C语言实现顺序表),CCC全是C,数据结构,c语言

         

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

             

2 . 顺序表

顺序表概念及结构:

               

顺序表一段物理地址连续的存储单元依次存储数据元素线性结构

一般情况下采用数组存储

数组上完成数据的增删查改

顺序表一般可以分为 静态顺序表动态顺序表

               

               

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

                

因为静态顺序表使用定长数组存储元素

对空间的运用不够灵活,可能造成空间浪费或不够的问题
所以在实际情况下静态顺序表并不常用不够实用

示例:

【数据结构初阶】二、 线性表里的顺序表(C语言实现顺序表),CCC全是C,数据结构,c语言

                    

                    

动态顺序表:使用动态开辟的数组存储元素

             

静态顺序表适用于确定知道需要存多少数据的场景

静态顺序表定长数组导致N定大了空间开多了浪费开少了不够用

所以现实中基本都是使用动态顺序表根据需要动态地分配空间大小

示例:

【数据结构初阶】二、 线性表里的顺序表(C语言实现顺序表),CCC全是C,数据结构,c语言

         

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

             

3 .接口实现(实现动态顺序表):

(详细解释在注释,代码分文件放最后)

                

数据结构可以管理数据

通过 增删改查 等操作就可以实现管理数据

              

现在有了动态顺序表后

就可以对其进行增删改查等操作实现动态顺序表

                      文章来源地址https://www.toymoban.com/news/detail-714890.html

                        

--------------------------------------------------------------------------------------------------------------------------

                  

                      

SLInit函数 -- 顺序表初始化

【数据结构初阶】二、 线性表里的顺序表(C语言实现顺序表),CCC全是C,数据结构,c语言

                      

                      

--------------------------------------------------------------------------------------------------------------------------

                  

                      

SLDestroy函数 -- 顺序表销毁

【数据结构初阶】二、 线性表里的顺序表(C语言实现顺序表),CCC全是C,数据结构,c语言

                      

                        

--------------------------------------------------------------------------------------------------------------------------

                  

                      

SLPrint函数 -- 测试函数

【数据结构初阶】二、 线性表里的顺序表(C语言实现顺序表),CCC全是C,数据结构,c语言

                      

                        

--------------------------------------------------------------------------------------------------------------------------

                  

                      

SLPushBack函数 -- 将值插入顺序表尾部(尾插)

【数据结构初阶】二、 线性表里的顺序表(C语言实现顺序表),CCC全是C,数据结构,c语言

尾插函数SLPushBack测试:

【数据结构初阶】二、 线性表里的顺序表(C语言实现顺序表),CCC全是C,数据结构,c语言

                      

                        

--------------------------------------------------------------------------------------------------------------------------

                  

                      

上面尾插需要考虑空间不够进行扩容

后面的头插同样也需要考虑

所以可以在顺序表实现文件设置一个内部函数SLCheckCapacity,

在需要的时候直接调用该函数进行扩容操作

↓↓↓↓↓

                 

SLCheckCapacity内部函数 -- 进行扩容操作

【数据结构初阶】二、 线性表里的顺序表(C语言实现顺序表),CCC全是C,数据结构,c语言

                      

                        

--------------------------------------------------------------------------------------------------------------------------

                  

                      

SLPopBack函数 -- 将值从顺序表尾部删除(尾删)

【数据结构初阶】二、 线性表里的顺序表(C语言实现顺序表),CCC全是C,数据结构,c语言

尾删函数SLPopBack测试:

【数据结构初阶】二、 线性表里的顺序表(C语言实现顺序表),CCC全是C,数据结构,c语言

                      

                        

--------------------------------------------------------------------------------------------------------------------------

                  

                      

SLPushFront函数 -- 将值插入顺序表头部(头插)

【数据结构初阶】二、 线性表里的顺序表(C语言实现顺序表),CCC全是C,数据结构,c语言

头插函数SLPushFront测试:

【数据结构初阶】二、 线性表里的顺序表(C语言实现顺序表),CCC全是C,数据结构,c语言

                      

                        

--------------------------------------------------------------------------------------------------------------------------

                  

                      

SLPopFront函数 -- 将值从顺序表头部删除(头删)

【数据结构初阶】二、 线性表里的顺序表(C语言实现顺序表),CCC全是C,数据结构,c语言

头删函数SLPopFront测试:

【数据结构初阶】二、 线性表里的顺序表(C语言实现顺序表),CCC全是C,数据结构,c语言

                      

                        

--------------------------------------------------------------------------------------------------------------------------

                  

                      

SLInsert函数 -- 在指定位置(pos)插入想要的值(x)

【数据结构初阶】二、 线性表里的顺序表(C语言实现顺序表),CCC全是C,数据结构,c语言

指定添加函数SLInsert测试:

【数据结构初阶】二、 线性表里的顺序表(C语言实现顺序表),CCC全是C,数据结构,c语言

             

这里写了指定位置插入SLInsert函数

可以想到其实 头插 尾插 也是可以用 SLInsert函数 实现的

所以可以在头插和尾插函数中复用 SLInsert函数减少代码量

↓↓↓↓↓

                  

复用SLInsert函数 -- 改写头插函数SLPushFront

【数据结构初阶】二、 线性表里的顺序表(C语言实现顺序表),CCC全是C,数据结构,c语言

                     

复用SLInsert函数 -- 改写尾插函数SLPushBack

【数据结构初阶】二、 线性表里的顺序表(C语言实现顺序表),CCC全是C,数据结构,c语言

                      

                        

--------------------------------------------------------------------------------------------------------------------------

                  

                      

上面SLInsert函数涉及了插入位置pos下标

有时在增删改查操作时,需要知道有效元素中某个元素的下标再进行操作,

所以我们可以定义一个函数SLFind查找该元素的下标

↓↓↓↓↓

                 

SLFind函数 -- 查找x这个值在顺序表中的下标是多少

【数据结构初阶】二、 线性表里的顺序表(C语言实现顺序表),CCC全是C,数据结构,c语言

查找函数SLFind测试:

【数据结构初阶】二、 线性表里的顺序表(C语言实现顺序表),CCC全是C,数据结构,c语言

                      

                        

--------------------------------------------------------------------------------------------------------------------------

                  

                      

SLErase函数 -- 删除指定位置(pos)的值

【数据结构初阶】二、 线性表里的顺序表(C语言实现顺序表),CCC全是C,数据结构,c语言

删除指定位置函数SLErase测试:

【数据结构初阶】二、 线性表里的顺序表(C语言实现顺序表),CCC全是C,数据结构,c语言

                   

完成指定删除SLErase函数

头删 尾删 函数中也可以进行复用 SLErase函数 减少代码量

↓↓↓↓↓

                  

用SLErase函数 -- 改写头删函数SLPopFront

【数据结构初阶】二、 线性表里的顺序表(C语言实现顺序表),CCC全是C,数据结构,c语言

                     

用SLErase函数 -- 改写尾删函数SLPopBack

【数据结构初阶】二、 线性表里的顺序表(C语言实现顺序表),CCC全是C,数据结构,c语言

                      

                        

--------------------------------------------------------------------------------------------------------------------------

                  

                      

SLModify函数 -- 把某个位置(pos)的值修改为某值(x)

【数据结构初阶】二、 线性表里的顺序表(C语言实现顺序表),CCC全是C,数据结构,c语言

修改函数SLModify测试:

【数据结构初阶】二、 线性表里的顺序表(C语言实现顺序表),CCC全是C,数据结构,c语言

          

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

             

4 . 对应代码

SeqList.h -- 顺序表头文件

#pragma once

定义一个静态顺序表:使用定长数组存储元素
因为静态顺序表使用定长数组存储元素,对空间的运用不够灵活
所以在实际情况下,静态顺序表并不常用(不够实用)
//
//#define N 1000  //“表”的大小的值
//typedef int SLDataType;  //定义顺序表中存储的类型,这里是int类型
//
//struct SeqList
//{
//	SLDataType a[N]; //定义表的大小
//	int size; //记录表中存储了多少个有效数据
//};


//将需要的头文件都包含在 SeqList.h 头文件中
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>


//定义一个动态顺序表:使用动态开辟的数组存储元素
typedef int SLDataType;  //定义顺序表中存储的类型,这里是int类型

typedef struct SeqList
{
	//定义一个顺序表类型的指针,指向动态开辟的数组
	SLDataType* a; 
	
	int size; //记录表中存储了多少个有效数据
	int capactity; //容量空间的大小
}SL;


//数据结构 --> 管理数据 --> 增删查改

//顺序表初始化  --  头文件中声明
void SLInit(SL* ps); 

//顺序表销毁 --  头文件中声明
//内存是动态开辟地,不销毁的话可能会导致内存泄漏)
void SLDestroy(SL* ps);

//写一个测试函数(声明),方便检查各步骤有没有问题:
void SLPrint(SL* ps);

//尾插(声明) -- 将值插入顺序表尾部:
void SLPushBack(SL* ps, SLDataType x);

//尾删(声明) -- 将值从顺序表尾部删除:
void SLPopBack(SL* ps);

//头插(声明) -- 将值插入顺序表头部:
void SLPushFront(SL* ps, SLDataType x);

//头删(声明) -- 将值从顺序表头部删除:
void SLPopFront(SL* ps);

//在指定位置(pos)插入想要的值(x)
void SLInsert(SL* ps, int pos, SLDataType x);

//查找x这个值在顺序表中的下标是多少:
int SLFind(SL* ps, SLDataType x); //返回找到的下标

//删除指定位置(pos)的值:
void SLErase(SL* ps, int pos);

//把某个位置(pos)的值修改为某值(x)
void SLModify(SL* ps, int pos, SLDataType x);

                        

--------------------------------------------------------------------------------------------------------------------------

                  

                      

SeqList.c -- 顺序表实现文件

#define _CRT_SECURE_NO_WARNINGS 1

//包含我们写的 SeqList.h 头文件
#include "SeqList.h"


//顺序表初始化 -- 实现
void SLInit(SL* ps)
{
	//assert断言,防止接收空指针:
	assert(ps);

	//初始化顺序表类型指针
	//初始化时要先开辟一些动态空间:
	//开辟的空间为顺序表类型,大小为4个顺序表类型的大小
	ps->a = (SLDataType*)malloc(sizeof(SLDataType)*4); 
	
	//顺序表作为一个独立的程序,之后可能会应用于其他程序,
	//所以要对开辟的动态空间进行检查:
	if (ps->a == NULL)
	{
		//可能开辟的空间过大 或 前面开辟太多空间不够再开辟
		perror("malloc failed");  //打印错误

		//让程序以异常的形式结束程序
		//和 return 不同,return后主函数还会继续进行
		exit(-1);
	}

	//将顺序表中的有效数据初始化为0:
	ps->size = 0;

	//将已动态开辟的容量空间初始化为4:
	ps->capactity = 4;
}



//顺序表销毁 -- 实现
//内存是动态开辟地,不销毁的话可能会导致内存泄漏)
void SLDestroy(SL* ps)
{
	//assert断言,防止接收空指针:
	assert(ps);

	//释放前面开辟的动态空间:
	free(ps->a);
	
	//将释放的指针置为空指针:
	ps->a = NULL;

	//将已开辟的动态空间置为0,顺序表有效数据也置为0
	ps->capactity = ps->size = 0;
}



//写一个测试函数(实现),方便检查各步骤有没有问题:
void SLPrint(SL* ps)
{
	//assert断言,防止接收空指针:
	assert(ps);

	//打印动态顺序表现有的有效数据:
	for (int i = 0; i < ps->size; i++)
	{
		printf("%d ", ps->a[i]);
	}

	//打印完当前动态顺序表有效数据后进行换行:
	printf("\n");
}



//在顺序表实现文件中设置一个内部函数SLCheckCapacity,
//在需要的时候直接调用该函数进行扩容操作
void SLCheckCapacity(SL* ps)
{
	//assert断言,防止接收空指针:
	assert(ps);

	//判断开辟的空间是否已满,满了再开辟:
	if (ps->size == ps->capactity)
		//顺序表有效个数 等于 已开辟容量空间
	{
		//使用 realloc函数 进行扩容,每次扩容2倍:
		SLDataType* tmp = (SLDataType*)realloc(ps->a, ps->capactity * 2 * (sizeof(SLDataType)));
		// realloc 是把空间扩容到第二个参数的大小,而不是直接把空间扩容第二个参数的大小

		//同样进行检验:
		if (tmp == NULL)
		{
			//打印错误:
			perror("realloc failed");
			//出现错误直接终止程序:
			exit(-1);
		}

		//realloc函数,有两种扩容情况:一种是原地扩容,另一种是异地扩容
		//原地扩容:扩容时看原空间后的内容有没有分配给别人,如果没有则把原空间后面的空间标记出来进行扩容,返回原空间的地址
		//异地扩容:如果扩容时原空间后面的内容已被分配,则另找一个足够原空间扩容后的空间进行存放,
		//		   原本的数据都搬到这个空间来,原空间会被释放,返回这个新空间的地址。
		//所以使用 realloc函数 扩容后,不要对原空间指针进行释放,
		//如果realloc执行后是原地扩容返回原空间指针,扩容后后对原空间指针释放就会出问题


		//把扩容返回的指针赋给原指针:
		ps->a = tmp;

		//将已动态开辟的容量空间置为原来的2倍:
		ps->capactity *= 2;
	}
}



//尾插(实现) -- 将值插入顺序表尾部:
void SLPushBack(SL* ps, SLDataType x)
{
	//assert断言,防止接收空指针:
	assert(ps);

	调用内部函数进行扩容操作:
	//SLCheckCapacity(ps);

	空间容量足够后将要插入尾部的值插入:
	//ps->a[ps->size] = x; 
	因为下标从0开始,所以size的值会等于现有元素下一位的下标

	//ps->size++; //尾部插入元素后,更新顺序表中有效数据个数

	//复用SLInsert函数 -- 改写尾插函数SLPushBack
	SLInsert(ps, ps->size, x); //在size位置插入就相当于尾插
}



//尾删(实现) -- 将值从顺序表尾部删除:
void SLPopBack(SL* ps)
{
	//assert断言,防止接收空指针:
	assert(ps);

	检查一下:如果有效数据size等于0,则不能继续删除了
	防止越界,可能一直删除到空间外了导致越界
	//
	检查方法一:太“温柔”,返回后不知道自己错了
	if (ps->size == 0)
	{
		return; //直接返回 即可
	}
	//
	检查方法二:使用断言,错误了会直接报错并给出错误信息
	//assert(ps->size > 0); //顺序表中有效数据大于0才进行下面的操作

	直接有效数据size--即可
	尾插是也是用size插入的,所以下次添加时直接就覆盖了原来值
	//ps->size--;

	不能局部释放,不能说不要末尾的值就把末尾的这个空间直接释放掉
	C++有个规定,malloc一次就要free一次,要free释放的话只能整体释放
	顺序表的物理内存是连续的,释放空间是不能“分期”的


	//复用SLErase函数 -- 改写尾删函数SLPopBack
	SLErase(ps, ps->size-1); //size-1 就是最末元素下标
}



//头插(实现) -- 将值插入顺序表头部:
void SLPushFront(SL* ps, SLDataType x)
{
	//assert断言,防止接收空指针:
	assert(ps);

	调用内部函数进行扩容操作:
	//SLCheckCapacity(ps);

	将现有有效数据往后移一位,让出头位置:
	//int end = ps->size - 1; 
	size-1 有效个数-1,就相当于当前最后一个元素的下标

	//while (end >= 0)
	//	//使用while循环循环移动各个有效元素,一直移到下标为0的元素
	//{
	//	ps->a[end + 1] = ps->a[end]; //end下标元素 移到 下一位上
	//	--end; //改变下标
	//}

	将要插入头部的元素x插入头部:
	//ps->a[0] = x;

	有效个数加一:
	//ps->size++;

	Capacity在扩容函数SLCheckCapacity中就修改好了


	//复用SLInsert函数 -- 改写头插函数SLPushFront
	SLInsert(ps, 0, x); //在0位置插入就相当于头插
}



//头删(实现) -- 将值从顺序表头部删除:
void SLPopFront(SL* ps)
{
	//assert断言,防止接收空指针:
	assert(ps);

	因为要将头部的有效元素删除,
	所以直接把第一个有效元素后面的其他元素往前移一位就行了,
	覆盖掉第一个元素

	先进行断言检查,防止没有元素还进行删除:
	//assert(ps->size > 0);

	//int begin = 1; //从下标为1的元素开始往前移,把下标为0的元素覆盖

	//while (begin < ps->size)
	//	//只要begin还小于有效元素个数就继续往前移
	//	//因为是从下标为1的元素开始移动,
	//	//所以最后就只有下标为0的元素没动
	//{
	//	//把当前begin下标的元素往前挪一位:
	//	ps->a[begin - 1] = ps->a[begin]; 

	//	//当前begin下标元素移动后,begin++继续移动下一位:
	//	++begin;
	//}
	//
	因为第一个元素被覆盖,所以有效元素size--
	//ps->size--;


	//复用SLErase函数 -- 改写头删函数SLPopFront
	SLErase(ps, 0); //头元素下标是0
}



//在指定位置(pos)插入想要的值(x)
void SLInsert(SL* ps, int pos, SLDataType x)
{
	//先使用assert检查pos是否合法:
	//在pos位置插入一个值后,顺序表还得是连续的
	assert(pos >= 0 && pos <= ps->size);
	//pos等于0 -- 相等于头插
	//pos等于size -- 相等于尾插
	
	//使用SLCheckCapacity进行扩容操作:
	SLCheckCapacity(ps);

	//定义一个变量end,对应要移动元素的下标
	int end = ps->size - 1; //一开始对应最后一个元素的下标

	while (end >= pos)
		//只要end下标对应的元素还在pos下标元素的右边
		//就把“end元素”向右移,移到pos下标无元素
	{
		//把“end元素”向右移
		ps->a[end + 1] = ps->a[end];
		
		//移动下标进行写一个元素的移动
		--end;
	}

	//让出位置后,将接收的x插入pos位置:
	ps->a[pos] = x;

	//有效元素+1:
	ps->size++;
}



//查找x这个值在顺序表中的下标是多少:
int SLFind(SL* ps, SLDataType x) //返回找到的下标
{
	//assert断言,防止接收空指针:
	assert(ps);

	//数据量不大的话直接暴力查找吧:
	for (int i = 0; i < ps->size; i++)
		//有几个有效元素就循环几次:
	{
		if (ps->a[i] == x)
			//该下标元素等于要找的值x则返回当前下标:
		{
			return i;
		}
	}

	return -1; //表未找到该元素下标
}



//删除指定位置(pos)的值:
void SLErase(SL* ps, int pos)
{
	//同样先使用assert检查pos是否合法:
	//这里检查条件pos不能像SLInsert一样等于size
	//因为size空了能插入(尾插),但不能删除
	assert(pos >= 0 && pos < ps->size);

	//指定删除和头删的思路类似,
	//只要把pos后面的值往前覆盖,覆盖掉pos的值就好了:

	int begin = pos + 1; //从pos+1的位置往前挪
	
	while (begin < ps->size)
		//一直移到size为止(不包括size位置)
	{
		ps->a[begin - 1] = ps->a[begin]; //往前挪
		++begin; //挪完继续挪下一个 
	}

	ps->size--; //覆盖掉pos位置的值后,有效数字减一
}



//把pos位置的值修改为x
void SLModify(SL* ps, int pos, SLDataType x)
{
	//同样先使用assert断言检查pos是否合法:
	assert(pos >= 0 && pos < ps->size);

	//进行修改:
	ps->a[pos] = x;
}

                        

--------------------------------------------------------------------------------------------------------------------------

                  

                      

test.c -- 测试函数

#define _CRT_SECURE_NO_WARNINGS 1

//包含我们写的 SeqList.h 头文件
#include "SeqList.h"

//分组测试,测试不同的函数--SLPushBack 和 SLPopBack 函数
void TestSeqList1()
{
	SL sl;  //创建顺序表类型变量

	//使用 SLInit函数 初始化顺序表类型变量
	//注意传递的是变量的地址,防止形参改变实参不改变
	SLInit(&sl);

	//使用尾插函数SLPushBack:
	SLPushBack(&sl, 1);
	SLPushBack(&sl, 2);
	SLPushBack(&sl, 3);
	SLPushBack(&sl, 4);
	//此时再调用会进行扩容:
	SLPushBack(&sl, 5);
	SLPushBack(&sl, 6);
	//调用测试函数SPrint查看是否插入成功:
	SLPrint(&sl);

	//测试尾删函数SLPopBack:
	SLPopBack(&sl);
	SLPopBack(&sl);
	//调用测试函数SPrint查看是否“删除”成功:
	SLPrint(&sl);

	//测试完后使用SLDestroy函数销毁顺序表:
	SLDestroy(&sl);
}

//分组测试,测试不同的函数--SLPushFront函数
void TestSeqList2()
{
	SL sl;  //创建顺序表类型变量

	//使用 SLInit函数 初始化顺序表类型变量
	//注意传递的是变量的地址,防止形参改变实参不改变
	SLInit(&sl);

	//使用尾插函数SLPushBack:
	SLPushBack(&sl, 1);
	SLPushBack(&sl, 2);
	SLPushBack(&sl, 3);
	SLPushBack(&sl, 4);
	//此时再调用会进行扩容:
	SLPushBack(&sl, 5);
	SLPushBack(&sl, 6);
	//调用测试函数SPrint查看是否插入成功:
	SLPrint(&sl);

	//测试头插函数SLPushFront:
	SLPushFront(&sl, 10);
	SLPushFront(&sl, 20);
	//调用测试函数SPrint查看是否“删除”成功:
	SLPrint(&sl);

	//测试完后使用SLDestroy函数销毁顺序表:
	SLDestroy(&sl);
}


//分组测试,测试不同的函数--SLPopFront函数
void TestSeqList3()
{
	SL sl;  //创建顺序表类型变量

	//使用 SLInit函数 初始化顺序表类型变量
	//注意传递的是变量的地址,防止形参改变实参不改变
	SLInit(&sl);

	//使用尾插函数SLPushBack:
	SLPushBack(&sl, 1);
	SLPushBack(&sl, 2);
	SLPushBack(&sl, 3);
	SLPushBack(&sl, 4);
	//此时再调用会进行扩容:
	SLPushBack(&sl, 5);
	SLPushBack(&sl, 6);
	//调用测试函数SPrint查看是否插入成功:
	SLPrint(&sl);

	//测试头删函数SLPopFront:
	SLPopFront(&sl);
	SLPopFront(&sl);
	//调用测试函数SPrint查看是否“删除”成功:
	SLPrint(&sl);

	//测试完后使用SLDestroy函数销毁顺序表:
	SLDestroy(&sl);
}

//分组测试,测试不同的函数--SLInsert函数
void TestSeqList4()
{
	SL sl;  //创建顺序表类型变量

	//使用 SLInit函数 初始化顺序表类型变量
	//注意传递的是变量的地址,防止形参改变实参不改变
	SLInit(&sl);

	//使用尾插函数SLPushBack:
	SLPushBack(&sl, 1);
	SLPushBack(&sl, 2);
	SLPushBack(&sl, 3);
	SLPushBack(&sl, 4);
	//此时再调用会进行扩容:
	SLPushBack(&sl, 5);
	SLPushBack(&sl, 6);
	//调用测试函数SPrint查看是否插入成功:
	SLPrint(&sl);

	//测试指定增加函数SLInsert:
	SLInsert(&sl, 2, 100);
	//调用测试函数SPrint查看是否“删除”成功:
	SLPrint(&sl);

	//int x;
	//scanf("%d", &x);
	//int pos = SLFind(&sl, x);
	//if (pos != -1)
	//{
	//	SLInsert(&sl, pos, x * 10);
	//}
	//SLPrint(&sl);

	//测试完后使用SLDestroy函数销毁顺序表:
	SLDestroy(&sl);
}


//分组测试,测试不同的函数--SLFind函数
void TestSeqList5()
{
	SL sl;  //创建顺序表类型变量

	//使用 SLInit函数 初始化顺序表类型变量
	//注意传递的是变量的地址,防止形参改变实参不改变
	SLInit(&sl);

	//使用尾插函数SLPushBack:
	SLPushBack(&sl, 1);
	SLPushBack(&sl, 2);
	SLPushBack(&sl, 3);
	SLPushBack(&sl, 4);
	//此时再调用会进行扩容:
	SLPushBack(&sl, 5);
	SLPushBack(&sl, 6);
	//调用测试函数SPrint查看是否插入成功:
	SLPrint(&sl);

	//测试指定增加函数SLFind:
	int pos = SLFind(&sl, 2);
	
	printf("2在元素中是第%d个元素", pos+1);

	//测试完后使用SLDestroy函数销毁顺序表:
	SLDestroy(&sl);
}

//分组测试,测试不同的函数--SLErase函数
void TestSeqList6()
{
	SL sl;  //创建顺序表类型变量

	//使用 SLInit函数 初始化顺序表类型变量
	//注意传递的是变量的地址,防止形参改变实参不改变
	SLInit(&sl);

	//使用尾插函数SLPushBack:
	SLPushBack(&sl, 1);
	SLPushBack(&sl, 2);
	SLPushBack(&sl, 3);
	SLPushBack(&sl, 4);
	//此时再调用会进行扩容:
	SLPushBack(&sl, 5);
	SLPushBack(&sl, 6);
	//调用测试函数SPrint查看是否插入成功:
	SLPrint(&sl);

	int x;
	scanf("%d", &x);
	//配合SLFind函数,找到顺序表中某个值的下标
	int pos = SLFind(&sl, x);
	//再使用SLErase函数通过下标删除该值
	if (pos != -1)
	{
		SLErase(&sl, pos);
	}
	SLPrint(&sl);

	//测试完后使用SLDestroy函数销毁顺序表:
	SLDestroy(&sl);
}


//分组测试,测试不同的函数--SLModify函数
void TestSeqList7()
{
	SL sl;  //创建顺序表类型变量

	//使用 SLInit函数 初始化顺序表类型变量
	//注意传递的是变量的地址,防止形参改变实参不改变
	SLInit(&sl);

	//使用尾插函数SLPushBack:
	SLPushBack(&sl, 1);
	SLPushBack(&sl, 2);
	SLPushBack(&sl, 3);
	SLPushBack(&sl, 4);
	//此时再调用会进行扩容:
	SLPushBack(&sl, 5);
	SLPushBack(&sl, 6);
	//调用测试函数SPrint查看是否插入成功:
	SLPrint(&sl);
	
	//测试指定增加函数SLInsert:
	SLModify(&sl, 2, 100);
	//调用测试函数SPrint查看是否“删除”成功:
	SLPrint(&sl);

	//测试完后使用SLDestroy函数销毁顺序表:
	SLDestroy(&sl);
}

//菜单:
void menu()
{
	printf("********************************\n");
	printf("1、尾插			2、头插\n");
	printf("3、头删			4、尾删\n");
	printf("7、打印			-1、退出\n");
	printf("********************************\n");
}


int main()
{
	//先创建一个顺序表:
	SL sl;

	//再对其进行初始化:
	SLInit(&sl);

	//创建一个变量接收菜单选项:
	int option = 0;

	do
	{
		//使用菜单:
		menu();
		//打印提示信息:
		printf("请选择想要进行的操作的序号:>");
		//接收序号:
		scanf("%d", &option);
		
		printf("\n");

		if (option == 1)
		{
			printf("请依次输入你要插入的数据个数:>");
			int n = 0; //接收数据个数
			scanf("%d", &n); //接收数据个数
			
			printf("\n");
			printf("请依次输入你要插入的数据\n");

			//知道数据个数后,直接使用for循环循环接收数据
			int x = 0;
			for (int i = 0; i < n; i++)
			{
				scanf("%d", &x);
				SLPushBack(&sl, x);
			}
		}
		else if (option == 7)
		{
			SLPrint(&sl);
		}

	} while (option != -1);
	

	//最后销毁顺序表:
	SLDestroy(&sl);


	//TestSeqList1();
	//TestSeqList2();
	//TestSeqList3();
	//TestSeqList4();
	//TestSeqList5();
	//TestSeqList6();
	//TestSeqList7();

	return 0;
}

到了这里,关于【数据结构初阶】二、 线性表里的顺序表(C语言实现顺序表)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【数据结构初阶】八、非线性表里的二叉树(二叉树的实现 -- C语言链式结构)

    ========================================================================= 相关代码gitee自取 : C语言学习日记: 加油努力 (gitee.com)  ========================================================================= 接上期 : 【数据结构初阶】七、非线性表里的二叉树(堆的实现 -- C语言顺序结构)-CSDN博客  ==========

    2024年02月08日
    浏览(51)
  • 【数据结构初阶】五、线性表中的栈(C语言 -- 顺序表实现栈)

    ========================================================================= 相关代码gitee自取 : C语言学习日记: 加油努力 (gitee.com)  ========================================================================= 接上期 : 【数据结构初阶】四、线性表里的链表(带头+双向+循环 链表 -- C语言实现)_高高的胖子的博客

    2024年02月08日
    浏览(44)
  • 数据结构初阶之顺序表(C语言实现)

    顺序表是数据结构里面很基础的一类,它是线性表的一种,其它线性表还有链表、栈和队列等,今天来和博主一起学习关于顺序表的知识吧。 顺序表,它分为两类: 动态顺序表 和 静态顺序表 ,这两个表的区别就是 前者的空间不固定 ,是 支持扩容 的,后者的 空间是固定

    2024年02月03日
    浏览(45)
  • 初阶数据结构之---顺序表和链表(C语言)

    线性表: 线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构。线性表在逻辑上是线性结构,也就是说是连续的一条直线。但在物理上并不一定是连续的。线性表在物理上存储时,通常以 数组 和 链式结构 的形式存储。

    2024年02月22日
    浏览(66)
  • 『初阶数据结构 • C语言』⑦ - 静态顺序表详解(附完整源码)

    本章内容 1.什么是线性表 2.什么是顺序表  3.静态顺序表结构的定义 4.静态顺序表的函数接口实现 5.静态顺序表的问题及思考     线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、

    2024年02月15日
    浏览(44)
  • 『初阶数据结构 • C语言』⑧ - 动态顺序表详解(附完整源码)

    本章内容 写在前面 1.静态与动态是指什么? 2.动态顺序表结构的定义 3.动态顺序表的函数接口实现 4.动态顺序表的问题及思考 5.关于顺序表的OJ题 6.OJ答案及解析 1.移除元素 2.删除有序数组中的重复项 ​3.合并两个有序数组 7.动态顺序表完整源码 1.SeqList.h 2.SeqList.c     上一章

    2024年02月16日
    浏览(45)
  • C语言数据结构(2)——线性表其一(顺序表)

    欢迎来到博主的新专栏——C语言数据结构 博主ID:代码小豪 再开始这篇文章之前,我们假设要对10个数据进行操作。这十个数据全都被声明成10个变量 如果我们准备为这些数据增加功能,将他们进行赋值,打印,交换等。就会发现一个特别棘手的问题,这些程序写起来太繁杂

    2024年01月19日
    浏览(40)
  • 【数据结构初阶】六、线性表中的队列(C语言 -- 链式结构实现队列)

    ========================================================================= 相关代码gitee自取 : C语言学习日记: 加油努力 (gitee.com)  ========================================================================= 接上期 : 【数据结构初阶】五、线性表中的栈(C语言 -- 顺序表实现栈)_高高的胖子的博客-CSDN博客  

    2024年02月08日
    浏览(42)
  • 【数据结构】线性表的顺序存储结构及实现——C语言版

    线性表的顺序存储结构称为 顺序表 ,其基本思想是 用一段地址连续的存储单元一次存储线性表的数据元素。 设顺序表的每个元素占用 c 个存储单元,则第 i 个元素的存储地址为: 所以, 只要确定了存储顺序表的起始地址(即基地址),计算任意一个元素的存储地址的时间

    2024年03月15日
    浏览(53)
  • 数据结构入门(C语言版)线性表中顺序表介绍及接口实现

    C语言的学习结束,就该入门数据结构了呦 不论在程序员的工作上,还是在学习或是考研上,数据结构都是一门非常重要且值得我们一直研究探索的学科,可以说数据结构和算法就是编程的核心。OK,接下来我们来到数据结构的入门第一步就是学习线性表,接下来由作者来详细

    2023年04月12日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包