• 主元素问题


    x称为一个长度为n的数组a的主元素,如果这个数组里面等于x的元素数目不少于n/2个。

    例如,a={2,3,2,2,5,3,2,4,2}, x = 2就是主元素。给定包含n个元素的数组a,主元素问题就是判断数组a是否包含一个主元素x。

    三方法实现:

    方法一:求中位数,主元素肯定是中位数,否则该元素数量少于n/2则不是主元素:快速排序,然后确定中位数时间复杂度O(nlogn)

    方法二:分治的思想:

        若T 中存在主元素,则将T 分为两部分后,T 的主元素也必为两部分中至少一部分的主元素,因此可用分治法。
    将元素划分为两部分,递归地检查两部分有无主元素。算法如下:
    a. 若T 只含一个元素,则此元素就是主元素,返回此数。
          b. 将T 分为两部分T1 和T2(二者元素个数相等或只差一个),分别递归调用此方法求其主元素m1 和m2。
          c. 若m1 和m2 都存在且相等,则这个数就是T 的主元素,返回此数。
    d. 若m1 和m2 都存在且不等,则分别检查这两个数是否为T 的主元素,若有则返回此数,若无则返回空值。
    e. 若m1 和m2 只有一个存在,则检查这个数是否为T 的主元素,若是则返回此数,若否就返回空值。
    f. 若m1 和m2 都不存在,则T 无主元素,返回空值。

    方法三:思路比较新颖,原理是如果一个数组中存在一个主元素(个数大于n/2),则同时删除两个不相等的值,这个主元素不会改变。
    简单的说就一个大小为n数组中存在一个元素的个数大于n/2,则如果用这个数组中其他元素和该主元素进行抵消的话,最后剩下的一定是主元素,因为主元素个数最多。
    该方法可以在O(n)的时间内找到主元素,十分高效。

    方法一代码如下:

     1 #include <stdio.h>
     2 
     3 //求中位数的方法
     4 int swap(int *a, int *b)
     5 {
     6         int temp = 0;
     7         temp = *a; 
     8         *a = *b;
     9         *b = temp;
    10 }
    11 
    12 int partition(int *num, int start, int end)
    13 {
    14         int x = num[end];
    15         int i = start-1;
    16         int j;
    17         for (j = start; j < end; j++) {
    18                 if (num[j] <= x) {
    19                         i = i + 1;
    20                         swap(&num[i], &num[j]);
    21                 }
    22         }
    23         swap(&num[i+1], &num[end]);
    24         return i+1;
    25 
    26 }
    27 
    28 void quicksort(int *num, int start, int end)
    29 {
    30         if( start < end) {
    31                 int mid = partition(num, start, end);
    32                 quicksort(num, start, mid-1);
    33                 quicksort(num, mid+1, end);
    34         }
    35 }
    36 
    37 int main()
    38 {
    39         int i;
    40         int num1[]={2,8,7,1,3,5,6,4};
    41         int num[] = {2,3,1,2,2,2,5,4,2,2};
    42         quicksort(num, 0, 7);
    43         for (i = 0; i < 8; i++) {
    44                 printf("%d\n", num[i]);
    45         }
    46         int index = 9/2; //奇数n/2偶数n/2-1
    47         if (num[0] == num[index] || num[9] == num[index]) {
    48                 printf("main element exits: index = %d element = %d\n", index, num[index]);
    49         }
    50         else {
    51                 printf("main element not exits\n");
    52         }
    53 }

    方法二代码如下:

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 
     4 typedef struct _node{
     5         int data;
     6         int count;
     7 }*node;
     8 
     9 int checkNum(int *num, int p, int q, int data)
    10 {
    11         int count = 0;
    12         int i;
    13         for (i = p-1; i < q; i++) {
    14                 if (num[i] == data) {
    15                         count++;
    16                 }
    17         }
    18         return count;
    19 }
    20 
    21 node checkAnotherPart(int *num, int len, int p, int q, node nodec)
    22 {
    23         nodec->count = checkNum(num, p, q, nodec->data) + nodec->count;
    24         if (nodec->count >= len/2) {
    25                 return nodec;
    26         }
    27         else {
    28                 return NULL;
    29         }
    30 }
    31 node checkMaster(int *num, int p, int q)
    32 {
    33         node nodetmp = malloc(sizeof(node));
    34         node nodea = malloc(sizeof(node)); 
    35         node nodeb = malloc(sizeof(node));
    36         if (p == q) {
    37                 nodetmp->data = num[p-1];
    38                 nodetmp->count = 1;
    39                 return nodetmp;
    40         }
    41         int len = q - p + 1;
    42         int mid = p + len / 2;
    43         nodea = checkMaster(num, p, mid-1);
    44         nodeb = checkMaster(num, mid, q);
    45         if (nodea == NULL && nodeb == NULL) {
    46                 return NULL;
    47         }
    48         if (nodea == NULL && nodeb != NULL) {
    49                 return checkAnotherPart(num, len, p, mid-1, nodeb);
    50         }
    51         if (nodea != NULL && nodeb == NULL) {
    52                 return checkAnotherPart(num, len, mid, q, nodea);
    53         }
    54         if (nodea != NULL && nodeb != NULL) {
    55                 if (nodea->data == nodeb->data) {
    56                         nodea->count = nodea->count + nodeb->count;
    57                         return nodea;
    58                 }
    59                 else {
    60                         node nodec = checkAnotherPart(num, len, p, mid-1, nodeb); 
    61                         if (nodec != NULL) {
    62                                 return nodec;
    63                         }
    64                         else {
    65                                 return checkAnotherPart(num, len, mid, q, nodea);
    66                         }
    67                 }
    68         }
    69 
    70 }
    71 
    72 int main()
    73 {
    74 
    75         int num[] = {2,2,3,1,2,2,2,5,4,2,2};
    76         node masterNode = checkMaster(num, 1, 11);
    77         printf("num = %d count = %d\n", masterNode->data, masterNode->count);
    78 }

    方法三代码如下:

     1 #include <stdio.h>
     2 
     3 int mainElement(int *num, int n)
     4 {
     5         int seed = num[0];
     6         int count = 1;
     7         int i;
     8         for (i = 1; i < n; i++) {
     9                if (seed == num[i]) {
    10                        count++;
    11                }
    12                else {
    13                        if (count > 0) {
    14                                count--;
    15                        }
    16                        else {
    17                                seed = num[i];
    18                        }
    19                }
    20                 
    21         }
    22         count = 0;
    23         for (i = 0; i < n; i++) {
    24                 if (num[i] == seed) {
    25                         count++;
    26                 }
    27         }
    28         if (count >= n/2) {
    29                 return seed;
    30         }
    31         return 0; 
    32 }
    33 
    34 int main()
    35 {
    36         int num1[]={2,8,7,1,3,5,6,4};
    37         int num[] = {2,3,1,2,2,2,5,4,2,2};
    38         int mainElem = mainElement(num, 8);
    39         if (mainElem != 0) 
    40                 printf("main element is %d\n", mainElem);
    41         else 
    42                 printf("main element not exits\n");
    43 
    44 }

  • 相关阅读:
    SQL语句容易出现错误的地方-连载
    3D坦克大战游戏iOS源代码
    node.js setup wizard ended prematurely Win7安装nodejs失败解决方法
    Linux环境高级编程--出错处理(CLStatus)
    HT系统部署操作文档
    VC中常见的108个问题
    菜鸟nginx源代码剖析数据结构篇(十一) 共享内存ngx_shm_t
    Smalidea无源代码调试 android 应用
    MPAndroidChart开源图表库(三)之柱形图
    intent 显式意图和隐式意图之Activity的激活方式
  • 原文地址:https://www.cnblogs.com/taotao315/p/2952689.html
Copyright © 2020-2023  润新知