加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

寻找数组中第K大数

发布时间:2020-12-14 02:18:23 所属栏目:大数据 来源:网络整理
导读:1、 寻找数组中的第二大数 using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace ConsoleApplication2{ class Program { static void Main(string[] args) { int[] ar = { 1,25,3,4,

1、寻找数组中的第二大数

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            int[] ar = { 1,25,3,4,9,6,7,10};
            try
            {
                Console.WriteLine(get2rdMax(ar).ToString());
            }
            catch (Exception exc)
            {
                Console.WriteLine(exc.Message);
            }
            Console.ReadKey();
        }
        private static int get2rdMax(int[] ar)
        {
            int max = ar[0],s_max = ar[0];
            for (int i = 0; i < ar.Length; i++)
            {
               if (ar[i] > s_max)   //后面的跟第二大先比,if大,赋值给第二大,
                {
                    s_max = ar[i];    
                                      //第二大再跟最大比,if还大,第二大跟最大交换
                    if (s_max > max) //交换。一次最终:max>s_max>ar[i]
                    {                        
                        int temp;
                        temp = max;
                        max = s_max ;
                        s_max  = temp ;
                    }
                }
            }
            if (max == s_max)  //至少有两个一样的最大值
                throw new Exception("no second max!");
            else
                return s_max;
        }
    }
}
2、 寻找数组中的第K大数

求一个数组中第k大的数,我第一印象是冒泡,因为只要冒泡k趟即可,第一趟冒泡第一大,第二次冒泡第二大,第k次冒泡第k大,时间复杂度为O(kn),n为数组长度。但是我们都知道快速排序是对冒泡的改进,降低冒泡的递归深度,使时间复杂度降低到O(nlgn),为什么不用快排呢?那么快排的时间复杂度又是多少呢?

因为快排每次将数组划分为两组加一个枢纽元素,每一趟划分你只需要将k与枢纽元素的下标进行比较,如果比枢纽元素下标大就从右边的子数组中找,如果比枢纽元素下标小从左边的子数组中找,如果一样则就是枢纽元素,找到,如果需要从左边或者右边的子数组中再查找的话,只需要递归一边查找即可,无需像快排一样两边都需要递归,所以复杂度必然降低。

最差情况如下:假设快排每次都平均划分,但是都不在枢纽元素上找到第k大

第一趟快排没找到,时间复杂度为O(n),第二趟也没找到,时间复杂度为O(n/2),。。。。。,第k趟找到,时间复杂度为O(n/2k),所以总的时间复杂度为

O(n(1+1/2+....+1/2k))=O(n),明显比冒泡快,虽然递归深度是一样的,但是每一趟时间复杂度降低。

快排求第k大数代码如下:(C#版)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 求数组第K大的数
{
    class Program
    {
        static void Main(string[] args)
        {
            //int[] ar = { 1,2,5,17,28,39,8,10};
            //Array.Sort(ar);   //此方法实现的就是快速排序。。
            //Console.WriteLine("数组中第12大的数是:"+ar[12-1]);
            //Console.ReadLine( );

            int[] ar = { 1020,222,833,834,235,36,10 };
            Console.WriteLine("表中有元素" + ar.Length + "个,下标是0—" + (ar.Length - 1));
            for (int i = 0; i < ar.Length; i++)
            {
                Console.Write(ar[i] + "-");
            }

            QuickSort(ar,ar.Length - 1); //快速排序
            Console.WriteLine();
            for (int i = ar.Length - 1; i >= 0; i--)  //从大到小排
            {
                Console.Write(ar[i] + "-");
            }

            Console.WriteLine("输入你想找的第K大数(正整数):");
            string K = Console.ReadLine();
            int k = Convert.ToInt32(K);
            Console.WriteLine(ar[ar.Length - k]);
            Console.ReadLine();
        }

        public static void QuickSort(int[] a,int low,int high)
        {
            int i = low;
            int j = high;
            int tmp = a[low];  //分界点
            while (low < high)
            {
                while ((low < high) && (a[high] >= tmp)) //后边 比tmp大的 不动
                {
                    --high;
                }
                a[low] = a[high];  //将 比tmp小的放在前面,low位置


                while ((low < high) && (a[low] <= tmp))   //前面 比tmp小的 不动
                {
                    ++low;
                }
                a[high] = a[low];  //将 比tmp大的放在后面,high位置
                //直到此时  low=high                                           
            }
            a[high] = a[low] = tmp; // 此时low=high,就完成了以tmp值来分界


            //分别对前后两部分来  快速排序
            if (i < low - 1)   //对tmp 前面的数(0到low-1) 递归调用,,此时【low】==tmp,low=high 
            {
                QuickSort(a,i,low - 1);
            }
            if (low + 1 < j)   //对tmp 后面的数(low+1到j) 递归调用,,此时【low】==tmp,low=high
            {
                QuickSort(a,low + 1,j);
            }
        }
    }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读