【数据结构】 - 顺序表的模拟实现

我们要完成一个顺序链表

顺序表

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

1.创建项目

先创建两个源文件,一个头文件 

426a7a1fe8de4db69d50f95ef35ce07d.png

只有头文件SeqList.h是#include<...>

其他两个源文件直接引用有文件,也就是#include"SeqList.h"

静态顺序表

SeqList.h

首先写一个结构体

2c484072fcd64122b2031e561029342b.png

 

有点问题因为a写死了,以后想修改的时候不好修改,所以最好加个define。

d5acbe6a5fec41e19f78c5bf421ea8b2.png

还有点问题这个数组默认存储的是int型,以后想换很多地方都要跟着换,所以加个typedef方便以后进行更换

ef976701c1ca447b90ffdb7b74f28803.png

 

问:有人问了为什么不是DataType而是SLDataType?

答:因为后边链表也要从定义那这个,那DataType是谁的?所以我们取首字母的缩写也就是SLDataType。

数据结构是对数据进行管理也就是增删查改。

一般我们不喜欢写静态的顺序表因为N到底给多少比较好?小了不够用,大了浪费。

静态顺序表在实际中非常不实用,因此我们还是会选择用动态顺序表

动态顺序表

8d05fc58f5924db28ebdf5ff91cf0404.png

 

逻辑图: 

cd728126f9b64004a62a91c6e0cbdd37.png

先写两个简单的 

初始化 

SeqList.h

5be528447a604ea9b2ff6d31dc8974a7.png

SeqList.c

f4393795a03d49deb83305f2032e90e8.png

Test.c

建议编写边测,例如写两个函数就测两个函数。

5207a5ea27d64a118553c23fce865354.png

这种写法是有问题的,原因很好理解

6dc0d06e4ff749ef98457f4385a6ab3c.png

所以三个文件都要改

SeqList.h (改进)

5d1d946ea3b24d0a88a92e0c6bcb81ae.png

SeqList.c(改进)

f9bf1909eddd458cba481f46cfa2378a.png

Test.c(改进)

f6ecd53ddca94d539590dc66155cf62f.png

运行结果:

f27105becd9749ff874bc01a82a1ef59.png

 

在SeqList.c中 

初始化函数也不是很好,应该稍微开上那么一点点空间。

f76764afccc648dfa68a7b97ceb571d2.png

应该写成这样,但是还是不完整虽然在OJ中没问题,但是这不是一个独立的程序在其他项目也可能在用,可能内存耗尽。所以最好检查一下

f3a7394774e64353bd984a9da4f917f2.png

exit(-1) 为什么这么写

exit(0) 代表正常结束,如果是负数那就是异常结束的

可以测试一下

打断点5edf8c3c1af04b08b9841fadf6989386.png

F11进入函数

鼠标把小箭头拖进判断程序中

212017b2726a44feaa7658eace77ba07.png

 

然后F11继续往下走直到结束程序看结果:

6fe1fa4ec5f143dca6597d8298940716.png

总结:正常终止是0,负数是异常终止是自己定义的。给0就不知道是正常结束还是异常结束了。

 

初始化写好了也要写销毁

销毁

SeqList.h

3327edd9793d4dfba739b2bba8bbf522.png

SeqList.c

5079f74c5894425bb655db0479de9da5.png

后边是四个核心操作

头插头删,尾插尾删

a263bae1b42c4b26b603cc0cf703b1f8.png

问为什么不取insertback intend...都可以。就像给你娃取名字一样。

但是这里是因为后边学C++会有个库,这里习惯了后边会容易一些。

但是千万不要用拼音,这就像给你娃取名狗蛋一样。

尾插

SeqList.h

3b0ab05bf99849cabc2b9d0ed470ddc2.png

思路:

bb7eba05b0584689a9c61e5e58848aa4.png

SeqList.c

e3585eca37334f159729d22a2088c472.png

一般我们都是扩两倍

bf91b214542440119fb5466cddc19439.png

记得判断一下是否扩容成功。 

问: 这里用不用free一下a?

答:不用,realloc 的本质有两种方式原地扩容和异地扩容

b05dd8ceb4d54c86be4c7509564c491c.png

 e02a606aa54b4e6da942aa4dc29f3fec.png

这里加上个新的函数SPrint 方便测试查看。

SeqList.h

d806ef3628284c039b7c8b681667155c.png

SeqList.c

1948ae10eec2420dba92c5ed4525ec55.png

Test.c

30f0ce3b26a54c71b9fde22b2ed095cd.png

运行结果:

7d1cc48c33374de8ae8d9e979630d835.png

 

尾删

SeqList.h

4ce14cd7e10647778a105c0d2e47d03d.png

SeqList.c

先这么写

思路:

6a59caea2b3f4ed98f2e5c934d6c554d.png

e8d7328975864d7e988dc2080b994ca9.png

然后测试一下看行不行

Test.c

dd310dbc38024fe6ab2ec8c2a200120f.png

测试结果:

c44ecc7f32a244e2977562fda758e692.png

自己可以多测试一下。

如果后边加上几个0呢?

8d729593811a4d66be2247357701af0a.png

运行结果:

82cb4e129e8241b383926dfe667c33d7.png

发现这个尾删并不是很有意义,0~size-1才是有效数据。

所以SeqList.c要改

SeqList.c(改进)

思路:

994eec946e5f4c00be9cc5a077add7ca.png

有人问用不用free一下?

答:不能 ,因为C++有个规定malloc一次就要free一次,要free就全部free,不能局部释放。

SeqList.c

2414824f29b241f7850dc2940f8a89c9.png

还有什么问题?

看一下Test.c的测试

e4b62d0bb5c241cab6b642e6cf15666e.png

运行结果: 

2b259f99e7e84cf9a4e412ee558ba31e.png

删完了,竟然没有报错。为什么呢?有问题不一定报错。

再看一组测试:

5a253b44fcee42549438d0feb14b0019.png

运行结果:

3f26dacf709347b1b8c44bcec3733b1f.png

 为什么1,2没有出现因为PopBack有问题没有解决。在监视中查看到size已经减到负数了。

越界不一定报错。是抽查有时候查得出来有时候查不出来。 

a9205ef4f1924834a38377682d250a48.png

 如果我们少删几个

42b6dd7cedaa4c99949ba3a27047915c.png

运行结果: 

9896c099aa1040f2b4e2b5b79bda273d.png

发现报错了

free没问题,哪问题在哪里呢? 

越界不一定被查出来,因为VS编译器在前后检查。-10的时候在检查外,但是size在检查内就会被查出来。

6cd77eab4db748539380b1b53c902a0e.png

free报错不一定是这个地方,有可能在其地方。 

所以

SeqList要改

ce9d46f522654985aaaecd3051a83d59.png

Test.c

6d92fe008e53437cbe6a09f794365a19.png

运行结果: 7cda05c0cca745618fd3781ccd2f10b0.png

在测试对的:

3f366c82ceab46538501afdc451de4e6.png

运行结果:

bc2abe13785d4cd7ab10b0ea1f4f6f4c.png

头插

SeqList.h

c71785af687345a1a068e0ca5494671e.png

SeqList.c

思路:

c2d26ca632f84638ad32ca1330fc9cab.png

还是需要扩容所以我们干脆提取一个公共的函数出来。

检查

SeqList.h

66bf1b4479f1471db77ae1c420e8142e.png

SeqList.c

 c054e57169474f6b8c7f5d7866a684e9.png

 同时头插也要改

 faf3ca6c3f5748feac6ca8c474750a70.png 

 头插思路:

47d1eb6506164daf844cfaf38eed3ee2.png

头插代码: 

0d2e066a7f23436d8e2fdeac3804f1c0.png

Test.c

这时候我们发现测试代码太多了,所以我们要学会分组测试

1a7369231efb435e88d4d6b02f918f5e.png

 运行结果:

ad6a676afdfb4fdcae587c1e523601ca.png

 

原来测试的可以放进TestSeqList1中。

229e7297d2904c71bbf45ff5f6cdfc46.png

163a671546014c38bcf1ca990dd93f89.png

 

头删 

SeqList.h

b86f0c99280445f681f6c517e5a3369a.png

SeqList.c

如果我们这样写对吗?

思路:

c44899b1cea84bffb64f167afcf79a40.png

e54c36ebe5fe4b9d983e26d5c9545a01.png

Test.c

874e198f0d7047bba376edd770f1296d.png

0ac899667f7d49e48d4415b1088aaf37.png

运行结果:

4863e8a3c7e846ec9fe5b6e9152e2924.png

原因和之前一样,也是越界了,越界了不一定报错。

最好的方式还是断言一下。暴力检查和温柔检查都可以。

SeqList.c(改进)

86f35f59de6d478d8e5049815a7587cd.png

运行结果:

8b2846320fe34db3bc6531b9ee7cf58a.png

这也和Destroy有关(释放的时候会检查)。最好是双管齐下。 

a2fffdfb9689485898b9587e243736a8.png

 SEqList.c改进

思路:08677e691f574a9f813d604491870a3e.png

eac9b1f6bf5348649c2f18fcb4dd09ab.png

 

为什么不a++?要顾头顾尾。有free和size变成随机值两个问题

ce8aaaf0fac44e70882ed0fcd756a85f.png

 

 a是指针,C语言数组的本质是只能定义成静态的,静态的就有一个问题写死了。动态的申请一个数组把这个空间第一个位置的地址给你。

9e5e4a0789c74723a63333b23903a453.png

 

在pos位置插入x

SeqList.h

0f15c4b64d054e7d941cf71e7f326e73.png

SeqList.c

初始条件(迭代的开始),循环结束条件(迭代的终止),中间走的过程(迭代的过程)

思路以及代码:

f8fc13da1d6c4c5899f522617d5b95a5.png

前期多画图 

Test.c

912b5791672345cca3bca19963136117.png

从0开始数。 

运行结果:

c62c5c9027bf473c86627e7d4dda42ec.png

查找 

SeqList.h

 720223aad774466fbed4b62c01dcd6f3.png

SeqList.c

df36cba4eec143e6a229c32a1f8090e9.png

Test.c 

aeb0003468d04188a79167af957b5c3b.png

运行结果:

 283ea2147ecc438494f52e36a1765009.png

输入一个数,找到那个数并且在前边输出他的10倍 。

 

到这里头插尾插是不是可以复用这个插入函数?

尾插

SeqList.c

38d2f5ac890d42d7b196acee26addd48.png

 

头插

SeqList.c

398b0555190241fca9b6215c6d88aca6.png

 

Test.c 

e8ff9ec60ab74937bfb8377c340e5b68.png

运行结果:

707d95921a7448d8a53bdac96bc48885.png

 

删除pos位置的值

SeqList.h

5d5dd728ccf54f28a74cf4e50b28e4d5.png

SeqList.c

54bc2280a36a46189c43ba12d43db165.png

Test.c

91f83d2388e04bbe98bfb370da40ac1b.png

 

运行结果:

77fdae00f5084c278aa3a17dcf90d0ce.png

 在测试一组数据

db72b369826f483bb18fc01509eded88.png

运行结果:

28bb8ef83c4d4de0bcdf1b71e65c26d7.png

同时SLErase也能进行复用 。

SeqList.c

尾删

94a24dfc7b6840e7960b1a3550ef0142.png

头删

9ad8c1fa29d640a79f699d5cd22e7d78.png

 

Test.c 

不用改,直接运行结果是一样的。

 

修改pos位置的值

SeqList.h

2b4c1c12738e48eab8a94ac0fb2ff16b.png

SeqList.c

32d2263b405b40739d801d54d1f21720.png

Test.c

c6e8e8e17eff4286924b324f1d2a7687.png

运行结果:

1da92ed43fa8423d87864080695d7509.png

在测试一组数据:

d53561da142a44d3a43f172ca974ad86.png

运行结果:

cf88f72413254a8ba24374c15ecae72f.png

 

有人问这样子该不是也可以吗?为什么要用Modify这个函数呢,不直接访问这个结构体不好吗?

4b913f0211c2475093a7f33ade598e4e.png

数据结构这里有个原则,不要去轻易的访问数据,会带来恶果。

比如:

213831b7da0f418ca169497d5de5fd0d.png

c9b9bfd3b6514da586fd24adb8321e0f.png

输入的是错误的数据它竟然不会报错。

如果用的是Modify就会报错

9e50549a4c82453ebed1c6347b052597.png

abd653022f194a79bafbfc9cc1c73646.png

 

数据结构有个原则,哪怕再简单的操作都要去调用我们提供的函数去解决 ,因为每个函数里都有检查,函数用的不对会有更好的检查。这也是C语言的缺陷。

 

这里还有个小问题,还有个检查一直都没有做。

如果数据结构写出来给别人用。

你舍友用你这个程序的时候这么用

4a740a3709fc412ba0951b05c458117f.png

夸夸夸写了几百上千行代码运行时发现不对调试的时候看到是空指针

b67dea7b81644f808bad5192313405d6.png

我们写这个设计这个代码的逻辑是整体而言,我们认为传了结构体指针给你但是我认为结构体的空间是外面开好的,不管是malloc还是直接定义一个对象结构体变量,我认为结构体是开好的,而不是只传一个指针给我,我是不帮你开空间的。所以你无论如何都不能传个空指针给我,我们可以用暴力检查把这种方式规避一下,这样就不用去调试阶段找错误,错了一定不能传这个空指针。所以暴力检查都加上,一出错就告诉你你传错了。加入更多的检查是更好的。

95ded78e2b414c0a9611d5fd94be3f58.png

这是运行的时候就会报错。

 

这样修改就没有问题了

30b7d2577f4845f9b32c63096e3ac08b.png

 

 

Destroy也不要忘记,不然越界了都检查不出来,一般越界在Destroy中 free 的时候才会检查。

总代码: 

 SeqList.h

#pragma once

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>

//静态顺序表
//#define N 100
//typedef int SLDataType;//1.加了这里
//struct SeqList
//{
//	SLDataType a [N];//2.这里也要跟着改
//	int size;
//};

//动态顺序表
typedef int SLDataType;
// 顺序表的动态存储
typedef struct SeqList
{
	SLDataType *a;	//指向动态开辟的数组  
	int size;		//存储有效数据个数
	int capacity;	//容量空间大小
}SL;

//管理数据 -- 增删查改
// 顺序表初始化
void SLInit(SL *ps);

// 检查空间,如果满了,进行增容
void SLCheckCapacity(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);

// 顺序表查找
int SLFind(SL* ps, SLDataType x);

//在pos位置插入x
void SLInsert(SL* ps, int pos, SLDataType x);

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

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

SeqList.c 

#define  _CRT_SECURE_NO_WARNINGS 1

#include"SeqList.h"

void SLInit(SL* ps)
{
	assert(ps);
	ps->a = (SLDataType*)malloc(sizeof(SLDataType) * 4);
	if (ps->a == NULL)//这里
	{
		perror("malloc failed");
		exit(-1);
	}

	ps->size = 0;
	ps->capacity = 4;
}

void SLDestroy(SL* ps)
{
	assert(ps);

	free(ps->a);
	ps->a = NULL;

	ps->size = 0;
	ps->capacity = 0;
}

void SLPrint(SL* ps)
{
	assert(ps);

	int i = 0;
	for (i = 0; i < ps->size; i++)
	{
		printf("%d ", ps->a[i]);
	}
	printf("\n");
}

void SLCheckCapacity(SL* ps)
{
	assert(ps);

	//满了要扩容
	if (ps->size == ps->capacity)
	{
		SLDataType* tmp = (SLDataType*)realloc(ps->a, ps->capacity * 2 * (sizeof(SLDataType)));
		if (tmp == NULL)
		{
			perror("realloc failed");
			exit(-1);
		}

		ps->a = tmp;
		ps->capacity *= 2;
	}
}

void SLPushBack(SL* ps, SLDataType x)
{
	assert(ps);

	//SLCheckCapacity(ps);
	//ps->a[ps->size] = x;
	//ps->size++;

	SLInsert(ps, ps->size, x);
}

void SLPopBack(SL* ps)
{
	assert(ps);

	//温柔的检查
	//if (ps->size == 0)
	//{
	//	return;
	//}

	//暴力检查
	//assert(ps->size>0);//犯了错误直接报错

	ps->a[ps->size - 1] = 0;
	//ps->size--;

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

}

void SLPushFront(SL* ps, SLDataType x)
{
	assert(ps);

	//SLCheckCapacity(ps);

	挪动一下数据,从后往前挪。
	//int end = ps->size - 1;
	//while (end >= 0)
	//{
	//	ps->a[end + 1] = ps->a[end];
	//	end--;
	//}

	//ps->a[0] = x;
	//ps->size++;

	SLInsert(ps, 0, x);

}

void SLPopFront(SL* ps)
{
	//assert(ps->size>0);
	从前往后挪动
	//int begin = 1;
	//while (begin < ps->size)
	//{
	//	ps->a[begin - 1] = ps->a[begin];
	//	begin++;
	//}

	//ps->size--;

	SLErase(ps, 0);
}

int SLFind(SL* ps, SLDataType x)
{
	for (int i = 0; i < ps->size; i++)
	{
		if (ps->a[i] == x)
		{
			return i;
		}
	}

	return -1;
}

//在pos位置插入x
void SLInsert(SL* ps, int pos, SLDataType x)
{
	assert(ps);

	assert(pos >= 0 && pos <= ps->size);
	SLCheckCapacity(ps);

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

	ps->a[pos] = x;
	ps->size++;
}

//删除pos位置的值
void SLErase(SL* ps, int pos)
{
	assert(ps);

	assert(pos >= 0 && pos < ps->size);

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

	ps->size--;
}

void SLModify(SL* ps, int pos, SLDataType x)
{
	assert(ps);

	assert(pos >= 0 && pos < ps->size);

	ps->a[pos] = x;

Test.c

 

void TestSeqList1()
{
	SL s1;
	SLInit(&s1);
	SLPushBack(&s1, 1);
	SLPushBack(&s1, 2);
	SLPushBack(&s1, 3);
	SLPushBack(&s1, 4);
	SLPushBack(&s1, 5);
	SLPushBack(&s1, 0);
	SLPushBack(&s1, 0);

	SLPrint(&s1);

	SLPopBack(&s1);
	SLPopBack(&s1);
	SLPrint(&s1);

	//SLPopBack(&s1);
	//SLPopBack(&s1);
	//SLPopBack(&s1);
	//SLPopBack(&s1);
	//SLPopBack(&s1);
	//SLPopBack(&s1);
	//SLPopBack(&s1);
	//SLPopBack(&s1);
	//SLPrint(&s1);

	SLPushBack(&s1, 1);
	SLPushBack(&s1, 2);
	SLPrint(&s1);

	SLDestroy(&s1);

}

void TestSeqList2()
{
	SL s1;
	SLInit(&s1);
	SLPushBack(&s1, 1);
	SLPushBack(&s1, 2);
	SLPushBack(&s1, 3);
	SLPushBack(&s1, 4);
	SLPrint(&s1);

	SLPushFront(&s1, 10);
	SLPushFront(&s1, 20);
	SLPushFront(&s1, 30);
	SLPushFront(&s1, 40);
	SLPrint(&s1);

	SLDestroy(&s1);

}

void TestSeqList3()
{
	SL s1;
	SLInit(&s1);
	SLPushBack(&s1, 1);
	SLPushBack(&s1, 2);
	SLPushBack(&s1, 3);
	SLPushBack(&s1, 4);
	SLPushBack(&s1, 5);
	SLPrint(&s1);

	SLPopFront(&s1);
	SLPopFront(&s1);
	SLPrint(&s1);

	SLPopFront(&s1);
	SLPopFront(&s1);
	SLPopFront(&s1);
	SLPopFront(&s1);
	SLPrint(&s1);

	SLPushBack(&s1, 1);
	SLPushBack(&s1, 2);
	SLPrint(&s1);

	SLDestroy(&s1);
}

void TestSeqList4()
{
	SL s1;
	SLInit(&s1);
	SLPushBack(&s1, 1);
	SLPushBack(&s1, 2);
	SLPushBack(&s1, 3);
	SLPushBack(&s1, 4);
	SLPushBack(&s1, 5);
	SLPushFront(&s1, -1);
	SLPushFront(&s1, -2);
	SLPrint(&s1);

	SLInsert(&s1, 3, 40);
	SLPrint(&s1);

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

	SLPrint(&s1);

	SLDestroy(&s1);
}

void TestSeqList5()
{
	SL s1;
	SLInit(&s1);
	SLPushBack(&s1, 1);
	SLPushBack(&s1, 2);
	SLPushBack(&s1, 3);
	SLPushBack(&s1, 4);
	SLPushBack(&s1, 5);
	SLPrint(&s1);

	SLErase(&s1, 2);
	SLPrint(&s1);

	int x;
	scanf("%d", &x);
	int pos = SLFind(&s1, x);
	if (pos != -1)
	{
		SLErase(&s1, pos);
	}

	SLPrint(&s1);

	SLDestroy(&s1);

}

void TestSeqList6()
{
	SL s1;
	SLInit(&s1);
	SLPushBack(&s1, 1);
	SLPushBack(&s1, 2);
	SLPushBack(&s1, 3);
	SLPushBack(&s1, 4);
	SLPrint(&s1);

	SLModify(&s1, 2, 20);
	s1.a[2] = 20;

	SLPrint(&s1);

	//int x;
	//scanf("%d", &x);
	//int pos = SLFind(&s1, x);
	//if (pos != -1)
	//{
	//	//SLModify(&s1, pos, x * 10);
	//	s1.a[pos] = x * 10;
	//}

	int pos;
	int x;
	scanf("%d%d", &pos, &x);
	//s1.a[pos] = x;
	SLModify(&s1, pos, x * 10);

	SLPrint(&s1);

	SLDestroy(&s1);


}

void TestSeqList7()
{
	//SL *s1 = NULL;
	//SLInit(s1);
	//SLPushBack(s1, 1);
	//SLPushBack(s1, 2);
	//SLPushBack(s1, 3);
	//SLPushBack(s1, 4);
	//SLPushBack(s1, 5);
	//SLPrint(s1);

	SL s1;
	SLInit(&s1);
	SLPushBack(&s1, 1);
	SLPushBack(&s1, 2);
	SLPushBack(&s1, 3);
	SLPushBack(&s1, 4);
	SLPrint(&s1);

	SLDestroy(&s1);

}

int main()
{
	TestSeqList7();

	return 0;
}

//int main()
//{
//	SLTNode* n1 = (SLTNode*)malloc(sizeof(SLTNode));
//	n1->data = 10;
//
//	SLTNode* n2 = (SLTNode*)malloc(sizeof(SLTNode));
//	n2->data = 20;
//
//	SLTNode* n3 = (SLTNode*)malloc(sizeof(SLTNode));
//	n3->data = 30;
//
//	n1->next = n2;
//	n2->next = n3;
//	n3->next = NULL;
//
//	PrintSList(n1);
//
//	return 0;
//}

  

有时候我们觉得写个菜单形式nb一点

菜单形式 

8d7a8772c95347279379b9a30f628abf.png

也就是有什么方式能帮助我们输入-1? 

3a5e0a1e7063412e8ee9793c72b798c6.png

这个样子写能在逻辑上控制。 

可以加在Test.c中

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

int main()
{
	SL s1;
	SLInit(&s1);
	int input = 0;
	do
	{
		menu();
		scanf("%d", &input);

		if (input == 1)
		{
			//printf("请依次输入你要插入的数据, 以-1结尾\n");

			printf("请依次输入你要插入的数据个数和数据\n");
			int n = 0;
			scanf("%d", &n);

			int x = 0;
			int i = 0;
			for (i = 0; i < n; i++)
			{
				scanf("%d", &x);
				SLPushBack(&s1, x);
			}
		}

		else if (input == 2)
		{
			SLPopFront(&s1);
		}

		else if (input == 7)
		{
			SLPrint(&s1);
		}

	} while (input != -1);

	SLDestroy(&s1);
	return 0;
}

//数据结构不太需要菜单,
//先单个测,写好了再写菜单

 后边可以自己去完善。记得先单个测试,写好了再写菜单,不然一运行一片红都不知道从哪里下手。

 

一定要多练,厉害的神枪手都是子弹喂出来的,程序员也是如此。

 

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

No more cages

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值