【C语言数组经典问题】
C语言数组经典问题的分析解决
C语言数组的学习!
基础知识
数组概念:
- 定义 :数组是数目固定,类型相同,连续存放的有序集合;
(数组解决的就是变量过多,程序繁琐冗余,可以读性差的问题) - 构成:数组由元素构成,元素的数目固定,类型相同,连续存放在内存中;
- 特点:使用数组可以使程序结构更加合理、简洁、清晰, 提高程序的功能和灵活性;
- 分类:按照结构分类: 一维数组、二维数组
按照类型分类: 整型数组、实型数组,字符数组、指针数组 - 格式:类型说明符 标识符[]
- 首位置:首地址:数组名就是首地址(是一个常量)
sizeof(数组名):整个数组占用的字节数 - 下标:从0开始 表示距首地址偏移的元素个数 下标范围【0,n-1】
经典问题
1.求数组最值
题目:输入n 输入n个元素的值 求其中最大值最小值
分析:题目要求得到最大最小值,首先想到是要遍历所有元素获取其中最大最小值,在循环中加入一个中间变量保存第一个元素的值,与后续元素依次进行比较即可得到最值。
代码实现:
#include "stdio.h"
int main() {
int arr[100] = {0};
int n = 0;
scanf("%d", &n);
int max=INT_MIN, min=INT_MAX;
for (int i = 0; i < n; ++i) {
scanf("%d", &arr[i]);
}
for (int i = 0; i < n; ++i) {
for (int i = 0; i < n; ++i) {
//遍历-查询-最值问题,逐一查询拿到最大值
max=max>arr[i]?max:arr[i];
min=min<arr[i]?min:arr[i];
}
printf("\n%d", max);
printf("\n%d", min);
}
return 0;
}
2.对数组进行逆序后输出逆序后的数组
题目:输入n 输入n个元素的值 将数组逆序后输出
分析:逆序可以理解为对数组首个元素和最后一个元素换位,其它元素依次进行换位,也就是数组的其中一半的元素和对应的元素交换位置即可。
代码实现:
#include "stdio.h"
int main() {
int arr[100];
int ass[100];
int n = 0, t, a;
scanf("%d", &n);
for (int i = 0; i < n; i++) {
scanf("%d", &arr[i]);
}
for (int i = 0; i < n / 2; i++) {
t = arr[i];
arr[i] = arr[n - 1 - i];
arr[n - 1 - i] = t;
}
for (int j = 0; j < n; j++) {
printf("%d\t", arr[j]);
}
return 0;
}
3.向数组中指定下标插入元素
题目:输入n 输入n个元素的值,向数组中指定下标插入元素;
分析:插入元素不会删除原有的元素,而是将原有元素依次向后移动一位,可以循环将指定元素之和的值依次向后移动一位。
代码实现:
#include "stdio.h"
int main() {
int arr[100] = {0};
int n, m = 0, num = 0;
scanf("%d", &n);
scanf("%d", &m);//指定下标
scanf("%d", &num);//要插入的元素
for (int i = 0; i < n; ++i) {
scanf("%d", &arr[i]);
}
for (int i = n; i >= m; i--) {
arr[i] = arr[i - 1];
}
arr[m] = num;
n++;
for (int i = 0; i < n; ++i) {
printf("%d\t", arr[i]);
}
return 0;
}
4.删除数组中指定下标的元素
题目:输入n 输入n个元素的值,删除数组中指定下标的元素;
分析:删除指定下标的元素后,依次向前赋值。
代码实现:
#include "stdio.h"
int main() {
int arr[100] = {0};
int index, n,;
scanf("%d", &n);
for (int i = 0; i < n; ++i) {
scanf("%d", &arr[i]);
}
scanf("%d",&index);
for(int i=index;i<n;i++){
arr[i]=arr[i+1];
}
n--;
for (int i = 0; i < n; ++i) {
printf("%d\t",arr[i]);
}
return 0;
}
5.冒泡排序
题目:输入n 输入n个元素的值,对其中的元素依照从小到大进行排序;
分析:两两相比,每次将较大的数向后移动,循环n-1次得到排序后的值。
代码实现:
void bubbleSort(int n, int *arr) {
for (int i = 0; i < n - 1; ++i) {//n个数进行n-1次比较
for (int j = 0; j < n - 1 - i; ++j) {//n-1-i 是减去已经排出来的元素
if (arr[j] > arr[j + 1]) {//内存循环比较每次取出最大的数
int tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;//取出的最大的数始终在循环的最后一个位置
}
}
}
for (int i = 0; i < n; ++i) {
printf("%d\t", arr[i]);
}
}
6.查找对应数据的下标
题目:输入n 输入n个元素的值,查找值为target的数据的下标,如果存在打印下标,如果没有则返回-1;
分析:使用依次查找的方式数据量较大的情况下非常耗时,使用二分法可以大大提高查询效率。
代码实现:
int findTarget(int n, int *arr, int target) {
int left, right, mid;
left = 0;
right = n - 1;
while (left <= right) {//左加右减,当左>右时结束循环
mid = (left + right) / 2;
if (arr[mid] == target) {
return mid;
} else if (arr[mid] > target) {
right = mid - 1;
} else {
left = mid + 1;
}
}
return -1;
}
7.数组去重
题目:给定一个包含红色,白色,蓝色,共n中元素的数组a[];原地对他们进行排序,使得相同颜色的红色,白色,蓝色顺序排列。我们使用整数0 1 2分别代表红色 白色 蓝色 必须在不使用库函数sort函数的情况下完成。
示例
输入a=[2,0,2,1,1,0]
输出 [0,0,1,1,2,2]
分析:使用标记法将每次出现的元素都与之前的元素相比,如果相同flag=0,最后把flag=1的数据依次赋给新的数组。
代码实现:
void deleteSame(int n, int *arr) {
int m = 0;
int brr[100];
for (int i = 0; i < n; i++) {
int flag = 0;//0没出现过, 1出现过
for (int j = 0; j < m; j++) {
if (arr[i] == brr[j]) {//arr在brr数组前m个元素中是否存在
flag = 1;
break;
}
}
if (flag == 0) {//不存在标记不变
brr[m]=arr[i];//将arr[i]添加到brr末尾
m++;
}
}
for (int i = 0; i < m; ++i) {
printf("%d\t", brr[i]);
}
}