草庐IT

史上最详细的改良顺序表讲解,看完不会你打我

陈大大陈 2023-04-14 原文

目录

0.什么是顺序表

1.顺序表里结构体的定义

2.顺序表的初始化

3.顺序表的输入

4.增加顺序表的长度

5.1顺序表的元素查找(按位查找)

5.2顺序表的元素查找(按值查找)在顺序表进行按值查找,大概只能通过遍历的方式,这也算是顺序表的缺点吧!

6.顺序表的元素插入

7.顺序表的元素删除

8.顺序表的打印

9.求顺序表的表长

10.顺序表的销毁

11.运行结果 

 12.全部代码

0.什么是顺序表

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

  • 顺序表:可动态增长的数组,要求数据是连续存储的

1.顺序表里结构体的定义

typedef struct SList
{
	int length;
	int MaxSize;
	int* data;
}SList;

length为当前顺序表长度 MaxSize是顺序表最大长度 ,* data是定义顺序表中元素类型的数组指针

2.顺序表的初始化

#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include<string.h>
#define InitSize 10

void InitSList(SList& L)
{
	L.data = (int*)malloc(sizeof(int) * InitSize);
	if (L.data == NULL)
	{
		printf("%s\n",strerror(errno));
	}
	L.length = 0;
	L.MaxSize = InitSize;
}

需要注意的是,malloc函数的返回的是无类型指针,在使用时一定要强制转换为所需要的类型。在使用malloc函数开辟的空间中,不能进行指针的移动,因为一旦移动之后可能出现申请的空间和释放空间大小的不匹配。

我们使用malloc函数申请大小为InitSize个字节的空间,成功申请会返回指向所申请空间的指针,如果申请失败会返回空指针NULL。

可能会空间开辟失败的情况,我们加上strerror函数。

strerror函数会返回错误码所对应的错误信息,返回值是一个指向描述错误的字符串的指针。

要使用它的话,必须包含errno.h这个头文件。

  • 每一个这样的错误码都对应着一个错误信息,sterror函数能把错误码所对应错误信息的首字符的地址返回。
  • 当C语言的库函数调用失败的时候,会将一个错误码存放在一个叫errno的变量中。
  • 当我们想知道调用库函数的时候发生了什么错误信息,就可以将errno中的错误码翻译成错误信息。

如图,当我们所要的空间太大,初始化失败时

 它会提示空间不够。

3.顺序表的输入

void WriteSList(SList& L)
{
	printf("请输入你要创建的顺序表的长度:>");
	scanf("%d", &L.length);
	printf("请输入你要创建的顺序表的元素:>");
	for (int j = 0; j < L.length; j++)
	{
		scanf("%d", &L.data[j]);
	}
}

这一部分没有什么好说的,我们先输入长度再将每个元素输入就行。

4.增加顺序表的长度

我们定义一个*p指针来指向原顺序表的地址,之后再使用malloc函数来开辟一块更大的空间,空间大小由我们来定义,再将*p指向的值,也就是原顺序表的内容挨个赋值给新的顺序表,最后将原来的空间删除即可。不要忘记让p指向空指针哦!

void IncreaseSize(SList& L)
{
	int len;
	int* p = L.data;
	printf("请输入你要增加的长度:>");
	scanf("%d", &len);
	L.data = (int*)malloc(sizeof(int) * (L.MaxSize+len));
	for (int i = 0; i < L.length; i++)
	{
		L.data[i] = p[i];
	}
	L.MaxSize = L.MaxSize + len;
	free(p);
    p=NULL;
}

5.1顺序表的元素查找(按位查找)

按位查找直接通过数组下标即可。 

bool GetElem(SList& L)
{
	int i;
	printf("你要找第几个元素:>");
	scanf("%d", &i);
	if (i<1 || i>L.length)
	{
		return false;
	}
	printf("第%d个元素是%d\n", i, L.data[i - 1]);
	return true;
}

布尔型(bool)变量的值只有 真 (true) 和假 (false)。一般将非零值看做true,将零值看做false。使用布尔型可以增加代码的可读性。

5.2顺序表的元素查找(按值查找)
在顺序表进行按值查找,大概只能通过遍历的方式,这也算是顺序表的缺点吧!

顺序表按值查找的时间复杂度为:O(n),效率比较低。

void LocateElem(SList& L)
{
	int e, i, k=1;
	printf("请输入你要查找的元素:>");
	scanf("%d", &e);
	for (i = 0; i < L.length; i++)
	{
		if (e == L.data[i])
		{
			k = 0;	
			printf("找到了,是第%d个元素\n", i + 1);
			break;
		}
	}
	if (k)
	{
		printf("找不到该元素\n");
	}
}

6.顺序表的元素插入

将顺序表元素的插入类比成为我们排队,当有一个人想要插入一个中间的位置时,后面的人一定会因为插队的人而后移一位。倒数第二个人会到原先倒数第一人的位置,而原先倒数第一的那个人会后移一位,所以最后表长会加一。

需要判断的有两点:

1.顺序表的空间是否够用。

2.所插入的位置是否合法,有没有越界。

bool InsertSList(SList& L)
{
	int i, e;
	printf("请输入要插入的位置和元素:>");
	scanf("%d%d", &i, &e);
	if (i<1 || i>L.length)
	{
		return false;
	}
	if (L.length > L.MaxSize)
	{
		return false;
	}
	for (int j = L.length; j >= i; j--)
	{
		L.data[j] = L.data[j - 1];
	}
	L.data[i - 1] = e;
	L.length++;
	printf("插入的元素是%d,插入的位置是%d\n", e, i);
	return true;
}

我们同样使用布尔型,在以上两种情况时返回一个false值。

让插入位置之后的元素挨个后移,在腾出的位置插入要插入的元素,返回一个true值。

7.顺序表的元素删除

依旧可以用排队的例子来说,队伍中有一个人有事要走,那么他的位置就会空出来,这时候他后面的人就要挨个向前一位来补齐这个位置。当然,最后表长会减一。

bool DeleteSList(SList& L)
{
	int i,j,e;
	printf("请输入你要删除的元素位置:>");
	scanf("%d", &i);
	if (i<1 || i>L.length)
	{
		return false;
	}
	if (!L.data)
	{
		return false;
	}
	e = L.data[i-1];
	
	for (j = i; j <= L.length;j++)
	{
		L.data[j-1] = L.data[j];
	}
	L.length--;
	printf("删除的元素是%d,它的位置是%d\n",e, i);
	return true;
}

8.顺序表的打印

首先判断表是否为空表,是空表时返回一个false。

bool PrintSList(SList &L)
{
	if (!L.data)
	{
		return false;
	}
	printf("数组里的元素有:>");
	for (int i = 0; i < L.length; i++)
	{
		printf("%d ", L.data[i]);
	}
	printf("\n");
	return true;
}

9.求顺序表的表长

int GetLength(SList& L)
{
	if (L.length == 0)
	{
		return 0;
	}
		return L.length;
}

10.顺序表的销毁

getchar的使用是很关键的,用来接收前面的回车,如果不加的话之后的scanf将会直接被跳过。

就如上篇博客所说,malloc开辟的空间是在堆区的,这片空间需要程序员主动去释放,不然会导致内存泄露的问题。大家感兴趣可以看看上篇博客。

我眼中的‘C’——动态内存+柔型数组_陈大大陈的博客-CSDN博客

void DestroySList(SList& L)
{
	char c;
	getchar();
	printf("是否销毁顺序表(Y/N):>");
	scanf("%s", &c);
	if (c == 'Y')
	{
		L.length = 0;
		L.MaxSize = 0;
		free(L.data);
        L.data=NULL;
		printf("顺序表已销毁\n");
	}
}

11.运行结果 

 12.全部代码

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include<string.h>
#define InitSize 10
typedef struct SList
{
	int length;
	int MaxSize;
	int* data;
}SList;
void InitSList(SList& L)
{
	L.data = (int*)malloc(sizeof(int) * InitSize);
	if (L.data == NULL)
	{
		perror("malloc");
	}
	L.length = 0;
	L.MaxSize = InitSize;
}
void WriteSList(SList& L)
{
	printf("请输入你要创建的顺序表的长度:>");
	scanf("%d", &L.length);
	printf("请输入你要创建的顺序表的元素:>");
	for (int j = 0; j < L.length; j++)
	{
		scanf("%d", &L.data[j]);
	}
}
void IncreaseSize(SList& L)
{
	int len;
	int* p = L.data;
	printf("请输入你要增加的长度:>");
	scanf("%d", &len);
	L.data = (int*)malloc(sizeof(int) * (L.MaxSize+len));
	for (int i = 0; i < L.length; i++)
	{
		L.data[i] = p[i];
	}
	L.MaxSize = L.MaxSize + len;
	free(p);
	p = NULL;
}
bool GetElem(SList& L)
{
	int i;
	printf("你要找第几个元素:>");
	scanf("%d", &i);
	if (i<1 || i>L.length)
	{
		return false;
	}
	printf("第%d个元素是%d\n", i, L.data[i - 1]);
	return true;
}
void LocateElem(SList& L)
{
	int e, i, k=1;
	printf("请输入你要查找的元素:>");
	scanf("%d", &e);
	for (i = 0; i < L.length; i++)
	{
		if (e == L.data[i])
		{
			k = 0;	
			printf("找到了,是第%d个元素\n", i + 1);
			break;
		}
	}
	if (k)
	{
		printf("找不到该元素\n");
	}
}
bool InsertSList(SList& L)
{
	int i, e;
	printf("请输入要插入的位置和元素:>");
	scanf("%d%d", &i, &e);
	if (i<1 || i>L.length)
	{
		return false;
	}
	if (L.length > L.MaxSize)
	{
		return false;
	}
	for (int j = L.length; j >= i; j--)
	{
		L.data[j] = L.data[j - 1];
	}
	L.data[i - 1] = e;
	L.length++;
	printf("插入的元素是%d,插入的位置是%d\n", e, i);
	return true;
}
bool DeleteSList(SList& L)
{
	int i,j,e;
	printf("请输入你要删除的元素位置:>");
	scanf("%d", &i);
	if (i<1 || i>L.length)
	{
		return false;
	}
	if (!L.data)
	{
		return false;
	}
	e = L.data[i-1];
	
	for (j = i; j <= L.length;j++)
	{
		L.data[j-1] = L.data[j];
	}
	L.length--;
	printf("删除的元素是%d,它的位置是%d\n",e, i);
	return true;
}
bool PrintSList(SList &L)
{
	if (!L.data)
	{
		return false;
	}
	printf("数组里的元素有:>");
	for (int i = 0; i < L.length; i++)
	{
		printf("%d ", L.data[i]);
	}
	printf("\n");
	return true;
}
int GetLength(SList& L)
{
	if (L.length == 0)
	{
		return 0;
	}
		return L.length;
}
void DestroySList(SList& L)
{
	char c;
	getchar();
	printf("是否销毁顺序表(Y/N):>");
	scanf("%s", &c);
	if (c == 'Y')
	{
		L.length = 0;
		L.MaxSize = 0;
		free(L.data);
		L.data = NULL;
		printf("顺序表已销毁\n");
	}
}
int main()
{
	SList L;
	InitSList(L);
	WriteSList(L);
	PrintSList(L);
	IncreaseSize(L);
	InsertSList(L);
	PrintSList(L);
	DeleteSList(L);
	PrintSList(L);
	GetElem(L);
	LocateElem(L);
	int len = GetLength(L);
	printf("顺序表的长度是%d\n", len);
	DestroySList(L);
	return 0;
}

 这篇博客旨在总结我自己阶段性的学习,要是能帮助到大家,那可真是三生有幸!如果觉得我写的不错的话还请点个赞和关注哦~我会持续输出编程的知识的!😘😘😘

有关史上最详细的改良顺序表讲解,看完不会你打我的更多相关文章

  1. ruby - Highline 询问方法不会使用同一行 - 2

    设置:狂欢ruby1.9.2高线(1.6.13)描述:我已经相当习惯在其他一些项目中使用highline,但已经有几个月没有使用它了。现在,在Ruby1.9.2上全新安装时,它似乎不允许在同一行回答提示。所以以前我会看到类似的东西:require"highline/import"ask"Whatisyourfavoritecolor?"并得到:Whatisyourfavoritecolor?|现在我看到类似的东西:Whatisyourfavoritecolor?|竖线(|)符号是我的终端光标。知道为什么会发生这种变化吗? 最佳答案

  2. ruby-on-rails - 项目升级后 Pow 不会更改 ruby​​ 版本 - 2

    我在我的Rails项目中使用Pow和powifygem。现在我尝试升级我的ruby​​版本(从1.9.3到2.0.0,我使用RVM)当我切换ruby​​版本、安装所有gem依赖项时,我通过运行railss并访问localhost:3000确保该应用程序正常运行以前,我通过使用pow访问http://my_app.dev来浏览我的应用程序。升级后,由于错误Bundler::RubyVersionMismatch:YourRubyversionis1.9.3,butyourGemfilespecified2.0.0,此url不起作用我尝试过的:重新创建pow应用程序重启pow服务器更新战俘

  3. ruby - Chef 执行非顺序配方 - 2

    我遵循了教程http://gettingstartedwithchef.com/,第1章。我的运行list是"run_list":["recipe[apt]","recipe[phpap]"]我的phpapRecipe默认Recipeinclude_recipe"apache2"include_recipe"build-essential"include_recipe"openssl"include_recipe"mysql::client"include_recipe"mysql::server"include_recipe"php"include_recipe"php::modul

  4. 世界前沿3D开发引擎HOOPS全面讲解——集3D数据读取、3D图形渲染、3D数据发布于一体的全新3D应用开发工具 - 2

    无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD

  5. 在VMware16虚拟机安装Ubuntu详细教程 - 2

    在VMware16.2.4安装Ubuntu一、安装VMware1.打开VMwareWorkstationPro官网,点击即可进入。2.进入后向下滑动找到Workstation16ProforWindows,点击立即下载。3.下载完成,文件大小615MB,如下图:4.鼠标右击,以管理员身份运行。5.点击下一步6.勾选条款,点击下一步7.先勾选,再点击下一步8.去掉勾选,点击下一步9.点击下一步10.点击安装11.点击许可证12.在百度上搜索VM16许可证,复制填入,然后点击输入即可,亲测有效。13.点击完成14.重启系统,点击是15.双击VMwareWorkstationPro图标,进入虚拟机主

  6. ruby-on-rails - 在 RSpec 中,如何以任意顺序期望具有不同参数的多条消息? - 2

    RSpec似乎按顺序匹配方法接收的消息。我不确定如何使以下代码工作:allow(a).toreceive(:f)expect(a).toreceive(:f).with(2)a.f(1)a.f(2)a.f(3)我问的原因是a.f的一些调用是由我的代码的上层控制的,所以我不能对这些方法调用添加期望。 最佳答案 RSpecspy是测试这种情况的一种方式。要监视一个方法,用allowstub,除了方法名称之外没有任何约束,调用该方法,然后expect确切的方法调用。例如:allow(a).toreceive(:f)a.f(2)a.f(1)

  7. ruby-on-rails - 使用 javascript 更改数据方法不会更改 ajax 调用用户的什么方法? - 2

    我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的

  8. ruby-on-rails - prawnto 显示新页面时不会中断的表格 - 2

    我有可变数量的表格和可变数量的行,我想让它们一个接一个地显示,但如果表格不适合当前页面,请将其放在下一页,然后继续。我已将表格放入事务中,以便我可以回滚然后打印它(如果高度适合当前页面),但我如何获得表格高度?我现在有这段代码pdf.transactiondopdf.table@data,:font_size=>12,:border_style=>:grid,:horizontal_padding=>10,:vertical_padding=>3,:border_width=>2,:position=>:left,:row_colors=>["FFFFFF","DDDDDD"]pdf.

  9. ruby - 按数字(从大到大)然后按字母(字母顺序)对对象集合进行排序 - 2

    我正在构建一个小部件来显示奥运会的奖牌数。我有一个“国家”对象的集合,其中每个对象都有一个“名称”属性,以及奖牌计数的“金”、“银”、“铜”。列表应该排序:1.首先是奖牌总数2.如果奖牌相同,按类型分割(金>银>铜,即2金>1金+1银)3.如果奖牌和类型相同,则按字母顺序子排序我正在用ruby​​做这件事,但我想语言并不重要。我确实找到了一个解决方案,但如果感觉必须有更优雅的方法来实现它。这是我做的:使用加权奖牌总数创建一个虚拟属性。因此,如果他们有2个金牌和1个银牌,加权总数将为“3.020100”。1金1银1铜为“3.010101”由于我们希望将奖牌数排序为最高的,因此列表按降序排

  10. ruby - 以随机顺序将数组拆分为多个数组 - Ruby - 2

    我试图在每次运行时以随机顺序将一个名称数组拆分为多个数组。我知道如何拆分它们:name_array=["bob","john","rob","nate","nelly","michael"]array=name_array.each_slice(2).to_a=>[["bob","john"],["rob","nate"],["nelly","michael"]]但是,如果我希望它每次都以随机顺序吐出它们怎么办? 最佳答案 在做同样的事情之前,打乱数组。(Array#shuffle)name_array.shuffle.each_s

随机推荐