news 2026/2/17 20:45:12

冒泡排序与数组传递全解析 一维二维指针数组及二级指针应用指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
冒泡排序与数组传递全解析 一维二维指针数组及二级指针应用指南

冒泡排序与数组传递全解析 一维二维指针数组及二级指针传参指南

一、冒泡排序核心知识点

冒泡排序是一种简单的交换排序算法,核心思想是通过相邻元素的比较与交换,让较大(或较小)的元素像气泡一样逐步“浮”到数组末端。以升序排序为例,步骤如下:

  1. 比较相邻元素:从数组第一个元素开始,依次比较相邻的两个元素(如arr[i]和arr[i+1])。

  2. 交换逆序元素:如果前一个元素大于后一个元素(arr[i] > arr[i+1]),则交换它们的位置。

  3. 重复多轮:每一轮排序后,最大的元素会“沉”到当前未排序部分的末尾。因此,若有n个元素,需进行n-1轮排序(最后一个元素无需再比较)。

  4. 优化:若某一轮未发生交换,说明数组已有序,可提前结束排序。

二、传递一维数组给冒泡排序函数
知识点

C语言中,数组作为函数参数时会退化为指针,因此传递一维数组时需同时传递数组长度(编译器无法通过数组名获取长度)。函数参数可写为int arr[](等价于int *arr),接收数组首地址。

示例代码(含注释)
#include <stdio.h> // 冒泡排序函数:对一维数组升序排序 // 参数:arr 数组首地址(退化为指针),len 数组长度 void bubble_sort_1d(int arr[], int len) { int i, j, temp; int swapped; // 标记本轮是否发生交换,用于优化 for (i = 0; i < len - 1; i++) { // 共需 len-1 轮排序 swapped = 0; // 初始化为未交换 // 每轮比较次数:未排序部分长度为 len - i,需比较 len - i - 1 次 for (j = 0; j < len - i - 1; j++) { if (arr[j] > arr[j + 1]) { // 前大后小,交换 temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; swapped = 1; // 标记发生交换 } } if (!swapped) break; // 本轮无交换,数组已有序,提前退出 } } // 打印数组 void print_array(int arr[], int len) { int i; for (i = 0; i < len; i++) { printf("%d ", arr[i]); } printf("\n"); } int main() { int nums[] = {64, 34, 25, 12, 22, 11, 90}; int len = sizeof(nums) / sizeof(nums[0]); // 计算数组长度 printf("排序前数组:"); print_array(nums, len); bubble_sort_1d(nums, len); // 传递一维数组和长度 printf("排序后数组:"); print_array(nums, len); return 0; }
三、传递二维数组给冒泡排序函数
知识点

二维数组传递需注意函数参数必须指定第二维的大小(除非用指针数组或数组指针)。可将二维数组视为“一维数组”(内存连续),对所有元素统一排序。

示例代码(含注释)
#include <stdio.h> // 冒泡排序二维数组(整体排序,视为一维数组) // 参数:arr 二维数组首地址(第二维固定为4),rows 行数,cols 列数 void bubble_sort_2d(int arr[][4], int rows, int cols) { int total = rows * cols; // 总元素个数 int i, j, temp; int swapped; for (i = 0; i < total - 1; i++) { swapped = 0; for (j = 0; j < total - i - 1; j++) { // 计算当前元素的行列坐标(模拟一维索引转二维) int row1 = j / cols, col1 = j % cols; int row2 = (j + 1) / cols, col2 = (j + 1) % cols; if (arr[row1][col1] > arr[row2][col2]) { temp = arr[row1][col1]; arr[row1][col1] = arr[row2][col2]; arr[row2][col2] = temp; swapped = 1; } } if (!swapped) break; } } // 打印二维数组 void print_2d_array(int arr[][4], int rows, int cols) { int i, j; for (i = 0; i < rows; i++) { for (j = 0; j < cols; j++) { printf("%d ", arr[i][j]); } printf("\n"); } } int main() { int matrix[3][4] = {{9, 5, 7, 3}, {2, 8, 1, 6}, {4, 0, 10, 12}}; int rows = 3, cols = 4; printf("排序前二维数组:\n"); print_2d_array(matrix, rows, cols); bubble_sort_2d(matrix, rows, cols); printf("排序后二维数组(整体升序):\n"); print_2d_array(matrix, rows, cols); return 0; }
四、指针数组与冒泡排序
知识点

指针数组是数组元素为指针变量的数组(如char *str_arr[])。对指针数组排序时,交换指针(而非内容)更高效,常用于字符串排序(按字典序)。指针数组名退化为二级指针char **)。

示例代码(含注释)
#include <stdio.h> #include <string.h> // 冒泡排序指针数组(交换指针,按字符串字典序升序) // 参数:str_arr 指针数组首地址(等价于二级指针 char **),len 数组长度 void bubble_sort_str_ptr(char *str_arr[], int len) { int i, j; char *temp; // 临时指针(交换指针用) int swapped; for (i = 0; i < len - 1; i++) { swapped = 0; for (j = 0; j < len - i - 1; j++) { // strcmp比较字符串:返回正数表示前者大于后者 if (strcmp(str_arr[j], str_arr[j + 1]) > 0) { temp = str_arr[j]; // 交换指针(核心) str_arr[j] = str_arr[j + 1]; str_arr[j + 1] = temp; swapped = 1; } } if (!swapped) break; } } // 打印字符串数组 void print_str_array(char *str_arr[], int len) { int i; for (i = 0; i < len; i++) { printf("%s ", str_arr[i]); } printf("\n"); } int main() { char *fruits[] = {"banana", "apple", "cherry", "date"}; // 指针数组 int len = sizeof(fruits) / sizeof(fruits[0]); printf("排序前字符串数组:"); print_str_array(fruits, len); bubble_sort_str_ptr(fruits, len); // 传递指针数组(退化为二级指针) printf("排序后字符串数组(字典序升序):"); print_str_array(fruits, len); return 0; }
五、二级指针传参与冒泡排序
知识点

二级指针(如int **pp)是指向指针的指针,用于存储“指针变量的地址”。在数组传递中,二级指针主要用于两种场景:

  1. 传递指针数组:指针数组名本身就是二级指针(如char *str_arr[]等价于char **str_arr)。

  2. 传递动态二维数组:通过malloc动态分配的二维数组(如int **arr),其数组名也是二级指针。

下面通过两个示例讲解二级指针传参的用法。

示例1 二级指针传递指针数组

之前的指针数组排序中,bubble_sort_str_ptr(char *str_arr[], int len)的参数char *str_arr[]等价于char **str_arr(二级指针)。这里显式用二级指针参数重写,更直观展示二级指针传参逻辑。

#include <stdio.h> #include <string.h> // 显式用二级指针参数:pp 指向指针数组的指针(即二级指针) void bubble_sort_2ptr(char **pp, int len) { int i, j; char *temp; int swapped; for (i = 0; i < len - 1; i++) { swapped = 0; for (j = 0; j < len - i - 1; j++) { if (strcmp(pp[j], pp[j + 1]) > 0) { // 比较字符串 temp = pp[j]; // 交换指针(通过二级指针访问元素) pp[j] = pp[j + 1]; pp[j + 1] = temp; swapped = 1; } } if (!swapped) break; } } int main() { char *fruits[] = {"banana", "apple", "cherry", "date"}; int len = sizeof(fruits) / sizeof(fruits[0]); // fruits 是指针数组名,退化为二级指针 char **,直接传递给函数 bubble_sort_2ptr(fruits, len); printf("排序后(二级指针传参):"); for (int i = 0; i < len; i++) { printf("%s ", fruits[i]); } printf("\n"); return 0; }

核心逻辑:二级指针pp指向指针数组的首元素(即第一个字符串的地址),通过pp[j]访问第j个字符串的指针,交换时直接操作指针值。

示例2 二级指针传递动态二维数组(动态分配内存)

动态二维数组通过malloc分配:先分配行指针数组(int **arr),再为每行分配列空间。此时arr是二级指针,可直接传递给排序函数。

#include <stdio.h> #include <stdlib.h> // 冒泡排序动态二维数组(整体排序,视为一维数组) // 参数:pp 动态二维数组首地址(二级指针),rows 行数,cols 列数 void bubble_sort_dynamic_2d(int **pp, int rows, int cols) { int total = rows * cols; int i, j, temp; int swapped; for (i = 0; i < total - 1; i++) { swapped = 0; for (j = 0; j < total - i - 1; j++) { // 计算行列坐标(动态数组同样连续存储) int row1 = j / cols, col1 = j % cols; int row2 = (j + 1) / cols, col2 = (j + 1) % cols; if (pp[row1][col1] > pp[row2][col2]) { temp = pp[row1][col1]; pp[row1][col1] = pp[row2][col2]; pp[row2][col2] = temp; swapped = 1; } } if (!swapped) break; } } // 打印动态二维数组 void print_dynamic_2d(int **pp, int rows, int cols) { int i, j; for (i = 0; i < rows; i++) { for (j = 0; j < cols; j++) { printf("%d ", pp[i][j]); } printf("\n"); } } int main() { int rows = 3, cols = 4; int **matrix = (int **)malloc(rows * sizeof(int *)); // 分配行指针数组 for (int i = 0; i < rows; i++) { matrix[i] = (int *)malloc(cols * sizeof(int)); // 为每行分配列空间 } // 初始化动态数组 int init_data[3][4] = {{9, 5, 7, 3}, {2, 8, 1, 6}, {4, 0, 10, 12}}; for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { matrix[i][j] = init_data[i][j]; } } printf("动态数组排序前:\n"); print_dynamic_2d(matrix, rows, cols); bubble_sort_dynamic_2d(matrix, rows, cols); // 传递二级指针 printf("动态数组排序后(整体升序):\n"); print_dynamic_2d(matrix, rows, cols); // 释放内存(避免泄漏) for (int i = 0; i < rows; i++) free(matrix[i]); free(matrix); return 0; }

核心逻辑:动态二维数组的二级指针pp指向行指针数组,通过pp[i][j]访问元素,排序时视为一维数组处理(利用内存连续性)。

六、总结

数组类型

传递方式

本质(退化后)

排序核心思路

典型场景

一维数组

int arr[]int *arr

一级指针

相邻元素比较交换

普通数值数组排序

二维数组(静态)

int arr[][N]int (*arr)[N]

数组指针(行指针)

视为一维数组整体排序

固定列数的矩阵排序

指针数组

char *arr[]char **arr

二级指针

交换指针(高效)或交换内容

字符串数组按字典序排序

动态二维数组

int **arr

二级指针

视为一维数组整体排序

运行时动态创建的多维数组排序

二级指针传参的关键:明确其指向“指针数组”或“动态二维数组的行指针数组”,通过解引用(pp[j]pp[i][j])访问元素,排序逻辑与普通数组一致,仅传递方式不同。掌握二级指针传参,能灵活处理更复杂的数组场景(如动态内存、多级指针数据结构)。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/9 0:42:44

用AI写国际专利:开发者出海工具包

AI赋能软件测试从业者的专利出海新机遇 在全球化竞争加剧的背景下&#xff0c;软件测试从业者面临将创新技术转化为国际专利的挑战——技术细节需精准表述、格式需符合多国审查标准&#xff0c;耗时且易出错。生成式AI的崛起&#xff0c;如专利辅助工具&#xff0c;正重塑这一…

作者头像 李华
网站建设 2026/2/15 19:05:13

【小程序毕设源码分享】基于php+小程序的php文山手工艺品展销平台的设计与实现(程序+文档+代码讲解+一条龙定制)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/2/15 19:05:11

AI生成的测试用例归档:从理论到实践的最佳方案

归档在AI测试中的战略意义在AI驱动的测试环境中&#xff0c;测试用例生成速度大幅提升&#xff0c;但随之而来的管理挑战——如版本混乱、数据冗余和质量波动——凸显了归档工作的关键性。归档不仅是对用例的静态存储&#xff0c;更是确保测试资产可追溯、可复用和可审计的动态…

作者头像 李华
网站建设 2026/2/15 19:05:10

亲测好用! AI论文写作软件 千笔·专业论文写作工具 VS PaperRed 本科生必备

随着人工智能技术的快速发展&#xff0c;AI辅助写作工具已逐渐成为高校学生完成毕业论文的重要帮手。无论是开题报告、文献综述还是正文撰写&#xff0c;越来越多的学生开始借助AI工具提升写作效率与质量。然而&#xff0c;在面对市场上种类繁多、功能各异的AI写作软件时&#…

作者头像 李华
网站建设 2026/2/17 13:09:59

汽车制造企业使用百度UE导入EXCEL参数表,如何生成动态数据图表?

Word内容粘贴及文档导入功能解决方案报告 作为公司前端技术负责人&#xff0c;我针对客户提出的Word/公众号内容粘贴及Office文档导入需求进行了全面调研与技术方案设计。以下是详细报告&#xff1a; 一、需求分析 客户核心诉求为在现有UEditor编辑器中实现&#xff1a; Wo…

作者头像 李华