【数据结构初阶】二、 线性表里的顺序表

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

相关代码gitee自取

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

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

接上期

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

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

                     

1 . 线性表

               

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

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

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

顺序表示例:

【数据结构初阶】二、 线性表里的顺序表_第1张图片

              

              

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

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

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

链表示例:

【数据结构初阶】二、 线性表里的顺序表_第2张图片

         

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

             

2 . 顺序表

顺序表概念及结构:

               

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

一般情况下采用数组存储

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

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

               

               

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

                

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

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

示例:

                    

                    

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

             

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

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

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

示例:

         

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

             

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

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

                

数据结构可以管理数据

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

              

现在有了动态顺序表后

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

                      

                        

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

                  

                      

SLInit函数 -- 顺序表初始化

                      

                      

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

                  

                      

SLDestroy函数 -- 顺序表销毁

                      

                        

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

                  

                      

SLPrint函数 -- 测试函数

                      

                        

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

                  

                      

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

尾插函数SLPushBack测试:

                      

                        

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

                  

                      

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

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

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

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

↓↓↓↓↓

                 

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

                      

                        

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

                  

                      

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

尾删函数SLPopBack测试:

                      

                        

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

                  

                      

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

头插函数SLPushFront测试:

                      

                        

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

                  

                      

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

头删函数SLPopFront测试:

                      

                        

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

                  

                      

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

指定添加函数SLInsert测试:

             

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

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

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

↓↓↓↓↓

                  

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

                     

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

                      

                        

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

                  

                      

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

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

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

↓↓↓↓↓

                 

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

查找函数SLFind测试:

                      

                        

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

                  

                      

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

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

                   

完成指定删除SLErase函数

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

↓↓↓↓↓

                  

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

                     

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

                      

                        

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

                  

                      

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

修改函数SLModify测试:

          

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

             

4 . 对应代码

SeqList.h -- 顺序表头文件

#pragma once

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


//将需要的头文件都包含在 SeqList.h 头文件中
#include 
#include 
#include 


//定义一个动态顺序表:使用动态开辟的数组存储元素
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;
}

你可能感兴趣的:(CCC全是C,数据结构,c语言)