求出数组的最大值和次大值

来源:互联网 发布:奔驰s600电脑编程 编辑:程序博客网 时间:2024/06/09 19:53

求数组的最大值相对来说是比较简单,只需要遍历一遍数组,不断更新数组的最大值,直到遍历完成。自然语言描述:

 1. 初始化最大值的角标 2. 遍历数组,比较当前的最大值角标的元素和遍历得到数组元素的大小;    如果数组元素大于当前最大值,更新最大值角标为遍历到的数组元素角标,    直到遍历完成

程序设计语言描述:

int getMax(int[] arr){        int max = 0;                    //定义最大值角标        for (int i = 0; i < arr.length; i++) {  //遍历数组            if (arr[max] < arr[i]) {    //比较当前最大值和遍历元素                max = i;                //更新最大值角标            }        }        return arr[max];}

分析算法,基本语句共执行n次(假设数组长度为n),时间复杂度O(n)。

如果要找出次大值,一开始先是考虑的是用2次冒泡,次大值就能找出下面是简单的程序代码

int getSubMax(int[] arr) {        for (int i = 0; i < 2; i++) {         //两次冒泡            for (int j = 0; j < arr.length - 1 - i; j++) {                if (arr[j] > arr[j+1]) swap(j, j+1, arr);//交换            }        }        return arr[arr.length - 2];    }

但是要遍历数组两次,效率肯定还是不好,所以采用下面的描述:

 1. 设置最大值和次大值的角标maxIndex,subMaxIndex 2. 比较头两个元素大小来初始化两个角标 3. 从第3个元素开始遍历,取数组元素arr[i],如果maxIndex<arr[i],    次大值取代最大值,subMaxIndex = maxIndex,更新最大值maxIndex = i;    反之,如果subMaxIndex<arr[i],更新次大值subMaxIndex = i;

程序语言描述:

int getSubMax(int[] arr) {        //定义最大值角标        int maxIndex = 0;        //定义次大值角标        int subMaxIndex = 0;        //比较头两个元素初始化最大,次大值得角标        if (arr[0] >= arr[1]) {            maxIndex = 0;            subMaxIndex = 1;        } else {            maxIndex = 1;            subMaxIndex = 0;        }        //注意从第三个元素开始比较        for (int i = 2; i < arr.length; i++) {            // 如果遍历到当前的数大于最大值时            if (arr[i] > arr[maxIndex]) {                // 出现新的最大值,最大值变为次大值                subMaxIndex = maxIndex;                // 新的最大值                maxIndex = i;                // 如果再次出现一个大于次大值且小于最大值的数,更新次大值            } else if (arr[i] > arr[subMaxIndex]) {                subMaxIndex = i;            }        }        return arr[subMaxIndex];    }

通过这样的比较,能同时得出最大值与次大值,而且基本语句执行的次数仅为n-2次,所以时间复杂度为O(n)。
一开始并没有加入前两个元素的比较,直接初始化两个索引都为0,但是后来发现程序还不够完美,当测试最大值就恰好就是第一个值时,结果次大值也是最大值,显然不满足算法的确定性原则,于是在原来基础上改进,先确定两组索引,从第三个元素开始比较,结果符合预期了。

0 0