• 中位数与第K小元素


    算法实际上是模仿快速排序算法设计出来的,其基本思想也是对输入数组进行递归划分,与快速排序不同的是,它只对划分出来的子数组之一进行递归处理;

    int randompartition(int a[],int l,int r)
    {
        int i=l-1,j=r,v=a[r],tmp;
        for(;;)
        {
            while(a[++i]<v);
            while(a[--j]>v)if(j==l)break;
            if(i>=j)break;
            tmp=a[i];
            a[i]=a[j];
            a[j]=tmp;
        }
        tmp=a[i];a[i]=a[r];a[r]=tmp;
        return i;
    }

    randompartition产生的划分基准是随机的,在这个条件下,可以证明算法randomselect可以在o(n)平均时间内找出n个输入元素的第k小元素。

    消除randomselect尾递归的算法如下:

     1 int randomselect(int a[],int l,int r,int k)
     2 {
     3     int i,j;
     4     while(l<r)
     5     {
     6         i=randompartition(a,l,r);
     7         j=i-l+1;
     8         if(j==k)
     9             return a[i];
    10         if(j>k)
    11             r=i-1;
    12         else
    13         {
    14             l=i+1;
    15             k-=j;
    16         }
    17     }
    18     return ((r<i)?a[l]:a[r]);
    19 }

    解决算法与数据结构实验题10.1神谕者:

     1  
     2             #include<stdio.h>
     3 int a[50005];
     4 int randompartition(int a[],int l,int r)
     5 {
     6     int i=l-1,j=r,v=a[r],tmp;
     7     for(;;)
     8     {
     9         while(a[++i]<v);
    10         while(a[--j]>v)if(j==l)break;
    11         if(i>=j)break;
    12         tmp=a[i];
    13         a[i]=a[j];
    14         a[j]=tmp;
    15     }
    16     tmp=a[i];a[i]=a[r];a[r]=tmp;
    17     return i;
    18 }
    19 int randomselect(int a[],int l,int r,int k)
    20 {
    21     int i,j;
    22     while(l<r)
    23     {
    24         i=randompartition(a,l,r);
    25         j=i-l+1;
    26         if(j==k)
    27             return a[i];
    28         if(j>k)
    29             r=i-1;
    30         else
    31         {
    32             l=i+1;
    33             k-=j;
    34         }
    35     }
    36     return ((r<i)?a[l]:a[r]);
    37 }
    38 int main()
    39 {
    40     int n,m,i,len,x,y;
    41     scanf("%d %d",&n,&m);
    42     for(i=0;i<n;i++)
    43     {
    44         scanf("%d",&a[i]);
    45     }
    46     len=n;
    47     for(i=0;i<m;i++)
    48     {
    49         scanf("%d %d",&x,&y);
    50         if(x==0)
    51             a[len++]=y;
    52         else
    53             printf("%d
    ",randomselect(a,0,len-1,y));
    54     }
    55     return 0;
    56 
    57 }
    58 
    59         
    View Code
  • 相关阅读:
    Vue学录 (第三章)
    Vue学录 (第二章)
    Vue 学录 (第一章)
    SpringBoot 学集 (第七章) 数据访问
    Leetcode789 阻碍逃脱者 曼哈顿距离
    Leetcode707 设计链表 双向链表实现
    leetcode 743 网络延迟时间 Dijkstra算法
    Leetcode676 实现魔法字典
    Leetcode443 压缩字符串 双指针原地压缩算法
    Leetcode23 合并K个升序链表
  • 原文地址:https://www.cnblogs.com/zeze/p/3432118.html
Copyright © 2020-2023  润新知