1. 程式人生 > >眾數問題-遞迴和分治

眾數問題-遞迴和分治

問題描述

       給定一個數組,找出其中出現次數最多的那個元素(即眾數)。

例如:


1 2 2 2 3 5

眾數是: 2

演算法思路:先排序  後用分治法計算求解

分治法求解程式碼如下:

#include <iostream>
#include <stdlib.h>
#include <time.h>

using namespace std;

/*----------快速排序*/
int Partition(int *a , int l , int r)
{
        int i = l , j = r+1;
        int x = a[l];

        while(true){
                while(a[++i] < x && i < r);
                while(a[--j] > x);
                if(i >= j)      break;
                swap(a[i] , a[j]);
        }
        a[l] = a[j];
        a[j] = x;

        return j;
}

/*------------隨機選擇中位數排序*/
int RandomizedPartitiom(int *a , int l , int r)
{
        srand(time(NULL));
        int i = rand()%(r-l)+l;

        swap(a[i] , a[l]);
        return  Partition(a , l , r);
}

/*----------------按中位數劃分成兩段*/
void split(int *a , int m , int l , int r , int *left , int *right)
{
        int med = a[m];
        *left = *right = m;
        /*--------------------將 == 中位數的元素剔除:及 right-left+1 == 眾數的個數*/
        while(a[--(*left)] == med);
        while(a[++(*right)] == med);
        (*left)++;
        (*right)--;
}

/*---------------分治法求解*/
void mode(int *a , int l , int r , int *largest , int *count)
{
        int m = RandomizedPartitiom(a , l , r);//----查詢中位數

        int left , right;
        split(a , m , l , r , &left , &right);//---按中位數分成2段

        if(*largest < right-left+1){//-----保留眾數個數最大值,及眾數下標
                *largest = right-left+1;
                *count = m;
        }
        if(left-l > *largest)    mode(a , l , left-1 , largest , count);//左邊個數大於眾數個數
        if(r-right > *largest)   mode(a , right+1 , r , largest , count);//右邊個數大於眾數個數
}

/*----------main()*/
int main()
{
        int n;
        cout<<"請輸入集合S的元素個數n:"<<endl;
        cin>>n;
        int a[n];
        int largest = 0 , count = 0;
        cout<<"請輸入元素:"<<endl;
        for(int i = 0 ; i < n ; i++)
                cin>>a[i];
        mode(&a[0] , 0 , n-1 , &largest , &count);
        cout<<"眾數是:"<<a[count]<<"\t重數是:"<<largest<<endl;
        return 0;
}
/*
請輸入集合S的元素個數n:
6
請輸入元素:
1 2 2 2 3 5
眾數是:2       重數是:3

Process returned 0 (0x0)   execution time : 7.504 s
Press any key to continue.

*/