一 概述
在順序表L=(a1,a2,...,an-1)中,若存在ap1=ap2=...=apm=x,且m > n/2(0<=pk<n,1<=k<=m),則稱x爲A的主元素。其中p爲主元素在順序表中出現的位置,而m爲主元素在順序表中出現的次數。
如L = (0,4,4,3,4,7,4,4),則主元素爲4;而L = (0,4,4,3,4,1,5,7)中不存在主元素。
二 算法思想
算法的策略是從前向後掃描數組元素,標記出一個可能成爲主元素的元素Main。然後進行計數,確認Main是否爲主元素。
算法的設計步驟:
- 選取候選的主元素,依次掃描所給數組中的每個整數,將第一個遇到的整數保存到Temp中,記錄Main出現的次數爲1;若下一個整數仍等於Main,則計數count加1,否則計數count減1;當計數減至0是,將下一個整數保存到Temp中,並重新計數count爲1,開始新一輪的計數,即從當前位置開始重複上述過程,直到掃描完全部的表元素。
- 再次掃描順序表,統計temp中元素出現的次數sum,若sum大於n/2,則temp中的元素爲主元素;否則,序列中不存在主元素。
三 算法實現
#include<iostream>//輸入頭
using namespace std;//標準輸入輸出
typedef int Status;
typedef int ElemType;
#define MAXSIZE 100
#define ERROR -1
#define OK 0
typedef struct {
ElemType *elem;
int length;
}SqList;
Status init_Queue(SqList &L){
L.elem = new ElemType[MAXSIZE]; //初始化最大長度的順序表
if(!L.elem){
return ERROR; //初始化失敗
}
L.length = 0; //初始時數據表爲空
return OK;
}
int mainNum(SqList &L) {
ElemType temp = L.elem[0];
int count = 1,sum = 0,i;
for(i = 1; i < L.length; i++) {
if(temp == L.elem[i]) {
count++;
}else if(count > 0) {
count--;
}else{
temp = L.elem[i];
count = 1;
}
}
if (count > 0){
for(i = 0; i < L.length; i++) {
if(temp == L.elem[i]) {
sum++;
}
}
}
if(sum < L.length/2){
temp = -1;
}
return temp;
}
int main(){
SqList L;
cout<<"1.初始化順序表!\n";
cout<<"2.輸入8個不同的數字!\n";
cout<<"3.順序表L中的主元素!\n";
cout<<"0.退出!"<<endl<<endl;
int elect = -1;
while(elect !=0){
cout<<"請選擇你的後續操作:";
cin>>elect;
switch(elect){
case 1:
if(!init_Queue(L)){
cout<<"初始化順序表成功!"<<endl;
}else{
cout<<"初始化順序表失敗!"<<endl;
}
break;
case 2:
cout<<"請輸入8不同數字:" ;
for(int i = 0; i < 8; i++){
cin>>L.elem[i];
L.length = 8;
}
break;
case 3:
if(mainNum(L) == -1){
cout<<"順序表L中不存在主元素且返回值爲:"<<mainNum(L)<<endl;
}else{
cout<<"順序表L中的主元素:"<<mainNum(L)<<endl;
}
break;
}
}
return 0;
}
順序表中存在主元素的結果:
順序表中不存在主元素的結果:
四 算法的時間複雜度和空間複雜度分析
時間複雜度:根據順序查找的時間複雜度分析,該算法的時間複雜度爲O(n);
空間複雜度:根據算法本地工作空間複雜度,該算法的所需的輔助空間爲常量,所以該算法的空間複雜度爲O(1);