搭建网站需要什么技术番禺人才网
搭建网站需要什么技术,番禺人才网,网络公司经营范围包括劳务吗,厦门百度竞价推广冒泡排序与数组传递全解析 一维二维指针数组及二级指针传参指南一、冒泡排序核心知识点冒泡排序是一种简单的交换排序算法#xff0c;核心思想是通过相邻元素的比较与交换#xff0c;让较大#xff08;或较小#xff09;的元素像气泡一样逐步“浮”到数组末端。以升序排序为…冒泡排序与数组传递全解析 一维二维指针数组及二级指针传参指南一、冒泡排序核心知识点冒泡排序是一种简单的交换排序算法核心思想是通过相邻元素的比较与交换让较大或较小的元素像气泡一样逐步“浮”到数组末端。以升序排序为例步骤如下比较相邻元素从数组第一个元素开始依次比较相邻的两个元素如arr[i]和arr[i1]。交换逆序元素如果前一个元素大于后一个元素arr[i] arr[i1]则交换它们的位置。重复多轮每一轮排序后最大的元素会“沉”到当前未排序部分的末尾。因此若有n个元素需进行n-1轮排序最后一个元素无需再比较。优化若某一轮未发生交换说明数组已有序可提前结束排序。二、传递一维数组给冒泡排序函数知识点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 二维数组首地址第二维固定为4rows 行数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是指向指针的指针用于存储“指针变量的地址”。在数组传递中二级指针主要用于两种场景传递指针数组指针数组名本身就是二级指针如char *str_arr[]等价于char **str_arr。传递动态二维数组通过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]访问元素排序逻辑与普通数组一致仅传递方式不同。掌握二级指针传参能灵活处理更复杂的数组场景如动态内存、多级指针数据结构。