数据结构——单链表(C语言版)
文章目录
- 一、链表的概念及结构
- 二、单链表的实现
- SList.h
- 链表的打印
- 申请新的结点
- 链表的尾插
- 链表的头插
- 链表的尾删
- 链表的头删
- 链表的查找
- 在指定位置之前插入数据
- 在指定位置之后插入数据
- 删除pos结点
- 删除pos之后的结点
- 销毁链表
- 三、完整源代码
- SList.h
- SList.c
- test.c
一、链表的概念及结构
概念:链表是 ⼀种物理存储结构上⾮连续、⾮顺序 的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的
链表的结构跟⽕⻋⻋厢相似,淡季时⻋次的⻋厢会相应减少,旺季时⻋次的⻋厢会额外增加⼏节。只需要将⽕⻋⾥的某节⻋厢去掉/加上,不会影响其他⻋厢,每节⻋厢都是独⽴存在的。
⻋厢是独⽴存在的,且每节⻋厢都有⻋⻔。
想象⼀下这样的场景,假设每节⻋厢的⻋⻔都是锁上的状态,需要不同的钥匙才能解锁,每次只能携带⼀把钥匙的情况下如何从⻋头⾛到⻋尾?
最简单的做法:每节⻋厢⾥都放⼀把下⼀节⻋厢的钥匙。
在链表⾥,每节“⻋厢”是什么样的呢?
与顺序表不同的是,链表⾥的每节"⻋厢"都是独⽴申请下来的空间,我们称之为“结点/节点”
节点的组成主要有两个部分:当前节点要保存的数据和保存下⼀个节点的地址(指针变量)。

图中指针变量plist保存的是第⼀个节点的地址,我们称plist此时“指向”第⼀个节点,如果我们希
望plist“指向”第⼆个节点时,只需要修改plist保存的内容为0x0012FFA0。
为什么还需要指针变量来保存下⼀个节点的位置?
链表中每个节点都是独⽴申请的(即需要插⼊数据时才去申请⼀块节点的空间),我们需要通过指针
变量来保存下⼀个节点位置才能从当前节点找到下⼀个节点。
结合前⾯学到的结构体知识,我们可以给出每个节点对应的结构体代码:
假设当前保存的节点为整型:
struct SListNode
{
int data; //节点数据
struct SListNode* next; //指针变量⽤保存下⼀个节点的地址
};
当我们想要保存⼀个整型数据时,实际是向操作系统申请了⼀块内存,这个内存不仅要保存整型数
据,也需要保存下⼀个节点的地址(当下⼀个节点为空时保存的地址为空)。
当我们想要从第⼀个节点⾛到最后⼀个节点时,只需要在前⼀个节点拿上下⼀个节点的地址(下⼀个
节点的钥匙)就可以了。
思考:当我们想保存的数据类型为字符型、浮点型或者其他⾃定义的类型时,该如何修改?
可以用typedef将数据类型重命名,这样方便后续修改数据类型
typedef int SLTDateType;//将int类型重命名为SLTDateType
补充说明:
1、链式机构在逻辑上是连续的,在物理结构上不⼀定连续
2、节点⼀般是从堆上申请的
3、从堆上申请来的空间,是按照⼀定策略分配出来的,每次申请的空间可能连续,可能不连续
二、单链表的实现
SList.h 单链表头文件,声明单链表,以及需要的函数
SList.c 单链表函数实现文件
test.c 测试代码
SList.h
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
//单链表
typedef int SLTDateType;
typedef struct SListNode
{SLTDateType date;struct SListNode* next;
}SLTNode;//链表的打印
void SLTPrint(SLTNode* phead);//链表的尾插
void SLTPushBack(SLTNode** pphead, SLTDateType x);//链表的头插
void SLTPushFront(SLTNode** pphead, SLTDateType x);//链表的尾删
void SLTPopBack(SLTNode** pphead);//链表的头删
void SLTPopFront(SLTNode** pphead);//链表的查找
SLTNode* SLTFind(SLTNode* phead, SLTDateType x);//在指定位置之前插入数据
void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDateType x);//在指定位置之后插入数据
void SLTInsertAfter(SLTNode* pos, SLTDateType x);//删除pos结点
void SLTErase(SLTNode** pphead, SLTNode* pos);//删除pos之后的结点
void SLTEraseAfter(SLTNode* pos);//销毁链表
void SListDesTroy(SLTNode** pphead);
链表的打印
//打印
void SLTPrint(SLTNode* phead)
{SLTNode* pcur = phead;while (pcur){printf("%d->", pcur->date);pcur = pcur->next;}printf("NULL\n");
}
申请新的结点
//申请新的结点
SLTNode* SLTBuyNode(SLTDateType x)
{SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));if (newnode == NULL){perror("malloc fail");exit(1);}newnode->date = x;newnode->next = NULL;return newnode;
}
链表的尾插
//尾插
void SLTPushBack(SLTNode** pphead, SLTDateType x)
{assert(pphead);SLTNode* newnode = SLTBuyNode(x);//空链表和非空链表if (*pphead == NULL){*pphead = newnode;}else{//找到尾结点SLTNode* ptail = *pphead;while (ptail->next){ptail = ptail->next;}ptail->next = newnode;}
}
链表的头插
//头插
void SLTPushFront(SLTNode** pphead, SLTDateType x)
{assert(pphead);SLTNode* newnode = SLTBuyNode(x);newnode->next = *pphead;*pphead = newnode;
}
链表的尾删
//尾删
void SLTPopBack(SLTNode** pphead)
{//不能为空链表assert(pphead && *pphead);//只有一个结点if ((*pphead)->next == NULL){free(*pphead);*pphead = NULL;}//有多个结点else{SLTNode* prev = *pphead;SLTNode* ptail = *pphead;while (ptail->next){prev = ptail;ptail = ptail->next;}free(ptail);ptail = NULL;prev->next = NULL;}
}
链表的头删
//头删
void SLTPopFront(SLTNode** pphead)
{assert(pphead && *pphead);SLTNode* next = (*pphead)->next;free(*pphead);*pphead = next;
}
链表的查找
//查找
SLTNode* SLTFind(SLTNode* phead, SLTDateType x)
{assert(phead);SLTNode* pcur = phead;while (pcur){if (pcur->date == x){return pcur;}pcur = pcur->next;}return NULL;
}
在指定位置之前插入数据
//在指定位置之前插入数据
void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDateType x)
{assert(pphead && *pphead);assert(pos);//在第一个结点前插入数据就是头插if (pos == *pphead){SLTPushFront(pphead, x);}else{SLTNode* newnode = SLTBuyNode(x);SLTNode* prev = *pphead;while (prev->next != pos){prev = prev->next;}newnode->next = pos;prev->next = newnode;}
}
在指定位置之后插入数据
//在指定位置之后插入数据
void SLTInsertAfter(SLTNode* pos, SLTDateType x)
{assert(pos);SLTNode* newnode = SLTBuyNode(x);newnode->next = pos->next;pos->next = newnode;
}
删除pos结点
//删除pos结点
void SLTErase(SLTNode** pphead, SLTNode* pos)
{assert(pphead && *pphead);assert(pos);//如果是头结点if (pos == *pphead){SLTPopFront(pphead);}else{SLTNode* prev = *pphead;while (prev->next != pos){prev = prev->next;}prev->next = pos->next;free(pos);pos = NULL;}
}
删除pos之后的结点
//删除pos之后的结点
void SLTEraseAfter(SLTNode* pos)
{assert(pos && pos->next);SLTNode* del = pos->next;pos->next = del->next;free(del);del = NULL;
}
销毁链表
//销毁链表
void SListDesTroy(SLTNode** pphead)
{assert(pphead && *pphead);SLTNode* pcur = *pphead;while (pcur){SLTNode* next = pcur->next;free(pcur);pcur = next;}*pphead = NULL;
}
三、完整源代码
SList.h
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
//单链表
typedef int SLTDateType;
typedef struct SListNode
{SLTDateType date;struct SListNode* next;
}SLTNode;//链表的打印
void SLTPrint(SLTNode* phead);//链表的尾插
void SLTPushBack(SLTNode** pphead, SLTDateType x);//链表的头插
void SLTPushFront(SLTNode** pphead, SLTDateType x);//链表的尾删
void SLTPopBack(SLTNode** pphead);//链表的头删
void SLTPopFront(SLTNode** pphead);//链表的查找
SLTNode* SLTFind(SLTNode* phead, SLTDateType x);//在指定位置之前插入数据
void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDateType x);//在指定位置之后插入数据
void SLTInsertAfter(SLTNode* pos, SLTDateType x);//删除pos结点
void SLTErase(SLTNode** pphead, SLTNode* pos);//删除pos之后的结点
void SLTEraseAfter(SLTNode* pos);//销毁链表
void SListDesTroy(SLTNode** pphead);
SList.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "SList.h"//打印
void SLTPrint(SLTNode* phead)
{SLTNode* pcur = phead;while (pcur){printf("%d->", pcur->date);pcur = pcur->next;}printf("NULL\n");
}//申请新的结点
SLTNode* SLTBuyNode(SLTDateType x)
{SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));if (newnode == NULL){perror("malloc fail");exit(1);}newnode->date = x;newnode->next = NULL;return newnode;
}//尾插
void SLTPushBack(SLTNode** pphead, SLTDateType x)
{assert(pphead);SLTNode* newnode = SLTBuyNode(x);//空链表和非空链表if (*pphead == NULL){*pphead = newnode;}else{//找到尾结点SLTNode* ptail = *pphead;while (ptail->next){ptail = ptail->next;}ptail->next = newnode;}
}//头插
void SLTPushFront(SLTNode** pphead, SLTDateType x)
{assert(pphead);SLTNode* newnode = SLTBuyNode(x);newnode->next = *pphead;*pphead = newnode;
}//尾删
void SLTPopBack(SLTNode** pphead)
{//不能为空链表assert(pphead && *pphead);//只有一个结点if ((*pphead)->next == NULL){free(*pphead);*pphead = NULL;}//有多个结点else{SLTNode* prev = *pphead;SLTNode* ptail = *pphead;while (ptail->next){prev = ptail;ptail = ptail->next;}free(ptail);ptail = NULL;prev->next = NULL;}
}//头删
void SLTPopFront(SLTNode** pphead)
{assert(pphead && *pphead);SLTNode* next = (*pphead)->next;free(*pphead);*pphead = next;
}//查找
SLTNode* SLTFind(SLTNode* phead, SLTDateType x)
{assert(phead);SLTNode* pcur = phead;while (pcur){if (pcur->date == x){return pcur;}pcur = pcur->next;}return NULL;
}//在指定位置之前插入数据
void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDateType x)
{assert(pphead && *pphead);assert(pos);//在第一个结点前插入数据就是头插if (pos == *pphead){SLTPushFront(pphead, x);}else{SLTNode* newnode = SLTBuyNode(x);SLTNode* prev = *pphead;while (prev->next != pos){prev = prev->next;}newnode->next = pos;prev->next = newnode;}
}//在指定位置之后插入数据
void SLTInsertAfter(SLTNode* pos, SLTDateType x)
{assert(pos);SLTNode* newnode = SLTBuyNode(x);newnode->next = pos->next;pos->next = newnode;
}//删除pos结点
void SLTErase(SLTNode** pphead, SLTNode* pos)
{assert(pphead && *pphead);assert(pos);//如果是头结点if (pos == *pphead){SLTPopFront(pphead);}else{SLTNode* prev = *pphead;while (prev->next != pos){prev = prev->next;}prev->next = pos->next;free(pos);pos = NULL;}
}//删除pos之后的结点
void SLTEraseAfter(SLTNode* pos)
{assert(pos && pos->next);SLTNode* del = pos->next;pos->next = del->next;free(del);del = NULL;
}//销毁链表
void SListDesTroy(SLTNode** pphead)
{assert(pphead && *pphead);SLTNode* pcur = *pphead;while (pcur){SLTNode* next = pcur->next;free(pcur);pcur = next;}*pphead = NULL;
}
test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "SList.h"
//测试代码
void test1()
{SLTNode* s1 = (SLTNode*)malloc(sizeof(SLTNode));s1->date = 1;SLTNode* s2 = (SLTNode*)malloc(sizeof(SLTNode));s2->date = 2;SLTNode* s3 = (SLTNode*)malloc(sizeof(SLTNode));s3->date = 3;SLTNode* s4 = (SLTNode*)malloc(sizeof(SLTNode));s4->date = 4;s1->next = s2;s2->next = s3;s3->next = s4;s4->next = NULL;//测试打印SLTNode* plist = s1;SLTPrint(plist);
}void test2()
{SLTNode* s = NULL;SLTPrint(s);//测试尾插SLTPushBack(&s, 2);SLTPushBack(&s, 3);SLTPushBack(&s, 4);SLTPrint(s);//测试头插/*SLTPushFront(&s, 8);SLTPushFront(&s, 7);SLTPushFront(&s, 6);SLTPrint(s);*///测试尾删/*SLTPopBack(&s);SLTPrint(s);SLTPopBack(&s);SLTPrint(s);SLTPopBack(&s);SLTPrint(s);SLTPopBack(&s);SLTPrint(s);*///测试头删/*SLTPopFront(&s);SLTPrint(s);SLTPopFront(&s);SLTPrint(s);SLTPopFront(&s);SLTPrint(s);SLTPopFront(&s);SLTPrint(s);*///测试查找/*SLTNode* find = SLTFind(s, 40);if (find != NULL){printf("找到了!\n");}else{printf("没有找到!\n");}*///测试在指定位置之前插入数据/*SLTNode* find = SLTFind(s, 3);SLTInsert(&s, find, 8);SLTPrint(s);*///测试在指定位置之后插入数据/*SLTNode* find = SLTFind(s, 2);SLTInsertAfter(find, 8);SLTPrint(s);*///删除pos结点/*SLTNode* find = SLTFind(s, 2);SLTErase(&s, find);SLTPrint(s);*///删除pos之后的结点/*SLTNode* find = SLTFind(s, 3);SLTEraseAfter(find);SLTPrint(s);*///链表的销毁SListDesTroy(&s);SLTPrint(s);
}int main()
{//test1();test2();return 0;
}
相关文章:
数据结构——单链表(C语言版)
文章目录 一、链表的概念及结构二、单链表的实现SList.h链表的打印申请新的结点链表的尾插链表的头插链表的尾删链表的头删链表的查找在指定位置之前插入数据在指定位置之后插入数据删除pos结点删除pos之后的结点销毁链表 三、完整源代码SList.hSList.ctest.c 一、链表的概念及…...
:app debug:armeabi-v7a failed to configure C/C++
报错信息 由于刚换电脑不久,新建native c工程时,出现报错如下: :app debug:armeabi-v7a failed to configure C/C null java.lang.NullPointerExceptionat com.android.build.gradle.tasks.CmakeQueryMetadataGenerator.getProcessBuilder(…...
计算机网络——应用层(4)DHCP和套接字编程
一、动态主机配置协议DHCP 1、关于协议配置: 在协议软件中,给协议参数赋值的动作就叫协议配置一个协议软件在使用前必须已被正确配置,具体的配置信息取决于协议栈连接到互联网的计算机的协议软件需要正确配置的参数包括①IP地址;…...
TF-IDF演算法(Term Frequency - Inverse Document Frequency)最好懂筆記
前情提要 BoW (Bag of Words) 演算法 假设现在有M篇文章,一共使用了N个词汇(term),我们就可以将文章转换成以下类型的矩阵,其中column1和row1的“10”表示“文章1”中出现了10次“词汇1”,“文章1”也可以…...
2024年4月最新版GPT
2024年4月最新版ChatGPT/GPT4, 附上最新的使用教程。 随着人工智能技术的不断发展,ChatGPT和GPT4已经成为了人们日常生活中不可或缺的助手。2024年4月,OpenAI公司推出了最新版本的GPT4,带来了更加强大的功能和更加友好的用户体验。本文将为大家带来最新版GPT4的实用…...
机器学习——模型评价
概述 在机器学习中,模型评价是评估和比较不同模型性能的关键步骤之一。它是通过对模型的预测结果与真实标签进行比较,从而量化模型的预测能力、泛化能力和稳定性。模型评价旨在选择最佳的模型,理解模型的行为,并为模型的改进提供…...
ARP代理
10.1.0.1/8 和10.2.0.1/8是在同一个网段 10.1.0.2/16 和10.2.0.2/16 不在同一个网段 10.1.0.1/8 和10.1.0.2/16 是可以ping通的 包发出来了,报文有发出来,目的地址是广播包 广播请求,发到路由器的接口G 0/0/0 target不是本接口࿰…...
手写前端控制并发任务
思路: 主要通过异步等待队列执行的原理。 当前执行的任务数达到最大值的时候,再继续执行的任务会放入等待队列里,直到当前任务执行结束后,减少一个当前任务数,并且判断队列中是否有任务,如果有则按顺序执…...
好用的Python开发工具合集
Python是一种功能强大且易于学习的编程语言,被广泛应用于数据科学、机器学习、Web开发等领域。随着Python在各个领域的应用越来越广泛,越来越多的Python开发工具也涌现出来。但是,对于新手来说,选择一款合适的Python开发工具可…...
近屿智能全新推出AI培训产品:AIGC大模型工程师与产品经理学习路径图
如今,人工智能和自然语言处理技术的发展,使得AI生成的内容(AIGC,AI Generated Content)领域开发出了巨大的潜力。就像业内巨头OpenAI公司,开发出了一系列自然语言处理模型ChatGPT,不仅带动了全世…...
Vue 3中的反向代理 和如何在服务器配置反向代理
如何在Vue 3项目中配置反向代理,让前端开发变得爽到爆!还有个小插曲,Vite为我们提供了更简单的方式,就像找对象一样直接。 首先,我们来谈谈反向代理是什么。简单来说,反向代理就像是前端和后端之间的婚姻介…...
【机器学习】贝叶斯算法在机器学习中的应用与实例分析
贝叶斯算法在机器学习中的应用与实例分析 一、贝叶斯算法原理及重要性二、朴素贝叶斯分类器的实现三、贝叶斯网络在自然语言处理中的应用四、总结与展望 在人工智能的浪潮中,机器学习以其独特的魅力引领着科技领域的创新。其中,贝叶斯算法以其概率推理的…...
回归预测 | Matlab实现SSA-GRNN麻雀算法优化广义回归神经网络多变量回归预测(含优化前后预测可视化)
回归预测 | Matlab实现SSA-GRNN麻雀算法优化广义回归神经网络多变量回归预测(含优化前后预测可视化) 目录 回归预测 | Matlab实现SSA-GRNN麻雀算法优化广义回归神经网络多变量回归预测(含优化前后预测可视化)预测效果基本介绍程序设计参考资料预测效果...
SQL SERVER的安装
目录 1.百度SQL SERVER找到图下的所显示的,点击进去 2.找到图下红色框起来的,点击立即下载 3.下载好之后点开,选择下载介质 4.SQLSERVER下载成功之后选择打开文件夹 6.双击后缀名是.iso的镜像文件 7.双击setup.exe进行安装 8.安装成功…...
(十一)C++自制植物大战僵尸游戏客户端更新实现
植物大战僵尸游戏开发教程专栏地址http://t.csdnimg.cn/cFP3z 更新检查 游戏启动后会下载服务器中的版本号然后与本地版本号进行对比,如果本地版本号小于服务器版本号就会弹出更新提示。让用户选择是否更新客户端。 在弹出的更新对话框中有显示最新版本更新的内容…...
关于Qt主窗口的菜单部件
前言 在介绍主窗口的两大部件之前,我们要先知道关于主窗口的一些知识。 主窗口 一个主窗口可以没有菜单条、工具条、状态条,但必须设置中心部件。在 Q 生成的 C头文件 ui_mainwindow.h 代码中,我们可以看到以下代码: centralWidget new Qwidget(MainWi…...
rabbitmq每小时自动重启
引言 找了半天,最后通过系统日志发现是因为执行 systemctl restart rabbitmq-server 命令无法返回回调 systemctl 导致超时,自动关机。怀疑是 rabbitmq 与 systemctl 冲突,后 mq 升级版本已修复,可参考:https://github…...
【多线程】单例模式 | 饿汉模式 | 懒汉模式 | 指令重排序问题
文章目录 单例模式一、单例模式1.饿汉模式2.懒汉模式(单线程)3.懒汉模式(多线程)改进 4.指令重排序1.概念2.question:3.解决方法4总结: 单例模式 一、单例模式 单例,就是单个实例 在有些场景中,…...
00_Qt概述以及如何创建一个QT新项目
Qt概述 1.Qt概述1.1 什么是Qt1.2 Qt的发展史1.3 支持的平台1.4 Qt版本1.5 Qt的下载与安装1.6 Qt的优点 2.QT新项目创建3.pro文件4.主函数5.代码命名规范和快捷键 1.Qt概述 1.1 什么是Qt Qt是一个跨平台的C图形用户界面应用程序框架。它为应用程序开发者提供建立艺术级图形界面…...
git报错
这里写自定义目录标题 git报错Permission denied (publickey). fatal: Could not read from remote repository. Please make sure you have the correct access rights and the repository exists. 有一个原因就是在github上设置对应密钥时,有一个key获取应该设置为…...
【杂谈】-递归进化:人工智能的自我改进与监管挑战
递归进化:人工智能的自我改进与监管挑战 文章目录 递归进化:人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管?3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...
浅谈不同二分算法的查找情况
二分算法原理比较简单,但是实际的算法模板却有很多,这一切都源于二分查找问题中的复杂情况和二分算法的边界处理,以下是博主对一些二分算法查找的情况分析。 需要说明的是,以下二分算法都是基于有序序列为升序有序的情况…...
css3笔记 (1) 自用
outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size:0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格ÿ…...
Fabric V2.5 通用溯源系统——增加图片上传与下载功能
fabric-trace项目在发布一年后,部署量已突破1000次,为支持更多场景,现新增支持图片信息上链,本文对图片上传、下载功能代码进行梳理,包含智能合约、后端、前端部分。 一、智能合约修改 为了增加图片信息上链溯源,需要对底层数据结构进行修改,在此对智能合约中的农产品数…...
return this;返回的是谁
一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请,不同级别的经理有不同的审批权限: // 抽象处理者:审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...
push [特殊字符] present
push 🆚 present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中,push 和 present 是两种不同的视图控制器切换方式,它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...
GO协程(Goroutine)问题总结
在使用Go语言来编写代码时,遇到的一些问题总结一下 [参考文档]:https://www.topgoer.com/%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/goroutine.html 1. main()函数默认的Goroutine 场景再现: 今天在看到这个教程的时候,在自己的电…...
4. TypeScript 类型推断与类型组合
一、类型推断 (一) 什么是类型推断 TypeScript 的类型推断会根据变量、函数返回值、对象和数组的赋值和使用方式,自动确定它们的类型。 这一特性减少了显式类型注解的需要,在保持类型安全的同时简化了代码。通过分析上下文和初始值,TypeSc…...
比较数据迁移后MySQL数据库和OceanBase数据仓库中的表
设计一个MySQL数据库和OceanBase数据仓库的表数据比较的详细程序流程,两张表是相同的结构,都有整型主键id字段,需要每次从数据库分批取得2000条数据,用于比较,比较操作的同时可以再取2000条数据,等上一次比较完成之后,开始比较,直到比较完所有的数据。比较操作需要比较…...
OD 算法题 B卷【正整数到Excel编号之间的转换】
文章目录 正整数到Excel编号之间的转换 正整数到Excel编号之间的转换 excel的列编号是这样的:a b c … z aa ab ac… az ba bb bc…yz za zb zc …zz aaa aab aac…; 分别代表以下的编号1 2 3 … 26 27 28 29… 52 53 54 55… 676 677 678 679 … 702 703 704 705;…...
