【面试官说实现一个顺序表,但听到要求后我沉默了】

news/2024/5/20 7:54:41 标签: 开发语言, 数据结构, 顺序表

在很多人心里,顺序表数据结构最基础最简单的东西了,如果面试让我们手撕一道顺序表,相信大家心里早就乐开了花,但是面试官真的会出这么简单的题吗?

 

答案是:当然会,哈哈。

我们来看看面试官的要求:

请实现下面函数的接口,并且自己安排测试用例测试:

void SLInit(SL* ps);//初始化顺序表
void SLPrint(SL* ps);//打印顺序表中有效数据
void SLPushFront(SL* ps, SLDataType x);//头插
void SLPushBack(SL* ps, SLDataType x);//尾插
void SLPopFront(SL* ps);//头删
void SLPopBack(SL* ps);//尾删
int SLFind(SL* ps, SLDataType x);//找到x数据,并返回这是顺序表中第几位,找不到就返回-1
void SLInsert(SL* ps, int pos, SLDataType x);//在表中第pos位后插入数据x
void SLErase(SL* ps, int pos);//删除表中第pos位的数据
void SLDestroy(SL* ps);//释放顺序表

很人多肯定会说,就这就这?? 这不是顺序表的基操吗,有手就行

 但是面试官接着说了一句话:

你能在20分钟内完成吗?你能够保证你的代码鲁棒性很好吗?

大家或许对于20min的概念不是特别强烈,20min实现上面10个函数的接口,并且还要自己测试代码是否有问题,20min内完成,平均每个接口不能超过2min,这还不算测试用例。如果还想让其规范性更高,分成3个文件是避免不了的(   text.c(测试接口功能 )     SeqList.c(接口的定义)   SeqList.h(头文件,接口的声明等等)    ),我自己测试了下,大概用了40多min(我太菜了,各位佬不要喷我)

下面是我实现接口的定义:SeqList.c

#define _CRT_SECURE_NO_WARNINGS 1

#include"SeqList.h"

void SLCheckCapacity(SL* ps)
{
	assert(ps);
	int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
	SL* tmp = (SL*)realloc(ps->a, newCapacity * sizeof(SLDataType));
	if (!tmp)
	{
		printf("realloc fail\n");
		exit(-1);
	}
	ps->a = tmp;
	ps->capacity = newCapacity;
}

void SLInit(SL* ps)
{
	assert(ps);
	ps->a = NULL;
	ps->capacity = ps->size = 0;
}

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

void SLPushFront(SL* ps, SLDataType x)
{
	assert(ps);
	SLCheckCapacity(ps);
	int end = ps->size;
	while (end > 0)
	{
		ps->a[end] = ps->a[end - 1];
		end--;
	}
	ps->a[end] = x;
	ps->size++;
}

void SLPushBack(SL* ps, SLDataType x)
{
	assert(ps);
	SLCheckCapacity(ps);
	ps->a[ps->size] = x;
	ps->size++;
}

void SLPopFront(SL* ps)
{
	assert(ps);
	assert(ps->size > 0);
	int begin = 0;
	while (begin < ps->size-1)
	{
		ps->a[begin] = ps->a[begin + 1];
		begin++;
	}
	ps->size--;
}

void SLPopBack(SL* ps)
{
	assert(ps);
	assert(ps->size > 0);
	ps->size--;
}

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


void SLInsert(SL* ps, int pos, SLDataType x)
{
	assert(ps);
	if (pos > ps->size)
	{
		printf("无法插入\n");
		return;
	}
	SLCheckCapacity(ps);
	int end = ps->size;
	while (end > pos)
	{
		ps->a[end] = ps->a[end - 1];
		end--;
	}
	ps->a[end] = x;
	ps->size++;
}

void SLErase(SL* ps, int pos)
{
	assert(ps);
	assert(ps->size > 0);
	int begin = pos;
	while (begin < ps->size)
	{
		ps->a[begin - 1] = ps->a[begin];
		begin++;
	}
	ps->size--;
}

void SLDestroy(SL* ps)
{
	assert(ps);
	
	ps->a = NULL;
	ps->capacity = ps->size = 0;
	free(ps);
}

至于测试接口的功能每个人有不同的写法,鄙人的愚见是写一个测一个,出了问题方便及时修改,不然等到一起测试时程序奔溃了那可就要了老命了。另外测试时要尽可能的考虑所有情况,想删除数据时万一表中已经没有了数据应该怎么办?在第几位插入或者删除数据时输入的位置是否有效等等都应该是我们所考虑的。

回到上文,我们要怎样做才能将时间缩短到20min内呢?

这种像我一样硬来的话或许够呛(大佬请自动忽略),那有什么更好的办法吗?

我们发现在第几位删除插入数据好像也能够完成头删尾删头插尾插,举个栗子:

我们想尾插数据,不就是想在最后一位插入数据吗?那我们只要实现了随机插入的接口,头插尾插不也就是间接实现了吗?删除数据也同理。

有了这样的思路后我们不妨来试试写:

void SLInsert(SL* ps, int pos, SLDataType x)
{
	assert(ps);
	if (pos > ps->size)
	{
		printf("无法插入\n");
		return;
	}
	SLCheckCapacity(ps);
	int end = ps->size;
	while (end > pos)
	{
		ps->a[end] = ps->a[end - 1];
		end--;
	}
	ps->a[end] = x;
	ps->size++;
}

void SLErase(SL* ps, int pos)
{
	assert(ps);
	assert(ps->size > 0);
	int begin = pos;
	while (begin < ps->size)
	{
		ps->a[begin - 1] = ps->a[begin];
		begin++;
	}
	ps->size--;
}

void SLPushFront(SL* ps, SLDataType x)
{
	SLInsert(ps, 0, x);
}

void SLPushBack(SL* ps, SLDataType x)
{
	SLInsert(ps, ps->size, x);

}

void SLPopFront(SL* ps)
{
	SLErase(ps, 1);
}

void SLPopBack(SL* ps)
{
	SLErase(ps, ps->size);
}

实现了SLInsert和SLErase这两个接口后实现头插尾插头删尾删就变得容易多了,能够节省很多时间,我又重新测试了一下大概花了20多min(可能是对函数接口不太熟悉的原因,我真的尽力了)

如果大佬有更好的方法,欢迎在评论区提出。

 


http://www.niftyadmin.cn/n/1088.html

相关文章

链路状态路由协议 OSPF (二)

作者简介&#xff1a;一名在校云计算网络运维学生、每天分享网络运维的学习经验、和学习笔记。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;网络豆的主页​​​​​​ 目录 前言 一.Router ID 1.什么是Router ID 2.获得Router ID方法 二.DR和…

全球名校AI课程库(28)| MIT麻省理工 · 基因组学机器学习课程『Machine Learning for Genomics』

&#x1f3c6; 课程学习中心 | &#x1f6a7; AI生物医疗课程合辑 | &#x1f30d; 课程主页 | &#x1f4fa; 中英字幕视频 | &#x1f680; 项目代码解析 课程介绍 MIT 6.047/6.878是全球顶校麻省理工开设的基因组学与机器学习的交叉专业课程。课程以基因组学为主要应用领域…

强化学习论文分析3---蜂窝网络联合频谱和功率分配的深度强化学习--《Deep Reinforcement Learning for ......》

目录一、研究内容概述二、系统目标与约束1.系统描述2.系统目标三、DQN、DDPG网络设计四、性能表征本文是对论文《Deep Reinforcement Learning for Joint Spectrum and Power Allocation in Cellular Networks》的分析&#xff0c;若需下载原文请依据前方标题搜索&#xff0c;第…

《CTF攻防世界web题》之茶壶我爱你(2)

前言 &#x1f340;作者简介&#xff1a;被吉师散养、喜欢前端、学过后端、练过CTF、玩过DOS、不喜欢java的不知名学生。 &#x1f341;个人主页&#xff1a;被吉师散养的职业混子 &#x1fad2;文章目的&#xff1a;记录唯几我能做上的题 &#x1f342;相应专栏&#xff1a;CT…

linux篇【8】:基础IO—<后序>

目录 一.myshell中实现重定向 1.myshell中实现重定向 二.标准输出与标准错误 小知识点&#xff1a;linux下的c后置——.cpp / .cc / .cxx 1. 示例解释 ./a. out > stdout. txt 解释&#xff1a; ./a.out 1> stdout. txt 2>stderr. txt 解释&#xff1a; ./a.out…

QtApplets-QTextToSpeechDemo

QtApplets-QTextToSpeechDemo 哎呀妈呀&#xff0c;这个系列应该有好长一段时间没有更细了&#xff0c;因为啥呢&#xff0c;主要是因为这一段时间都在折腾Debian 10 下的软件开发&#xff0c;都是在调试代码&#xff0c;实在是没有啥新功能需要试验的&#xff0c;有的也是在L…

举个栗子~Tableau 技巧(242):学做 条形图 和 桑基图 的组合图表

在应用模板&#xff1a;超市数据分析模型 中&#xff0c;产品分析仪表板&#xff08;如下图&#xff09;的右侧视图呈现出&#xff1a;各类别及其子类别产品的销售总额排列——各类别产品的销售总额、子类别的销售额占比。 许多数据粉希望学习这个图表的实现方法。其实&#…

java基础10题

1.abstract和final可以同时作为一个类的修饰符。&#xff08; &#xff09; A.正确 B,错误 2.有以下类定义&#xff1a; abstract class Animal{abstract void say(); } public class Cat extends Animal{public Cat(){System.out.printf("I am a cat");}public sta…