假如面试官让你十分钟完成双向循环链表

news2025/1/22 21:58:53

 

  • 💌 博客内容:假如面试官让你十分钟完成双向循环链表,多一秒都不行

  • 😀 作  者:陈大大陈

  • 🚀 个人简介:一个正在努力学技术的准前端,专注基础和实战分享 ,欢迎私信!

  • 💖 欢迎大家:这里是CSDN,我总结知识和写笔记的地方,喜欢的话请三连,有问题请私信 😘 😘 😘

改进前 

 要是我问你会不会写双向循环链表,那你一定会不假思索的回答——我当然会。

但如果我让你十分钟之内完成它呢?

那你可能就会犹豫了,十分钟!?双向循环链表那么多的功能,怎么是10分钟能写完的东西呢?

如果你这样想了,那就请听我缓缓道来吧!

#define _CRT_SECURE_NO_WARNINGS
#include"List.h"

LTNode* BuyLTNode(LTDataType x)
{
	LTNode* newnode = (LTNode*)malloc(sizeof(LTNode));
	if (newnode == NULL)
	{
		perror("malloc fail");
		return NULL;
	}

	newnode->data = x;
	newnode->next = NULL;
	newnode->prev = NULL;
	return newnode;
}

LTNode* LTInit()
{
	LTNode* phead = BuyLTNode(-1);
	phead->next = phead;
	phead->prev = phead;

	return phead;
}

void LTPrint(LTNode* phead)
{
	assert(phead);

	printf("guard<==>");
	LTNode* cur = phead->next;
	while (cur != phead)
	{
		printf("%d<==>", cur->data);
		cur = cur->next;
	}
	printf("\n");
}

bool LTEmpty(LTNode* phead)
{
	assert(phead);

	return phead->next == phead;
}

void LTPushBack(LTNode* phead, LTDataType x)
{
	assert(phead);

	LTNode* tail = phead->prev;
	LTNode* newnode = BuyLTNode(x);

	tail->next = newnode;
	newnode->prev = tail;
	newnode->next = phead;
	phead->prev = newnode;
}



void LTPushFront(LTNode* phead, LTDataType x)
{
	assert(phead);
	LTNode* newnode = BuyLTNode(x);
	LTNode* first = phead->next;

	phead->next = newnode;
	newnode->prev = phead;

	newnode->next = first;
	first->prev = newnode;

}

void LTPopBack(LTNode* phead)
{
	assert(phead);
	assert(!LTEmpty(phead));
	LTErase(phead->prev);

}

void LTPopFront(LTNode* phead)
{
	assert(phead);
	assert(!LTEmpty(phead));

	LTNode* next = phead->next;


	phead->next = next->next;
	next->next->prev = phead;
	free(next);
}


LTNode* LTFind(LTNode* phead, LTDataType x)
{
	assert(phead);

	LTNode* cur = phead->next;
	while (cur != phead)
	{
		if (cur->data == x)
		{
			return cur;
		}

		cur = cur->next;
	}

	return NULL;
}

// 在pos之前插入
void LTInsert(LTNode* pos, LTDataType x)
{
	assert(pos);

	LTNode* prev = pos->prev;
	LTNode* newnode = BuyLTNode(x);

	// prev newnode pos
	prev->next = newnode;
	newnode->prev = prev;
	newnode->next = pos;
	pos->prev = newnode;
}

// 删除pos位置的值
void LTErase(LTNode* pos)
{
	assert(pos);

	LTNode* posPrev = pos->prev;
	LTNode* posNext = pos->next;

	posPrev->next = posNext;
	posNext->prev = posPrev;
	free(pos);
}

void LTDestroy(LTNode* phead)
{
	assert(phead);

	LTNode* cur = phead->next;
	while (cur != phead)
	{
		LTNode* next = cur->next;
		free(cur);
		cur = next;
	}


	free(phead);
}

如图,我们第一时间想到的恐怕就是这样的写法,又臭又长。

面试中你如果打算这么写代码,那恐怕10分钟确实不太够。

简化冗杂的代码

为了尽可能地减少代码量,让我们能在10分钟内打出来,我们需要发掘其中可以简化的部分。

头插和尾插的代码可以直接用LTInsert函数来实现。

反正头插和尾插也不过是LTInsert函数在头部和尾部的实现而已。

紧接着就是头删和尾删,同理,它们也不过是LTErase函数在头部和尾部的实现而已。

实现之后大概就是这个样子


#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef struct Node
{
	int data;
	struct Node* next;
	struct Node* prev;
}Node;
Node* BuyListNode(int x);
Node* SLInit();
void LTPopFront(Node* phead);
void LTPushFront(Node* phead, int x);
void LTPopBack(Node* phead);
void LTDestroy(Node* phead);
void LTPushBack(Node* phead, int x);
void LTErase(Node* phead);
void LTInsert(Node* pos, int x);
int LTEmpty(Node* phead);
void Print(Node* phead);
Node* BuyListNode(int x)
{

	Node* newnode = (Node*)malloc(sizeof(Node));
	newnode->data = x;
	newnode->next = NULL;
	newnode->prev = NULL;
	return newnode;
}
Node* SLInit()
{
	Node* phead = BuyListNode(-1);
	phead->next = phead;
	phead->prev = phead;
	return phead;
}

void LTInsert(Node* pos, int x)
{
	assert(pos);
	Node* newnode = BuyListNode(x);
	Node* prev = pos->prev;
	newnode->next = prev->next;
	newnode->prev = prev;
	prev->next = newnode;
	pos->prev = newnode;
}
void LTPushFront(Node* phead, int x)
{
	assert(phead);
	LTInsert(phead->next, x);
}
void LTPushBack(Node* phead, int x)
{
	assert(phead);
	LTInsert(phead, x);
}
void LTPopFront(Node* phead)
{
	assert(phead);
	assert(!LTEmpty(phead));
	LTErase(phead->prev);
}
void LTErase(Node* pos)
{
	assert(pos);
	Node* prev = pos->prev;
	Node* next = pos->next;
	prev->next = next;
	next->prev = prev;

}
void LTPopBack(Node* phead)
{
	assert(phead);
	assert(!LTEmpty(phead));
	LTErase(phead->prev);
}
void LTDestroy(Node* phead)
{
	assert(phead);
	Node* cur = phead->next;
	while (phead != cur)
	{
		Node* next = cur->next;
		free(cur);
		cur = next;
	}
	free(phead);

}
int LTEmpty(Node* phead)
{
	assert(phead);
	return phead == phead->next;
}
void Print(Node* phead)
{
	Node* cur = phead->next;
	while (cur != phead)
	{
		Node* next = cur->next;
		printf("%d<==>", cur->data);
		cur = next;
	}
	printf("\n");
}

这样的代码量,我勉强能在10分钟之内打完,大家就更不用说了,5分钟足矣。

只要大家勤加练习,让面试官目瞪口呆指日可待!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/522058.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

大前端技能讲解:NodeJS、Npm、Es6、Webpack

文章目录 1. 基础概述2. Nodejs2.1 Nodejs 了解和快速入门2.2 Nodejs 实现 Httpserver 服务&#xff08;实现请求响应&#xff09;2.3 Nodejs 操作 MySQL 数据库 3. ES63.1 ES6 的概述3.2 ES6 的语法&#xff1a;let 和 const 命令3.3 ES6 的语法&#xff1a;模板字符串3.4 ES6…

基于SSM的在线电影购票系统设计与实现【附源码】

基于SSM的在线电影购票系统设计与实现 互联网的不断迅猛发展&#xff0c;每个行业都在寻找新的机会&#xff0c;都在从传统的人工方式向先进的信息化过度。随着人民生活水平的提高伴随的精神文化层次的享受&#xff0c;而现代互联网时代人们的重要精神消费之一是电影行业&…

NAS +AList实现云盘映射(本地硬盘扩容大法)

准备工具&#xff1a; 1&#xff09;Alist的docker &#xff1a;xhofe/alist 2&#xff09;RailDrive软件 安装&#xff1a; 1&#xff09;安装alist的docker 注意一定要给读写权限&#xff0c;装载路径和我一样 端口一般和容器端口一致 环境变量 网络桥接就行 记得勾选自…

【Prompting】ChatGPT Prompt Engineering开发指南(1)

ChatGPT Prompt Engineering开发指南1 Prompting指南设置 提示原则策略1&#xff1a;使用分隔符清楚地指示输入的不同部分策略2&#xff1a;要求结构化输出策略3&#xff1a;让模型检查条件是否满足策略4: “Few-shot”提示 原则2&#xff1a;给模型时间“思考”策略1&#xff…

idea新建springboot项目并提交码云仓库

新建springboot项目 平常我们在使用联网方式新建springboot项目时总是会遇到连接失败等这种情况 IDEA创建项目&#xff0c;本质是从官网创建并下载项目&#xff0c;然后导入本地。 创建项目连接失败&#xff0c;一般是外国网站的原因导致连接超时&#xff0c;解决方式很简单&a…

C++linux高并发服务器项目实践 day11

Clinux高并发服务器项目实践 day11 线程同步互斥锁死锁读写锁读写锁相关操作函数 生产者消费者模型条件变量信号量 线程同步 线程的主要优势在于&#xff0c;能够通过全局变量来共享信息。不过&#xff0c;这种便捷的共享是有代价的:必须确保多个线程不会同时修改同一变量&…

LabVIEWCompactRIO 开发指南17 网络流

LabVIEWCompactRIO 开发指南17 网络流 网络流类似于队列函数&#xff0c;因为它们是基于FIFO的&#xff0c;但与队列函数不同的是&#xff0c;网络流具有网络作用域。它们是为通过以太网进行无损、高吞吐量数据通信而设计和优化的&#xff0c;并且它们具有增强的连接管理功能…

Springboot +Flowable,各种历史信息如何查询(三)

一.简介 正在执行的流程信息是保存在以 ACT_RU_ 为前缀的表中&#xff0c;执行完毕的流程信息则保存在以 ACT_HI_ 为前缀的表中&#xff0c;也就是流程历史信息表。 假设有一个流程&#xff0c;流程图如下&#xff1a; 当这个流程执行完毕后&#xff0c;以 ACT_RU_ 为前缀的…

学习新技术,争做新青年:请ChatGPT帮我写一篇计算机视觉分类算法论文

文章目录 学习新技术&#xff0c;争做新青年&#xff1a;你不会还不用 ChatGPT 吧&#xff1f;学习新技术请告诉我最好的图像分类模型是哪个请推荐最新的分类模型是哪个请详细介绍一下 Swin Transformer请给出Swin Transformer的论文链接请帮我分析一下Swin Transformer 的创新…

Java实现多线程操作多账户

前言 某公司一个面试题&#xff1a; 1.有二十个账户&#xff0c;每个账户初始余额10000元。 2.有十个转账线程&#xff0c;对二十个账户中的两个随机选取账户进行转账&#xff0c;转账额度100以内正整数随机数。 3.每个线程执行100次转账操作。 4.最后请打印出二十个账户的…

西门子PLC控制步进电机方法与接线(全)

一、步进驱动系统 步进驱动系统包含步进电动机和步进驱动器&#xff0c;前端由PLC发脉冲。 步进电机是将电脉冲信号转变为角位移或线位移以控制转子转动的开环控制电机&#xff08;可以通过安装编码器形成闭环系统&#xff09;。 它旋转是以固定的角度&#xff08;步距角&…

ThinkPHP6的控制器定义及控制器初使用

ThinkPHP6的控制器定义及控制器初使用 控制器定义 控制器文件通常放在controller下面&#xff0c;类名和文件名保持大小写一致&#xff0c;并采用驼峰命名&#xff08;首字母大写&#xff09;。 如果要改变controller目录名&#xff0c;需要在route.php(config/route.php)配…

redis从零开始(1)----五种基本类型:string/hash

认识redis NoSQL Nosql not only sql&#xff0c;泛指非关系型数据库&#xff0c;与之相对的是RDBMS(Relational Database Management System)&#xff0c;即关系型数据库 关系型数据库&#xff1a;列行&#xff0c;同一个表下数据的结构是一样的。 非关系型数据库&#xff…

原生js手动实现一个多级菜单效果(高度可过渡变化)

文章目录 学习链接效果图代码要点 学习链接 vue实现折叠展开收缩动画 - 自己的链接 elment-ui/plus不定高度容器收缩折叠动画组件 - 自己的链接 Vue transition 折叠类动画自动获取隐藏层高度以及手风琴效果实现 vue transition动画钩子- vue官网 vue transition 过渡动画…

vue基础入门

1. vue简介 1.1 什么是vue 官方概念&#xff1a;Vue&#xff08;读音/vju:/&#xff0c;类似于view&#xff09;是一套用于构建用户界面的前端框架 1.2 vue 的特性 vue 框架的特性&#xff0c;主要体现在如下两方面&#xff1a; ① 数据驱动视图 ② 双向数据绑定 数据驱动…

IMS补充业务场景介绍

呼叫保持流程 通话主动Hold的一方,发INVITE消息,媒体流从sendrecv变为sendonly,对方返回200 ok,媒体流从sendrecv变为recvonly,双方ACK后,进入呼叫保持状态,没有通话的RTP包。 大致流程如下 UE A发送INVITE(Sendonly)到网络 网络发送INVITE(Sendonly)到UE B UE发…

Linux文件属性修改

关于我们的文件属性如何修改呢&#xff1f; 我们今天来看一下 chmod chmod u(拥有者)/g(所属组)/o(其他人)(-)r/w/x(t) 文件名 就是这样&#xff0c;我们演示几个 我们想给拥有者去掉file1的读权限 我们file1的拥有者已经没有读权限了&#xff0c;那么我们还想加回来呢…

asp.net+C#基于web的旅游网站自驾游网站

&#xff08;1&#xff09;登录注册模块&#xff1a;输入账号密码&#xff0c;数据库进行验证&#xff0c;正确通过后&#xff0c;根据不同的账户信息&#xff0c;不同角色&#xff0c;获取不同的功能。 &#xff08;2&#xff09;自驾游模块&#xff1a;此模块可以分享自己自…

《计算机网络—自顶向下方法》 第五章Wireshark实验:UDP 协议分析

用户数据报(UDP)协议是运输层提供的一种最低限度的复用/分解服务&#xff0c;可以在网络层和正确的用户即进程间传输数据。UDP 是一种不提供不必要服务的轻量级运输协议&#xff0c;除了复用/分用功能和简单的差错检测之外&#xff0c;几乎就是 IP 协议了&#xff0c;也可以说它…

Python操作Redis常见类型详解

1、windows 上安装 Redis 便于测试&#xff0c;笔者在 windows 上安装 Redis Redis 官方不建议在 windows 下使用 Redis&#xff0c;所以官网没有 windows 版本可以下载。微软团队维护了开源的 windows 版本&#xff0c;对于普通测试使用足够了。 1.1、安装包方式安装 Redis…