顺序表--数据结构第一关

顺序表

数据结构概念

定义:数据结构是计算机存储、组织数据的⽅式

根据学过C语言的基础上,数组是最简单的数据结构

顺序表的底层就是数组

为什么呢?

例子如下:

int arr[100]={1,2,3,4,5};
//修改某一个数据:arr[pos]=x;
//插入一个元素:找到数组已有元素,再进行插入数据
//删除一个元素,找到数组已有元素,再进行删除数据    

这个情况还是我们可见的情况下,如果说是好多数组要进行这样的操作,或者很大的未知大小的数组要进行如下的操作,是不是特别麻烦

顺序表说:我虽然底层是数组,但是我提供了很多现成的方法,开箱即用,我就变成了一个很厉害的数据结构。

数组和顺序表的对比

数组(苍蝇馆子)顺序表(米其林)
炒土豆丝豪华金丝(炒土豆丝+摆盘)
蔬菜汤西湖牛肉羹(蔬菜+水+摆盘)

由此可以形象地表现出顺序表:在数组的基础上增加了增删改查的方法

顺序表也是一种线性表

线性表是具有相同性质的数据结构的集合

初步理解

蔬菜分为绿叶类、⽠类、菌菇类。

水果有:香蕉,苹果,菠萝。。。。

那线性表是具有相同性质的数据结构的集合具体表现在哪两个方面呢?

(1):物理结构:不一定连续

​ (2):逻辑结构:连续的

如图所示:

在这里插入图片描述

这个是物理结构上的理解

逻辑结构就是我们通常所认为的理解。

打个比方,我们去商店购物:如果是比较火的店就需要排队

在这里插入图片描述

右边那串像葡萄一样的,可以抽象理解为一个连续的结构,再来看数组,数组是连续存放的,我们可以通过指针的方式,去访问数组里面的元素,所以数组是逻辑结构上连续的

再来看顺序表

顺序表的底层是数组,所以它的物理结构和逻辑结构都是连续的

接下来做一个知识的铺垫引入:

int arr[10]={0};//定长数组
int* arr;//动态内存开辟,确定大小之后再去动态申请

顺序表的分类

静态顺序表

struct SeqList
{int arr[100];//定长数组int size;//顺序表当前有效的数据个数;
}

动态顺序表

struct SeqList
{int* arr;int size;//有效的数据个数int capcity;//空间大小}

那么这两种哪一种更好呢?

首先我们来谈静态顺序表

(1)数组大小给小了,空间不够用 :如果说开发一个APP,你只提供了能储存一万个用户信息的空间,但是这款APP,却意外的火了,现在有很多很多用户想要去注册,但是没有空间可以注册,这样子给公司造成了不小的损失。

(2)数组大小给大了,空间造成了浪费:这样子也会给公司造成了一定的损失

接着我们再来谈动态顺序表:

动态增容:譬如说只开辟了100个空间,但是我们可以动态地扩容,相较于静态顺序表来说浪费的更少了

这里我们不难得出答案:动态顺序表更好
在这里插入图片描述

在这里插入图片描述

顺序表的实现

在这里插入图片描述

这就好比一本书的目录一样,头文件就相当于是目录的作用

Seq就是 sequence 的意思,也就是顺序的意思,List顾名思义就是列表

注意这里还需要创建一个源文件作为测试用叫test.c

注意来看:

#define _CRT_SECURE_NO_WARNINGS 1
//一般不推荐写静态顺序表
//以下是动态顺序表
typedef int SLDataType;
struct SeqList
{SLDataType* arr;int size;//有效的数据大小int capacity;//空间大小
};

为什么我这里还要重新定义int ,而不是直接写int 呢?

打个比方,我们以后进了公司,有100000000行的代码涉及到了int ,这时候领导来了一句,把其中的6000行换成char,虽然我们知道编译器有一键置换的功能,但是这个功能可不能轻易使用,我们只要换其中的6000行不是所有的,所以我们要用重命名的方法来做,提高了我们的效率。

初始化和销毁

注意点:

在这里插入图片描述

来看一些代码的实现:

头文件内的:

#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
//一般不推荐写静态顺序表
//以下是动态顺序表
typedef int SLDataType;
struct SeqList
{SLDataType* arr;int size;//有效的数据大小int capacity;//空间大小
}SL;
//顺序表的初始化
void SLInit(SL* ps);
//顺序表的销毁
void SLDestory(SL* ps);
//头部插⼊删除 / 尾部插⼊删除
void SLPushBack(SL* ps, SLDataType x);
void SLPopBack(SL* ps);
void SLPushFront(SL* ps, SLDataType x);
void SLPopFront(SL* ps);

SeqList.c:

#define _CRT_SECURE_NO_WARNINGS 1
#include "SeqList.h"
void SLInit(SL *ps)
{ps->arr = NULL;ps->size = ps->capcacity = 0;
}
void SLDestory(SL* ps)
{if (ps->arr){free(ps->arr);}ps->arr = NULL;ps->size = ps->capcacity = 0;
}

test.c:

#include "SeqList.h"
int main()
void SLTest01()
{SL sl;SLInit(&sl);
}
int main()
{SLTest01();return 0;
}

尾插

对尾插的概念图解:

在这里插入图片描述

ps指向的是一个数组,X=5是我要插入的数,size是我有效的数字个数,在这幅图中有4个,capacity是指空间大小

接下来是代码的实现过程了:

这是在SeqLsit.c的内容:

//尾插
void SLPushBack(SL* ps, SLDataType x)
{//ps->arr[ps->size]=x;//++ps->size;ps->arr[ps->size++];//这行代码是将上面的两行代码变成了一行代码,//对其size进行了后置++,提高程序运行效率
}

这是在test.c的内容:

void SLTest01()
{SL sl;SLInit(&sl);//增删查改操作//测试尾插SLPushBack(&sl, 1);SLDestory(&sl);
}

但是这样做在运行的时候会出现一些问题:
当你去监视程序的时候会发现:

size和capacity为0,也就意味着没有创建顺序表去可以去接受内容

这样就给我们提了一个醒:

插入数据前先看空间够不够

代码如下:

if(ps->capacity==ps->size)

如果不够,接下来我们就要去申请空间了

申请空间就不难想到之前学过的三个有关动态开辟空间的函数:malloc,calloc,realloc

经典的三选一:我们选择realloc,因为在这三个函数中只有realloc有增容的概念,其他两个都只是开辟空间,在这里又要注意malloc和calloc的区别,calloc开辟空间的时候会对其进行初始化

接下来出现了我们的第一个问题

要申请多大的空间/一次增容多少?

在这里插入图片描述

如上图,我到底是开辟一个还是开辟n个空间呢。

直接给出结论:

增容通常是成倍数的增加,一般是2倍或3倍,但通常来说是2倍的去增容

实际上是数学推理出来的,用2或者3倍更合理

若要频繁地增容,程序运行效率大大降低

空间大小和数据个数的关系
在这里插入图片描述

从图上可以清楚地看出:空间大小和数据个数成正比的关系

以下是一些补充(感兴趣自己看,不感兴趣也无妨,不会影响学习的效率)

在数据结构中,特别是当涉及到数组这样的连续存储结构时,增容(或称为扩容)通常以倍数的形式增加,这样做的主要原因有以下几点:

  1. 减少数据移动次数:当数组需要扩容时,通常的做法是开辟一块新的、更大的内存空间,然后将原数组中的元素复制到新的内存空间中。如果每次扩容只增加少量空间,那么随着数组元素的增加,这种复制操作会频繁发生,导致时间复杂度较高。而如果以倍数形式增加容量,比如每次扩容为原来的两倍,那么虽然单次扩容时复制的元素数量较多,但复制操作的频率会大大降低,从而减少总的复制次数和时间消耗。
  2. 均摊时间复杂度为O(1):当以倍数形式扩容时,可以计算出均摊到每个元素上的复制次数是常数级别的。具体来说,假设每次扩容为原来的两倍,那么最终数组中的n个元素中,n个元素至少被复制了1次,n/2个元素至少被复制了2次,n/4个元素至少被复制了3次,以此类推。将这些复制次数相加,可以得到一个等比数列的和,其和是O(n)的。但由于这个复制次数是分摊到n个元素上的,所以均摊到每个元素上的复制次数是O(1)的。这意味着,从长期来看,每次插入或删除元素的时间复杂度是常数级别的。
  3. 空间利用率:虽然以倍数形式扩容可能会导致一定的空间浪费(因为当数组未满时就已经进行了扩容),但这种浪费是可控的,并且可以通过选择合适的扩容倍数来平衡空间利用率和性能。通常,选择2倍作为扩容倍数是一个较好的折衷方案,因为它既能保证较好的性能,又能保持相对较高的空间利用率。

综上所述,数据结构中增容以倍数的形式增加主要是为了减少数据移动次数、降低均摊时间复杂度和保持相对较高的空间利用率。

代码如下:

ps->arr = realloc(ps->arr, ps->capacity * 2*sizeof(SLDataType));

接下来我们来看我们已经写的代码:

#define _CRT_SECURE_NO_WARNINGS 1
#include "SeqList.h"
void SLInit(SL *ps)
{ps->arr = NULL;ps->size = ps->capcacity = 0;
}
void SLDestory(SL* ps)
{if (ps->arr){free(ps->arr);}ps->arr = NULL;ps->size = ps->capcacity = 0;
}
//尾插
void SLPushBack(SL* ps, SLDataType x)
{//插入前先看空间够不够if (ps->capacity == ps->size){//申请空间ps->arr = realloc(ps->arr, ps->capacity * 2*sizeof(SLDataType));}//ps->arr[ps->size]=x;//++ps->size;ps->arr[ps->size++];//这行代码是将上面的两行代码变成了一行代码,//对其size进行了后置++,提高程序运行效率
}

有没有发现什么问题呢?

	ps->size = ps->capcacity = 0;

我把空间初始化为0了,我怎么插入数据呢?

看代码如下:

//判断空间大小是否为0
// 三目表达式
int newCapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;

但是不要忘了动态申请内存可能会失败,realloc申请空间失败会怎样呢?

里面会变成NULL.

例子如下:
在这里插入图片描述

还是来看这幅图:

如果这幅图我要插入的数据大于它所能存储的空间范围呢,那样子不就全都没了,竹篮打水一场空

来看代码的实现:

	SLDataType*tmp = realloc(ps->arr, ps->newCapacity * 2*sizeof(SLDataType));if (tmp == NULL){perror("realloc fail!");exit(1);}//空间申请成功ps->arr = tmp;ps->capacity = newCapacity;

我先去判断是否为空,这里还要注意我用了*tmp去接收内容。tmp是临时变量,以防数据丢失

再来看一个坑:

在test.c文件中:

#include "SeqList.h"
int main()
void SLTest01()
{SL sl;SLInit(&sl);//增删查改操作//测试尾插SLPushBack(&sl, 1);SLPushBack(&sl, 2);SLPushBack(&sl, 3);SLPushBack(&sl, 4);SLPushBack(NULL, 5);//注意看这个代码SLDestory(&sl);
}
int main()
{SLTest01();return 0;
}

如果我贸然地将前面的参数变为NULL,此时我们的代码还不具有健壮性,程序会出现访问冲突的问题,此时该怎么做呢?

if (ps == NULL)
{return;
}

在插入空间前看是否为空指针。

Tip:在程序运行的时候退出码为0,证明是正常退出的,如果不为0,那就是没有正常退出

这是一种比较温柔的解决方法

下面是比较粗暴的解决方式:

#include <assert.h>
assert(ps);//等价于assert(ps!=NULL);

头插

概念图:

在这里插入图片描述

把元素插到arr[0]的位置

大体思路如下:
在这里插入图片描述

目标是打算把最后一位有效数字往后挪一位

代码如下:

void SLPushFront(SL* ps, SLDataType x)
{assert(ps);SLCheckCapacity(ps);//先让顺序表已有的数据往后挪动一位for (int i = ps->size; i > 0; i--){ps->arr[i] =ps-> arr[i - 1];//arr[1]=arr[0],最后一次情况是这样,由此来推断i的限制条件}ps->arr = x;
}

特别需要注意这里i的限制条件,我们不确定的时候可以先往下写,由写出的代码推出for循环的限制条件

接下来的一步我们要去打印顺序表:

void SLPrint(SL s)
{for (int i = 0; i < s.size; i++){printf("%d ",s.arr[i]);}printf("\n");
}

为什么这里不要取地址呢?

因为我们要取的是它的值。

但是我们去打印的时候会出现一些不太符合我们预期的结果,在头插上,这是因为有效个数没有增加:

ps->size++;

综合来看代码如下:

void SLPushFront(SL* ps, SLDataType x)
{assert(ps);SLCheckCapacity(ps);//先让顺序表已有的数据往后挪动一位for (int i = ps->size; i > 0; i--){ps->arr[i] =ps-> arr[i - 1];//arr[1]=arr[0],最后一次情况是这样,由此来推断i的限制条件ps->size++;//特别要注意了}ps->arr = x;
}

尾删

概念图

情况一:

在这里插入图片描述

情况二:

在这里插入图片描述

我们需要知道一个道理:只要写的表达式能够很好地满足增删改查数据就是好的表达式

头删

在这里插入图片描述

代码如下:

void SLPopFront(SL* ps)
{assert(ps);assert(ps->size);for (int i = 0; i < size - 2; i++){ps->arr[i] = ps->arr[i + 1];//arr[size-2]=arr[size-1];}ps->size--;
}

完整的实现过程:

SeqList.h

#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
//一般不推荐写静态顺序表
//以下是动态顺序表
typedef int SLDataType;
struct SeqList
{SLDataType* arr;int size;//有效的数据大小int capacity;//空间大小
}SL;
//顺序表的初始化
void SLInit(SL* ps);
//顺序表的销毁
void SLDestory(SL* ps);
//顺序表的打印
void SLPrint(SL s);
//头部插入删除 / 尾部插入删除
//插入
void SLPushBack(SL* ps, SLDataType x);
void SLPushFront(SL* ps, SLDataType x);
//删除
void SLPopBack(SL* ps);
void SLPopFront(SL* ps);

SeqList.c

#define _CRT_SECURE_NO_WARNINGS 1
#include "SeqList.h"
//专门封装一个函数用来检查空间是否够不够
void SLCheckCapacity(SL*ps)
{//插入前先看空间够不够if (ps->capacity == ps->size){//温柔的解决方法if (ps == NULL){return;}//判断空间大小是否为0// 三目表达式int newCapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;//申请空间SLDataType* tmp = realloc(ps->arr, ps->newCapacity * 2 * sizeof(SLDataType));if (tmp == NULL){perror("realloc fail!");exit(1);}//空间申请成功ps->arr = tmp;ps->capacity = newCapacity;}
}
void SLInit(SL *ps)
{ps->arr = NULL;ps->size = ps->capcacity = 0;
}
void SLDestory(SL* ps)
{if (ps->arr){free(ps->arr);}ps->arr = NULL;ps->size = ps->capcacity = 0;
}
//尾插
void SLPushBack(SL* ps, SLDataType x)
{assert(ps);SLCheckCapacity(ps);//ps->arr[ps->size]=x;//++ps->size;ps->arr[ps->size++]=x;//这行代码是将上面的两行代码变成了一行代码,//对其size进行了后置++,提高程序运行效率
}
void SLPushFront(SL* ps, SLDataType x)
{assert(ps);SLCheckCapacity(ps);//先让顺序表已有的数据往后挪动一位for (int i = ps->size; i > 0; i--){ps->arr[i] =ps-> arr[i - 1];//arr[1]=arr[0],最后一次情况是这样,由此来推断i的限制条件ps->size++;//特别要注意了}ps->arr = x;
}void SLPrint(SL s)
{for (int i = 0; i < s.size; i++){printf("%d ",s.arr[i]);}printf("\n");
}
void SLPopBack(SL* ps)
{assert(ps);assert(ps->size);//顺序表不为空--ps->size;
}
void SLPopFront(SL* ps)
{assert(ps);assert(ps->size);for (int i = 0; i < size - 2; i++){ps->arr[i] = ps->arr[i + 1];//arr[size-2]=arr[size-1];}ps->size--;
}

test.c

#include "SeqList.h"
int main()
void SLTest01()
{SL sl;SLInit(&sl);//增删查改操作//测试尾插SLPushBack(&sl, 1);SLPushBack(&sl, 2);SLPushBack(&sl, 3);SLPushBack(&sl, 4);//SLPushBack(NULL, 5);SLPrint(sl);SLPushFront(&sl, 6);SLPrint(sl);SLDestory(&sl);
}
int main()
{SLTest01();return 0;
}

思维导图

在这里插入图片描述
送大家一句话:如果你遇到困难的时候,证明你在走上坡路。
希望大家喜欢的博客,如有不足请大家指正!

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

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

相关文章

【Docker】docker 替换宿主与容器的映射端口和文件路径

every blog every motto: You can do more than you think. https://blog.csdn.net/weixin_39190382?typeblog 0. 前言 docker 替换宿主与容器的映射端口和文件夹 1. 正文 1.1 关闭docker 服务 systemctl stop docker1.2 找到容器的配置文件 cd /var/lib/docker/contain…

游戏爱好者将《超级马里奥64》移植到GBA掌机

GBA虽然在当年拥有多款马里奥系列游戏&#xff0c;不过你一定没有想到&#xff0c;N64的《超级马里奥64》也能被移植到这个游戏掌机。近日&#xff0c;一位名为Joshua Barretto的开发者就完成了这一挑战。 大家都知道&#xff0c;《超级马里奥64》于1996年登陆任天堂64主机&am…

入职必备-mac下载安装maven

1、Maven 下载 1.1、官网下载安装包 官网下载链接 历史版本下载&#xff1a; Index of /dist/maven/maven-3/3.8.8/binaries 注意 .bash_profile 文件中的符号可能会影响配置 1.2、解压文件 2、Maven 环境配置 2.1、Java JDK 依赖 配置 maven 环境变量需要先配置好 JDK …

第一视角:获取VC账号,是成为亚马逊供应商的全面准备与必要条件

在当今全球化、数字化的商业环境中&#xff0c;亚马逊作为全球最大的电子商务平台&#xff0c;为众多企业提供了无限的商业机会。然而&#xff0c;想要成功在亚马逊上立足&#xff0c;成为其优质供应商&#xff0c;并非易事。其中&#xff0c;VC(Vendor Central)账号&#xff0…

低空经济再获新动能!沃飞长空完成新一轮数亿元融资

当下&#xff0c;作为中国"新质生产力"代表的低空经济正在成为新的发展“风口”&#xff0c;全国各地开足马力加速入场。 低空经济有多“火”&#xff1f;政策方面&#xff0c;据不完全统计&#xff0c;已有26个省份的政府工作报告对发展低空经济作出部署&#xff1…

如何做好新闻软文宣发媒体资源筛选?

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 媒体宣传加速季&#xff0c;100万补贴享不停&#xff0c;一手媒体资源&#xff0c;全国100城线下落地执行。详情请联系胡老师。 新闻软文宣发是指企业通过创造或利用新闻事件&#xff0c…

使用k8s变更线上版本号

第一步&#xff0c;在镜像仓库中找到历史版本号 第二步&#xff0c;在rancher中在工作负载里 第三步&#xff0c;在rancher找到这个版本号&#xff0c;可以更改之前的版本号 这样就可以很方便的退回到之前的版本了

Django安装与启动

1、Django是什么&#xff1f; 基于python的Web开发框架&#xff0c;支持用户快速开发安全、可维护的网站 2、怎么安装&#xff1f; pip install Django4.2 3、如何启动&#xff1f; 不写ip和端口时候&#xff0c;默认启动http://127.0.0.1:8000/ python .\manage.py runse…

AI时代的量化金融:ChatGPT在交易中的应用与前景

文章目录 &#x1f4d1;前言一、智能量化&#xff1a;开启金融新世界二、作者简介三、本书特色四、适读人群 在数字化、智能化的时代浪潮中&#xff0c;金融领域正经历着一场前所未有的变革。传统的金融分析方法逐渐被高效、精准的量化金融与算法交易所替代&#xff0c;而人工智…

【知识】详细介绍 CUDA Samples 示例工程

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhagn.cn] 如果本文帮助到了你&#xff0c;欢迎[点赞、收藏、关注]哦~ 内容较多&#xff0c;可通过 左侧或右侧 的 目录 进行跳转。 CUDA 是“Compute Unified Device Architecture (计算统一设备架构)”的首字母缩写。CUDA…

应用案例 | Panorama SCADA:开创性的铁路电气控制系统

案例概况 客户&#xff1a;英国铁路网运营商Network Rail 合作伙伴&#xff1a;Telent Technology Services Ltd 应用&#xff1a;实现对铁路牵引电网的高效管理与精准控制 应用产品&#xff1a;宏集Panorama E2 SCADA系统 一、应用背景 英国铁路网运营商Network Rail计划…

IDEA版本推荐

推荐版本&#xff1a; IDEA 2024.1.4 下载链接&#xff1a;IDEA下载 &#xff08;下载时可以往下拖&#xff0c;选到自己想要的版本哦&#xff09; 本人由于项目开发需要&#xff0c;陆续用过几个版本的IDEA&#xff0c;包括&#xff1a; IDEA 2020.2.4 。这是在看韩顺平老师…

创意学生木工工具——木工锯床

开展创意木工课程丰富了学校的课程多样性&#xff0c;强化了实践教育&#xff0c;并实现了跨学科的融合&#xff0c;在教育理念方面&#xff0c;创意木工课程强调了学生的主体地位&#xff0c;注重了学生的全面发展&#xff0c;并倡导了实践育人的理念&#xff0c;培养学生的综…

python-18-零基础自学python 类和子类的基础练习

学习内容&#xff1a;《python编程&#xff1a;从入门到实践》第二版 知识点&#xff1a; 类&#xff0c;父类与子类的继承&#xff0c;调用函数方法等。 练习内容&#xff1a; 练习9-7&#xff1a;管理员 管理员是一种特殊的用户。编写一个名为Admin的类&#xff0c;让它继…

游泳耳机入耳式好还是骨传导好?游泳教练力荐实力卓绝的四大热款

作为一名长期致力于游泳爱好者健康与运动体验提升的专业教练&#xff0c;我深知在水中听音乐的魅力&#xff0c;同时也深知选择正确的耳机对于水上运动的重要性。近年来&#xff0c;市场上的游泳耳机类型日益丰富&#xff0c;其中入耳式和骨传导两大主流各有千秋。今天&#xf…

springcloud第4季 分布式事务seata作用服务搭建1

一 seata作用 1.1 seata简介 1.seata是一款解决分布式事务的解决方案&#xff0c;致力于在微服务架构下提供高性能和简单易用的分布式事务服务。 1.2 seata的术语 一个中心&#xff1a;全局事务id&#xff0c;xid&#xff0c;在调用服务链路的上下文中进行传播。TC(Transa…

界面控件Telerik UI for Winforms 2024 Q2新版亮点 - 发布全新的AI相关组件

Telerik UI for WinForms拥有适用Windows Forms的110多个令人惊叹的UI控件&#xff0c;所有的UI for WinForms控件都具有完整的主题支持&#xff0c;可以轻松地帮助开发人员在桌面和平板电脑应用程序提供一致美观的下一代用户体验。 本文将介绍界面组件Telerik UI for Winform…

golang项目基于gorm框架从postgre数据库迁移到达梦数据库的实践

一、安装达梦数据库 1、登录达梦数据库官网&#xff0c;下载对应系统版本的安装包。 2、下载地址为&#xff1a;https://www.dameng.com/list_103.html 3、达梦数据库对大小写敏感&#xff0c;在安装初始化数据库实例时建议忽略大小写&#xff1b;具体安装教程可参考以下博客: …

C++02 变量和基本类型

基本类型 字、字节、bit、Byte之间的关系 字 word 字节 Byte 位 bit 1字 2字节 <---> 1word 2Byte 1字节 8位 <---> 1Byte 8bit 1Byte 8bits 1KB 1024Bytes 1MB 1024KB 1GB 1024MB #include <iostream> using namespace std; int main() {/*字符…

Brand Finance Retail 100 2024

近日,全球领先的品牌价值评估咨询机构Brand Finance发布了其年度行业研究报告——《Brand Finance Retail 100 2024》。该报告深入分析了全球最有价值的零售品牌及其品牌实力,揭示了品牌价值的变化趋势和品牌强度的排名情况。报告指出,尽管许多顶级零售品牌在品牌价值上遭遇了下…