数据结构-数组(详细讲解)

文章目录

    • 数组
      • 数组的概述
      • 数组的图示
        • 一维数组
        • 二维数组
      • 数组的定义
        • 一维数组的定义
        • 二维数组的定义
      • 数组的取值赋值
        • 一维数组
        • 二维数组
      • 数组的操作
        • 一维数组的操作
          • 索引实现
          • 指针实现
        • 二位数组的操作
          • 矩阵转三元组
          • 矩阵的乘法

数组

数组的概述

  • 概述:数组是一种线性数据结构,它由一组按顺序排列的元素组成。每个元素都有一个唯一的索引,用于访问和操作该元素。数组可以包含任意类型的数据,如整数、浮点数、字符串等
  • 注意:数组是只能存储一种数据类型,且数组一旦创建,大小就固定的容器。
  • 优缺点:
    • 数组的优点,快速访问和搜索速度,因为元素的位置是固定的,可以通过索引直接访问
    • 数组的缺点,插入和删除操作可能会导致大量元素的移动,从而影响性能,并且数组的大小一旦创建就是固定的
  • 种类:
    • 一维数组
    • 二维数组(二维数组其实就是多维数组,像一个表格一样)
    • 多维数组

数组的图示

一维数组

二维数组
  • 二维数组可以看成一个表格,下边就是一个4行3列的二维数组

  • 二维数组也可以看成一维数组中嵌套一维数组的样式,下边图也是一个 4行3列的二维数组

数组的定义

一维数组的定义
  • 格式

    // 格式一
    数据类型 数组名[长度];
    // 格式二
    数据类型 数组名[长度] = {1,2...值n};
    // 格式三
    数据类型 数组名[] = {1,2...值n};
    
  • 示例

    // 定义一个长度为 5 的整型数组
    int a[5];
    // 定义一个长度为 5 的整型数组,并初始化(初始化就是赋值的意思)
    int b[5] = {1,2,3,4,5};
    // 定义一个整型数组,并初始化,可以看到方括号中并无长度,是因为初始化列表自动推断数组的大小
    int c[] = {1,2,3,4,5};
    
二维数组的定义
  • 格式

    // 格式一
    数据类型 数组名[行数][列数];
    // 格式二
    数据类型 数组名[行数][列数] = {{1,2...值n},{1,2...值n},...,{1,2...值n}};
    // 格式三
    数据类型 数组名[][列数] = {{1,2...值n},{1,2...值n},...,{1,2...值n}};
    
  • 示例

    // 定义一个3行4列的整型二维数组
    int a[3][4];
    // 定义一个3行4列的整型二维数组,并初始化
    int b[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
    // 初始化列表自动推断数组是多少行
    int c[][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
    

数组的取值赋值

一维数组
#include <stdio.h>					// 打印需要靠这个 标准输入输出库

int main() {
    // 定义一个一维数组
    int arr[] = {1, 2, 3, 4, 5};

    // 访问数组中的元素
    printf("%d\n", arr[0]);  // 输出:1
    printf("%d\n", arr[2]);  // 输出:3

    // 修改数组中的元素
    arr[3] = 6;
    for (int i = 0; i < 5; i++) {
        printf("%d ", arr[i]);  // 输出:1 2 3 6 5
    }

    // 获取数组的长度
    int length = sizeof(arr) / sizeof(arr[0]);
    printf("\n%d\n", length);  // 输出:5

    return 0;
}
二维数组
#include <stdio.h>

int main() {
    // 定义一个二维数组
    int arr2d[3][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};

    // 访问二维数组中的元素
    printf("%d\n", arr2d[0][0]);  // 输出:1
    printf("%d\n", arr2d[1][2]);  // 输出:6

    // 修改二维数组中的元素
    arr2d[2][1] = 10;
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            printf("%d ", arr2d[i][j]);  // 输出:1 2 3 4 5 6 7 10 9
        }
    }

    // 获取二维数组的行数和列数
    int rows = sizeof(arr2d) / sizeof(arr2d[0]);
    int cols = sizeof(arr2d[0]) / sizeof(arr2d[0][0]);
    printf("\n%d %d\n", rows, cols);  // 输出:3 3

    return 0;
}

数组的操作

一维数组的操作
索引实现
#include <stdio.h>

// 使用索引进行操作
void arrayOperationsWithIndex(int arr[], int size) {
    // 插入操作,insertIndex 是要插入的位置,insertValue 是要插入的值
    int insertIndex = 2;
    int insertValue = 10;
    // 将插入位置之后的元素依次向后移动
    for (int i = size - 1; i >= insertIndex; i--) {
        arr[i + 1] = arr[i];
    }
    // 插入元素
    arr[insertIndex] = insertValue;
    // 改变数组长度
    size++;

    // 删除操作
    int deleteIndex = 3;
    // 将 deleteIndex 之后的元素依次前移,覆盖
    for (int i = deleteIndex; i < size - 1; i++) {
        arr[i] = arr[i + 1];
    }
    size--;

    // 修改操作
    int modifyIndex = 1;
    int newValue = 20;
    arr[modifyIndex] = newValue;

    // 查找操作
    int target = 20;
    int found = 0;
    for (int i = 0; i < size; i++) {
        if (arr[i] == target) {
            printf("元素 %d 找到了,索引为 %d\n", target, i);
            found = 1;
            break;
        }
    }
    if (!found) {
        printf("未找到元素 %d\n", target);
    }
}
int main() {
    int arr1[10] = {1, 2, 3, 4, 5};
    int size1 = 5;

    // 使用索引进行操作
    arrayOperationsWithIndex(arr1, size1);

    return 0;
}
指针实现
#include <stdio.h>
// 使用指针进行操作
void arrayOperationsWithPointer(int *arr, int *size) {
    // 插入操作
    int insertIndex = 2;
    int insertValue = 10;
    for (int i = *size - 1; i >= insertIndex; i--) {
        *(arr + i + 1) = *(arr + i);
    }
    *(arr + insertIndex) = insertValue;
    (*size)++;

    // 删除操作
    int deleteIndex = 3;
    for (int i = deleteIndex; i < *size - 1; i++) {
        *(arr + i) = *(arr + i + 1);
    }
    (*size)--;

    // 修改操作
    int modifyIndex = 1;
    int newValue = 20;
    *(arr + modifyIndex) = newValue;

    // 查找操作
    int target = 20;
    int found = 0;
    for (int i = 0; i < *size; i++) {
        if (*(arr + i) == target) {
            printf("元素 %d 找到了,索引为 %d\n", target, i);
            found = 1;
            break;
        }
    }
    if (!found) {
        printf("未找到元素 %d\n", target);
    }
}
int main() {

    int arr2[10] = {1, 2, 3, 4, 5};
    int size2 = 5;

    // 使用指针进行操作
    arrayOperationsWithPointer(arr2, &size2);

    return 0;
}
二位数组的操作
矩阵转三元组

#include <stdio.h>

// 定义矩阵的行数和列数
#define ROWS 3
#define COLS 3

// 定义矩阵转换为三元组的结构体
typedef struct Triple {
    int row;				// 行
    int col;				// 列
    int value;				// 值
}Triple;

/* 
	定义矩阵转换为三元组的函数
	参数:
		matrix[ROWS][COLS]		矩阵,用二维数组实现
		rows					矩阵行数
		cols					矩阵列数
		triple[]				三元组数组
*/
int convertToTriple(int matrix[ROWS][COLS], int rows, int cols, Triple triple[]) {
    int count = 0;
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            if (matrix[i][j] != 0) {
                /*
                	下边四行代码释义:
                		1、将不等于0元素的行值存到三元组中
                		2、将不等于0元素的列值存到三元组中
                		3、将不等于0元素的值存到三元组中
                		4、行数加1
                */
                triple[count].row = i;
                triple[count].col = j;
                triple[count].value = matrix[i][j];
                count++;
            }
        }
    }
    return count;
}

int main() {
    // 定义一个矩阵
    int matrix[ROWS][COLS] = {
        {1, 0, 0},
        {0, 2, 0},
        {0, 0, 3}
    };

    // 打印原始矩阵
    printf("原始矩阵:\n");
    for (int i = 0; i < ROWS; i++) {
        for (int j = 0; j < COLS; j++) {
            printf("%d ", matrix[i][j]);
        }
        printf("\n");
    }

    // 将矩阵转换为三元组
    Triple triple[ROWS * COLS];
    int count = convertToTriple(matrix, ROWS, COLS, triple);

    // 打印三元组
    printf("转换后的三元组:\n");
    for (int i = 0; i < count; i++) {
        printf("(%d, %d, %d)\n", triple[i].row, triple[i].col, triple[i].value);
    }

    return 0;
}

三元组,就是将矩阵压缩的一种形式,将非零元素值的位置和值存到三元组数组中,零元素值不存储

矩阵的乘法

#include <stdio.h>

#define ROWS1 2
#define COLS1 3
#define ROWS2 3
#define COLS2 2

/*
	矩阵乘法函数
	参数:
		mat1[ROWS1][COLS1]					矩阵1
		mat2[ROWS2][COLS2]					矩阵2
		result[ROWS1][COLS2]				结果矩阵
*/ 
void matrixMultiply(int mat1[ROWS1][COLS1], int mat2[ROWS2][COLS2], int result[ROWS1][COLS2]) {
 	// 遍历矩阵1的行
    for (int i = 0; i < ROWS1; i++) {
        // 遍历矩阵2的列
        for (int j = 0; j < COLS2; j++) {
            // 首先将这个位置初始化为 0
            result[i][j] = 0;
            // k 作为矩阵1 的列,矩阵2 的行
            for (int k = 0; k < COLS1; k++) {
                // 矩阵1的i行上的每个值 乘以 矩阵2 j列上的每个值相加之和,就是 i,j 位置的乘积
                result[i][j] += mat1[i][k] * mat2[k][j];
            }
        }
    }
}

int main() {
    int mat1[ROWS1][COLS1] = {{1, 2, 3}, {4, 5, 6}};
    int mat2[ROWS2][COLS2] = {{7, 8}, {9, 10}, {11, 12}};
    int result[ROWS1][COLS2];

    // 打印原始矩阵1
    printf("矩阵1:\n");
    for (int i = 0; i < ROWS1; i++) {
        for (int j = 0; j < COLS1; j++) {
            printf("%d ", mat1[i][j]);
        }
        printf("\n");
    }

    // 打印原始矩阵2
    printf("矩阵2:\n");
    for (int i = 0; i < ROWS2; i++) {
        for (int j = 0; j < COLS2; j++) {
            printf("%d ", mat2[i][j]);
        }
        printf("\n");
    }

    // 对矩阵进行相乘
    matrixMultiply(mat1, mat2, result);

    // 打印相乘后的结果矩阵
    printf("相乘后的结果矩阵:\n");
    for (int i = 0; i < ROWS1; i++) {
        for (int j = 0; j < COLS2; j++) {
            printf("%d ", result[i][j]);
        }
        printf("\n");
    }

    return 0;
}

注意:矩阵的乘法,需要知道,矩阵 Amxn * Bnxt = Cmxt ,矩阵B的行数得等于矩阵A的列数,这样才能相乘

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【机器学习300问】21、什么是激活函数?常见激活函数都有哪些?

在我写的上一篇文章中介绍了感知机&#xff08;单个神经元&#xff09;的构成&#xff0c;其中就谈到了神经元会计算传送过来的信号的总和&#xff0c;只有当这个总和超过了某个界限值时&#xff0c;才会输出值。这也称为“神经元被激活”。如果想对神经网络是什么有更多了解的…

网络防御保护——课程笔记

一.防火墙 防火墙的主要职责&#xff1a;控制和防护 --- 安全策略 --- 防火墙可以根据安全策略来抓取流量之后做出对应的动作。 防火墙的分类 防火墙的发展进程 防火墙的控制 带内管理 --- 通过网络环境对设备进行控制 --- telnet&#xff0c;ssh&#xff0c;web --- 登录设备…

【Go 快速入门】包及依赖管理 | Go 第三方包发布 | 接口 | 反射

文章目录 包和依赖管理依赖管理go modgo get go.mod 文件go.sum 文件Go Modules 发布包 接口空接口接口值类型断言 反射reflect.TypeOfreflect.ValueOf结构体反射 项目代码地址&#xff1a;04-PackageInterfaceReflection 包和依赖管理 Go 使用包来支持代码模块化和代码复用&…

【Django开发】前后端分离美多商城项目:项目准备和搭建(附代码,文档)

本系列文章md笔记&#xff08;已分享&#xff09;主要讨论django商城项目开发相关知识。本项目利用Django框架开发一套前后端不分离的商城项目&#xff08;4.0版本&#xff09;含代码和文档。功能包括前后端不分离&#xff0c;方便SEO。采用Django Jinja2模板引擎 Vue.js实现…

分表过多引起的问题/Apache ShardingSphere元数据加载慢

目录 环境 背景 探寻 元数据的加载策略 如何解决 升级版本到5.x 调大max.connections.size.per.query max.connections.size.per.query分析 服务启动阶段相关源码 服务运行阶段相关源码 受到的影响 注意事项&#xff08;重要&#xff09; 其他 环境 Spring Boot 2…

数据结构3、基于栈的后缀算术表达式求值

1 题目描述 图1 中缀表达式转化为后缀表达式题目描述 图2 基于栈的后缀算术表达式求值题目描述 2 题目解读 借助一个运算符栈&#xff0c;可将中缀表达式转化为后缀表达式&#xff1b;借助一个运算数栈&#xff0c;可对后缀表达式求值。借助一个运算符栈和一个运算数栈&#xf…

MongoDB安装以及卸载

查询id&#xff1a; docker ps [rootlocalhost ~]# docker stop c7a8c4ac9346 c7a8c4ac9346 [rootlocalhost ~]# docker rm c7a8c4ac9346 c7a8c4ac9346 [rootlocalhost ~]# docker rmi mongo sudo docker pull mongo:4.4 sudo docker images 卸载旧的 sudo docker stop mong…

Win10无法完成更新正在撤销更改的解决方法

在Win10电脑操作过程中&#xff0c;用户看到了“无法完成更新正在撤销更改”的错误提示&#xff0c;这样系统就不能成功完成更新&#xff0c;不知道如何操作才能解决此问题&#xff1f;以下小编分享最简单的解决方法&#xff0c;帮助大家轻松解决Win10电脑无法完成更新正在撤销…

BIO、NIO编程与直接内存、零拷贝

一、网络通信 1、什么是socket&#xff1f; Socket 是应用层与 TCP/IP 协议族通信的中间软件抽象层&#xff0c;它是一组接口&#xff0c;一般由操作 系统提供。客户端连接上一个服务端&#xff0c;就会在客户端中产生一个 socket 接口实例&#xff0c;服务端每接受 一个客户端…

【Linux网络编程】网络编程套接字(1)

【Linux网络编程】网络编程套接字(1) 目录 【Linux网络编程】网络编程套接字(1)源IP地址和目的IP地址端口号端口号和进程ID的关系 网络通信TCP协议UDP协议网络字节序socket编程接口简单的UDP网络程序 作者&#xff1a;爱写代码的刚子 时间&#xff1a;2024.1.29 前言&#xff1…

SV-7101T网络音频终端 网络对讲终端

SV-7101是一款IP网络广播终端&#xff0c;主要作为网络播放器使用&#xff0c;其接收网络的音频数据&#xff0c;提供音频输出。SV-7101与服务器主控软件、有源音箱配套使用可实现主控室对HG7101终端进行定时打铃、实时语音广播和紧急广播等功能。 淘宝速购&#xff1a; SV-701…

Android中属性property_get和property_set的详细用法介绍

1&#xff0c;property_get和property_set的作用说明 在Android操作系统中&#xff0c;property_get和property_set是用于获取和设置系统属性的函数。这些属性通常用于存储和读取配置信息&#xff0c;例如设备配置、网络设置、系统参数等。 property_get函数用于获取指定属性…

websocket 通信协议

websocket是什么 答: 它是一种网络通信协议&#xff0c;是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。 意思就是服务器可以主动向客户端推送信息&#xff0c;客户端也可以主动向服务器发送信息 属于服务器推送技术的一种. 为什么需要websocket? 疑问?…

(五)MySQL的备份及恢复

1、MySQL日志管理 在数据库保存数据时&#xff0c;有时候不可避免会出现数据丢失或者被破坏&#xff0c;这样情况下&#xff0c;我们必须保证数据的安全性和完整性&#xff0c;就需要使用日志来查看或者恢复数据了 数据库中数据丢失或被破坏可能原因&#xff1a; 误删除数据…

MySQL原理(二)存储引擎(3)InnoDB

目录 一、概况&#xff1a; 1、介绍&#xff1a; 2、特点&#xff1a; 二、体系架构 1、后台线程 2、内存池&#xff08;缓冲池&#xff09; 三、物理结构 1、数据文件&#xff08;表数据和索引数据&#xff09; 1.1、作用&#xff1a; 1.2、共享表空间与独立表空间 …

【C/C++ 05】快速排序

快速排序是Hoare于1962年提出的一种二叉树结构的交换排序算法&#xff0c;其基本思想是&#xff1a;任取待排序序列中的某元素作为基准值&#xff0c;按照该基准值将待排序集合分割成两个子序列&#xff0c;左子序列中所有元素均小于基准值&#xff0c;右子序列中所有元素均大于…

MySQL原理(二)存储引擎(1)概述

一、存储引擎介绍 1、概念&#xff1a; &#xff08;1&#xff09;MySQL中的数据用各种不下同的技术存储在文件中&#xff0c;每一种技术都使用不同的存储机制、索引技巧、锁定水平并最终提供不同的功能和能力&#xff0c;这些不同的技术以及配套的功能在MySQL中称为存储引擎…

【数据结构与算法】7.详解队列的基本操作

&#x1f4da;博客主页&#xff1a;爱敲代码的小杨. ✨专栏&#xff1a;《Java SE语法》|《数据结构与算法》 ❤️感谢大家点赞&#x1f44d;&#x1f3fb;收藏⭐评论✍&#x1f3fb;&#xff0c;您的三连就是我持续更新的动力❤️ &#x1f64f;小杨水平有限&#xff0c;欢…

2024年最新 MySQL的下载、安装、启动与停止

一、MySQL的下载 MySQL最常用的2个版本&#xff1a; 社区版&#xff1a;免费开源&#xff0c;自由下载&#xff0c;不提供官方技术支持&#xff0c;大多数普通用户选择这个即可。企业版&#xff1a;需要付费&#xff0c;不能在线下载&#xff0c;可以使用30天&#xff0c;提供…

ctfshow web72

下载源码&#xff1a; 开启环境&#xff1a; 本题设置了 open_basedir()&#xff0c;将php所能打开的文件限制在指定的目录树中&#xff0c;包括文件本身。 因为 ini_set() 也被限制了&#xff0c;所以 open_basedir() 不能用 ini_set() 重新设置绕过。 使用 php 伪协议 glob:…
最新文章