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

news2024/11/18 1:38:43

文章目录

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

数组

数组的概述

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

数组的图示

一维数组

二维数组
  • 二维数组可以看成一个表格,下边就是一个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.coloradmin.cn/o/1419552.html

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

相关文章

SQL Server ISO镜像文件安装

参考&#xff1a;Sql Server ISO镜像文件安装指南_sqlserveriso文件怎么安装-CSDN博客 参考文件中的步骤基本相同&#xff0c;注意两点 1、尽量安装在D盘&#xff0c;有些组件默认必须安装在C盘&#xff0c;有些会报没有目录的情况 需要在D盘创建目录。 2、我没有windows本地…

交叉编译opencv运行平台rk3588

opencv版本&#xff1a;4.8.0 opencv_contrib版本&#xff1a;4.8.0 在源码目录下建build目录&#xff0c;进入该目录配置编译选项生成makefile cmake 配置参数&#xff1a; cmake -DCMAKE_MAKE_PROGRAM:PATH/usr/bin/make -DCMAKE_INSTALL_PREFIX/home/rog/my_file/other_L…

开发通用模板设计

文章目录 需求摘要1 模板描述2 模板内容介绍2.1 模块间依赖关系2.2 模板目前集成2.2.1 swaggerKnife4j2.2.1 nacosSpringBootSpringCloudAlibaba 3 项目地址4 FAQ 需求 目前在开发中&#xff0c;使用的非本人搭建的项目架子&#xff0c;存在如下问题&#xff1a; 依赖无法统一…

MyBatis 的XML实现方法

MyBatis 的XML实现方法 MyBatis 的XML实现方法前情提示创建mapper接口添加配置创建xml文件操作数据库insert标签delete标签select标签resultMap标签 update标签sql标签,include标签 MyBatis 的XML实现方法 前情提示 关于mybatis的重要准备工作,请看MyBatis 的注解实现方法 创…

机器学习系列 16:使用 scikit-learn 的 Pipeline

在机器学习项目中&#xff0c;我们经常需要进行大量的数据预处理步骤&#xff0c;最后用处理干净的数据集来拟合机器学习算法得到一个合适的机器学习模型。 scikit-learn 提供了一个强大的 Pipeline 类来帮助我们将所有的数据预处理步骤和训练模型的步骤串起来。就像流水线一样…

【UE 材质】闪电材质

效果 步骤 1. 新建一个材质这里命名为“M_Lighting” 打开“M_Lighting”&#xff0c;设置混合模式为半透明&#xff0c;着色模型为无光照 在材质图表中添加如下节点 其中&#xff0c;纹理采样节点的纹理是一个线条 此时预览窗口中效果如文章开头所示。

LINUX基础培训十九之常见服务dns介绍

前言、本章学习目标 了解dns服务用途掌握dns服务器的配置掌握dns服务的使用 一、DNS服务概述 DNS是域名系统(Domain Name System)的缩写&#xff0c;是因特网的一项核心服务&#xff0c;它作为可以将域名和IP地址相互映射的个分布式数据库&#xff0c;能够使人更方便的访问…

计数排序(六)——计数排序及排序总结

目录 一.前言 二.归并小补充 三.计数排序 操作步骤&#xff1a; 代码部分&#xff1a; 四.稳定性的概念&#xff1a; 五.排序大总结&#xff1a; ​六.结语 一.前言 我们已经进入排序的尾篇了&#xff0c;本篇主要讲述计数排序以及汇总各类排序的特点。码字不易&#x…

Nuget包缓存存放位置迁移

一、背景 默认情况下&#xff0c;NuGet会将项目中使用的包缓存到C盘&#xff0c;随着项目开发积累nuget包越来越多&#xff0c;这会逐渐挤占大量C盘空间&#xff0c;所以我们可以将nuget包缓存位置指定到其他盘中存放。 二、软件环境 win10、vs2022 三、查看当前缓存存放位…

realsence 455 查看左右摄像头

前言 我打算使用realsence的左右连个摄像头去自己标定配准、然后计算距离的&#xff0c;就需要找s、下载包。 没成想&#xff0c;这个455的左右摄像头是红外的 步骤 安装sdk&#xff1a; Intel RealSense SDK 2.0 – Intel RealSense Depth and Tracking cameras 尽量在w…

为什么要用云手机养tiktok账号

在拓展海外电商市场的过程中&#xff0c;许多用户选择采用tiktok短视频平台引流的策略&#xff0c;以提升在电商平台上的流量&#xff0c;吸引更多消费者。而要进行tiktok引流&#xff0c;养号是必不可少的一个环节。tiktok云手机成为实现国内跨境养号的一种有效方式&#xff0…

【新书推荐】3.2节 位运算之加减乘除

本节内容&#xff1a;二进制移位运算&#xff0c;以及逻辑运算与算术运算之间的转换。任何进制的位运算本质都是一样的。 ■二进制数移位运算&#xff1a;二进制数向左移位运算相当于做2的幂乘法运算&#xff0c;二进制数向右移位运算&#xff0c;相当于做2的幂除法运算。 ■十…

qt学习:Table widget控件

目录 头文件 实战 重新配置ui界面 添加头文件 在构造函数中添加初始化 显示方法 该实例是在sqlite项目上添加qt学习&#xff1a;QTSQL连接sqlite数据库增删改查-CSDN博客 头文件 #include <QTableWidgetItem> 实战 重新配置ui界面 用法介绍&#xff0c;可以双击…

大数据StarRocks(八):资源隔离实战

前言 自 2.2 版本起&#xff0c;StarRocks 支持资源组管理&#xff0c;集群可以通过设置资源组&#xff08;Resource Group&#xff09;的方式限制查询对资源的消耗&#xff0c;实现多租户之间的资源隔离与合理利用。在 2.3 版本中&#xff0c;StarRocks 支持限制大查询&#…

RK3568 Android 13 系统裁剪

android 13 系统裁剪是个大工程&#xff0c;裁剪也是需要大量的测试&#xff0c;才能保证系统的稳定性&#xff0c;以下是RK官方给出的裁剪方案&#xff0c;有兴趣的可以去看一下&#xff0c;对裁剪不是要求过高的可以根据官方的建议&#xff0c;对系统进行裁剪: Rockchip And…

ssh 配置

ssh 配置 在管理Git项目上&#xff0c;很多时候都是直接使用 https url 克隆到本地&#xff0c;当然也有有些人使用 SSH url 克隆到本地。 这两种方式的主要区别在于&#xff1a;使用 https url 克隆对初学者来说会比较方便&#xff0c;复制 https url 然后到 git Bash 里面直…

纯html+js+css个人博客

首页 <!DOCTYPE HTML> <html> <head> <title>博客</title> <meta http-equiv"Content-Type" content"text/html; charsetutf-8" /> <meta name"viewport" content"widthdevice-width, initial-sca…

E. Vlad and a Pair of Numbers(位运算)

思路&#xff1a;如果x在这一位是1&#xff0c;说明a,b在这一位一个是1一个是0&#xff0c;我们默认a为1&#xff0c;b为0.. 对于n的一些位为0&#xff0c;那么a&#xff0c;b在这一位肯定相同。我们想&#xff0c;如果a和b的和右移一位与x相同&#xff0c;所以1的位置是相同的…

按照模板生成文件,Word 或者 Excel

需求流程&#xff1a; 模板部分如图&#xff1a; Web端技术选用Jfinal 功能实现&#xff1a; 下面代码是调用 --“外部接口”--传参&#xff0c;将前端选中的信息传给后端&#xff0c; 另外将后端返回的文件流下载成文件 package ibasic.web.com.controller;import java.io.Bu…

链表--114. 二叉树展开为链表/medium 理解度C

114. 二叉树展开为链表 1、题目2、题目分析3、复杂度最优解代码示例4、适用场景 1、题目 给你二叉树的根结点 root &#xff0c;请你将它展开为一个单链表&#xff1a; 展开后的单链表应该同样使用 TreeNode &#xff0c;其中 right 子指针指向链表中下一个结点&#xff0c;而…