一、直接更新
(一)初始化为最小值INT_MIN
在找数组中第二大元素,初始化时可以将最大值与第二大值初始化为int型的最小值INT_MIN,但是需要引入头文件#include <limits.h>。
然后再更新最大值与第二大值:
-
遍历剩余元素(从
i = 0开始):-
如果
num[i] > max:
说明发现了新的最大值,原来的max降级为secondMax,更新max = num[i]。 -
否则如果
num[i] > secondMax:
说明当前元素比次大值大(但小于最大值),直接更新secondMax。 -
注意:这里不需要考虑
num[i] == max的情况,因为初始化时已保证二者的值不重复。
-
#include <stdio.h>
#include <limits.h>
int main() {
int numbers[5], max, secondMax;
printf("Enter 5 integers:\n");
for (int i = 0; i < 5; i++) {
scanf("%d", &numbers[i]);
}
max = secondMax = INT_MIN;
for (int i = 0; i < 5; i++) {
if (numbers[i] > max) {
secondMax = max;
max = numbers[i];
} else if (numbers[i] > secondMax && numbers[i] != max ) {
secondMax = numbers[i];
}
}
printf("Second largest number is: %d\n", secondMax);
return 0;
}
(二)初始化为数组首元素
如果不想引用头文件时(或者记不住头文件时),可以将max与secondMax初始化为数组中的第一个元素,同时在更新第二大元素值的时候添加条件:(其他不变)
(最大==第二大)&&(当前值最大值): || (max==secondMax && numbers[i]<max)
添加max==secodnMax且大于当前元素这种情况可以避免max与secodnMax同时初始化为数组中最大值,导致后面无法更新secodnMax。
完整代码:
#include <stdio.h>
int main() {
int numbers[5], max, secondMax;
printf("Enter 5 integers:\n");
for (int i = 0; i < 5; i++) {
scanf("%d", &numbers[i]);
}
max = secondMax = numbers[0];
for (int i = 1; i < 5; i++) {
if (numbers[i] > max) {
secondMax = max;
max = numbers[i];
} else if ((numbers[i] > secondMax && numbers[i] != max) || (max==secondMax && numbers[i]<max)) {
secondMax = numbers[i];
}
}
printf("Second largest number is: %d\n", secondMax);
return 0;
}
三、先去重后更新(麻烦一些)
核心思路:
(一)数组去重
移除所有重复出现的元素,使数组中每个数值只保留一个。
方法
双重循环 + 覆盖删除。
- 外层循环用
i固定当前元素。 - 内层用
while循环遍历i之后的所有元素。 - 如果发现
num[j] == num[i],说明j位置是重复元素:
- 将
j后面的所有元素前移一位(覆盖num[j])。 - 数组有效长度
len减 1。 j不增加(因为新的元素移到了j位置,需要重新检查)。
if (num[i] == num[j]){
// 删除 num[j]
for (int k = j; k < len - 1; k++){
num[k] = num[k + 1];
}
len--; // 缩短长度
// j不增加,继续检查当前位置
}
- 如果不相等,则
j++,继续检查下一个位置。
else{
j++; // 只有不相等时才移动 j
}
关键点
删除元素后,j 要回退,确保不会漏掉因前移而进入 j 位置的新元素。
(二)处理去重后的数组
根据去重后的数组长度 len,分情况讨论:
情况 1:len == 1
-
说明数组中所有元素值都相同(去重后只剩一个)。
-
没有第二大元素,直接输出提示并结束。
if (len == 1){
printf("数组中所有元素相同,无第二大元素");
return 0;
}
情况 2:len >= 2
-
初始化最大值和次大值:
-
比较
num[0]和num[1],较大的赋给max,较小的赋给secondMax。 -
这样初始化的好处是:如果数组只有两个元素,它们就是最终结果,无需进入循环。
-
if (num[0] > num[1]) {
max = num[0];
secondMax = num[1];
}
else {
max = num[1];
secondMax = num[0];
}
-
遍历剩余元素(从
i = 2开始):-
如果
num[i] > max:
说明发现了新的最大值,原来的max降级为secondMax,更新max = num[i]。 -
否则如果
num[i] > secondMax:
说明当前元素比次大值大(但小于最大值),直接更新secondMax。 -
注意:这里不需要考虑
num[i] == max的情况,因为去重后已保证所有元素值不重复。
-
for (int i = 2; i < len; i++) {
if (num[i] > max){
// 新最大值,旧最大值降级为次大
secondMax = max;
max = num[i];
}
else if (num[i] > secondMax){
// 比次大大,直接更新次大
secondMax = num[i];
}
}
完整代码如下:
#include <stdio.h>
int main()
{
int num[8];
int len = sizeof(num) / sizeof(num[0]);
int max, secondMax;
// 1.输入数组
printf("请输入%d个元素:", len);
for (int i = 0; i < len; i++){
scanf("%d", &num[i]);
}
// 2.数组去重
for (int i = 0; i < len - 1; i++){
int j = i + 1;
while (j < len){
if (num[i] == num[j]){
// 删除 num[j]
for (int k = j; k < len - 1; k++){
num[k] = num[k + 1];
}
len--; // 缩短长度
// j不增加,继续检查当前位置
}
else{
j++; // 只有不相等时才移动 j
}
}
}
printf("去重后长度len=%d\n", len);
// 3.根据去重后元素个数分开求解
// 如果去重后只有一个元素
if (len == 1){
printf("数组中所有元素相同,无第二大元素");
return 0;
}
// 去重后有2个及以上
else{
// 先初始化,防止两个变量都是最大值
// 如果去重后只有2个元素则下面初始化为最后结果
if (num[0] > num[1]) {
max = num[0];
secondMax = num[1];
}
else {
max = num[1];
secondMax = num[0];
}
// 如果有2个则不满足for循环条件不执行下面循环,上面初始化为最后结果
// 如果是2个以上则执行循环更新最大和次大值
for (int i = 2; i < len; i++) {
if (num[i] > max){
// 新最大值,旧最大值降级为次大
secondMax = max;
max = num[i];
}
else if (num[i] > secondMax){
// 比次大大,直接更新次大
secondMax = num[i];
}
}
printf("该数组中第二大元素:%d\n", secondMax);
return 0;
}
}
2536




被折叠的 条评论
为什么被折叠?



