C++程式查詢陣列中第二大的元素


陣列的目的是將類似型別的資料儲存在一系列記憶體位置中,這些記憶體位置可以使用基地址和索引訪問。我們在許多不同的應用程式中使用陣列來儲存各種目的的資料。查詢最小和最大元素是陣列在許多應用程式(包括排序等)中所需的相當常見的示例。在本文中,我們將瞭解如何在 C++ 中從陣列中找到第二大的元素。

透過示例理解概念

Given array A = [89, 12, 32, 74, 14, 69, 45, 12, 99, 85, 63, 32]
The second largest element is 89

在上面的示例中,陣列中有 12 個元素。陣列中最大的元素是 99,第二大的元素是 89。在第一種方法中,要查詢陣列中的第二大元素,我們只需按升序或降序對元素進行排序,然後直接返回倒數第二個或第二個元素即可獲得第二大元素。演算法如下所示:

演算法

  • 獲取大小為 n 的陣列 A

  • 根據其值的非遞減順序對陣列 A 進行排序

  • 返回 A[ 1 ] // 因為第 0 個索引儲存最大元素

示例

#include <iostream>
#include <algorithm>
# define Z 30

using namespace std;

void displayArr(int arr[], int n ) {
   for( int i = 0; i < n; i++ ){
      cout << arr[ i ] << ", ";
   } 
   cout << endl;
} 

int getSecondLargest( int A[], int n ){
   sort( A, A + n, greater<int>() );
   return A[ 1 ];
}

int main() {
   int arr[ Z ] = {84, 56, 21, 32, 74, 96, 85, 41, 21, 94, 20, 37, 36, 75, 20};
   int n = 15;
   
   cout << "Given array elements: ";
   displayArr( arr, n);
   
   cout << "The second largest element: " << getSecondLargest( arr, n ); 
}

輸出

Given array elements: 84, 56, 21, 32, 74, 96, 85, 41, 21, 94, 20, 37, 36, 75, 20, 
The second largest element: 94

使用雙重遍歷

上述方法看起來很簡單,但這種方法對於這個問題效率不高。由於我們使用的是排序,因此至少需要 O(n.log n) 的時間來執行排序。但是我們也可以線上性時間內解決這個問題。在這種方法中,我們遍歷元素陣列兩次並找到第二大元素。讓我們檢查一下演算法。

演算法

  • 獲取大小為 n 的陣列 A

  • largest := -infinity

  • secLargest := -infinity

  • 對於陣列 A 中的每個元素 e,執行

    • 如果 e 大於 largest,則

      • largest = e

    • 結束 if

  • 結束 for

  • 對於陣列 A 中的每個元素 e,執行

    • 如果 e 大於 secLargest 但小於 largest,則

      • secLargest = e

    • 結束 if

  • 結束 for

  • 返回 secLargest

示例

#include <iostream>
#include <algorithm>
# define Z 30

using namespace std;

void displayArr(int arr[], int n ) {
   for( int i = 0; i < n; i++ ){
      cout << arr[ i ] << ", ";
   } 
   cout << endl;
} 

int getSecondLargest( int A[], int n ){
   int largest = -99999;
   for( int i = 0; i < n; i++ ) {
      if( A[i] > largest ){
         largest = A [ i ]; 
      }   
   }
   int secLargest = -99999;
   for( int i = 0; i < n; i++ ) {
      if( A[i] > secLargest && A[i] < largest ){
         secLargest = A [ i ]; 
      }   
   }
   return secLargest;
}

int main() {
   int arr[ Z ] = {84, 56, 21, 32, 74, 96, 85, 41, 21, 94, 20, 37, 36, 75, 20};
   int n = 15;
   
   cout << "Given array elements: ";
   displayArr( arr, n);
   
   cout << "The second largest element: " << getSecondLargest( arr, n ); 
}

輸出

Given array elements: 84, 56, 21, 32, 74, 96, 85, 41, 21, 94, 20, 37, 36, 75, 20, 
The second largest element: 94

使用單次遍歷

上述解決方案遍歷陣列兩次。在第一次執行中,從陣列中找到最大元素,然後在第二次執行中,搜尋大於最大元素但不小於第一個最大元素的元素。由於陣列是線性資料結構,並且每次遍歷都需要 O(n) 的時間,因此解決方案最終花費的時間為 O(2n),這也為線性,類似於 O(n)。但這並不是一個有效的解決方案,我們可以只通過一次遍歷來解決它。讓我們看看它的演算法。

演算法

  • 獲取大小為 n 的陣列 A

  • largest := A[0]

  • 從 1 到 n - 1 開始索引遍歷,執行

    • 如果當前元素 A[ i ] 大於 largest,則

      • secLargest := largest

      • largest := A[ i ]

    • 否則,當 A[ i ] 在 largest 和 secLargest 之間時,則

      • secLargest := A[ i ]

    • 結束 if

  • 結束 for

  • 返回 secLargest

示例

#include <iostream>
#include <algorithm>
# define Z 30

using namespace std;

void displayArr(int arr[], int n ) {
   for( int i = 0; i < n; i++ ){
      cout << arr[ i ] << ", ";
   } 
   cout << endl;
} 

int getSecondLargest( int A[], int n ){
   int largest = A[ 0 ];
   int secLargest = -9999;
   for( int i = 1; i < n; i++ ) {
      if( A[i] > largest ){
         secLargest = largest; 
         largest = A[ i ];
      }   
      else if( secLargest < A[ i ] && A[ i ] != largest ) {
         secLargest = A[ i ];
      }
   } 
   return secLargest;
}

int main() {
   int arr[ Z ] = {84, 56, 21, 32, 74, 96, 85, 41, 21, 94, 20, 37, 36, 75, 20};
   int n = 15;
   
   cout << "Given array elements: ";
   displayArr( arr, n);
   
   cout << "The second largest element: " << getSecondLargest( arr, n ); 
}

輸出

Given array elements: 84, 56, 21, 32, 74, 96, 85, 41, 21, 94, 20, 37, 36, 75, 20, 
The second largest element: 94

結論

在本文中,我們看到了三種從給定陣列中查詢第二大元素的不同方法。第一種方法是使用排序。但是,此解決方案效率不高,至少需要 O(n log n) 的時間。後來的解決方案效率更高,因為它們需要線性時間。第二個解決方案是使用雙重遍歷陣列來執行,這也可以透過單次遍歷進行最佳化,如第三個解決方案所示。

更新於: 2022年12月13日

5K+ 次瀏覽

開啟你的 職業生涯

透過完成課程獲得認證

開始學習
廣告