#寻找数列中的主元素
已知一个整数序列,若一个元素个数m大于元素总个数n的一半,称为主元素。
方法一:线性法
分两步走:1.选取候选的主元素:依次扫描所给数组中的每个整数,将遇到的第一个数N保存在C中,记N出现次数为1,然后接着往后扫描,若下个数仍然是N,则次数加一,否则减一,当计数为0时,将遇到的下一个整数保存到C中,计数为1,重新开始新一轮计数。
2。重新扫描,统计C出现的次数是否大于N/2;
这个方法一开始不怎么理解,后来一推发现只要有主元素,那么到最后C一定存的是主元素,因为个数大于N/2。
方法二:中位数法
这里我们利用求中位数的方法,若一个序列有主元素,那么我们先将序列排序,那么有序序列的主元素必定是中位数,所以我们先求出序列的中位数,然后再检查其个数是否大于N/2,从而确定序列是否含有主元素,这里排序我们选择快速排序的方法,代码如下:
主元素法代码:
int Majority(seqlist *L)
{
int i,c=L->data[0],count=1;
for(i=1;i<L->n;i++)
{
if(L->data[i]==c)
count++;
else{
if(count>0)
count--;
else
{
c=L->data[i];
count=1;
}
}
}
if(count>0)
{count=0;
for(i=0;i<L->n;i++)
if(L->data[i]==c)
count++;
if(count>(L->n)/2) return c;
else return -1;
}
}
方法二:中位数法,代码如下
#include<stdio.h>
#include<stdlib.h>
#define initsize 100
typedef int Datatype;
typedef struct{
Datatype *data;
int n;
int maxsize;
}seqlist;
void Init(seqlist *L)
{
L->data=(Datatype*)malloc(sizeof(Datatype)*initsize);
L->n=0;
L->maxsize=initsize;
}
void Creat(seqlist *L,int n)
{
for(int i=0;i<n;i++)
{
scanf("%d",&L->data[i]);
}
L->n=n;
}
int Partition(seqlist *L,int low,int high)
{
Datatype pivot=L->data[low];
while(low<high)
{
while(low<high&&L->data[high]>=pivot)
--high;
L->data[low]=L->data[high];
while(low<high&&L->data[low]<=pivot)
++low;
L->data[high]=L->data[low];
}
L->data[low]=pivot;
return low;
}
void QuickSort(seqlist *L,int low,int high)
{
if(low<high)
{
int pivotpos=Partition(L,low,high);//&
QuickSort(L,low,pivotpos-1);
QuickSort(L,pivotpos+1,high);
}
}
void show(seqlist L)
{
for(int i=0;i<L.n;i++)
{if(i!=L.n-1)
printf("%d ",L.data[i]);
else
printf("%d\n",L.data[i]);
}
}
int count(seqlist L,int x)
{ int m=0;
for(int i=0;i<(L.n)-1;i++)
{
if(L.data[i]==x)
m++;
}
return m;
}
void main()
{
int n,m;
seqlist L;
Init(&L);
printf("请输入序列的长度:");
scanf("%d",&n);
printf("请输入序列:");
Creat(&L,n);
printf("你输入的序列是:");
show(L);
QuickSort(&L,0,n-1);
printf("排序后的序列是:");
show(L);
m=count(L,L.data[n/2]);
if(m>n/2)
{
printf("主元素为:%d",L.data[n/2]);
}
else
printf("无主元素!");
system("pause");
}