编程之美2.5:寻找最大的K个数

 

引申:寻找第k大的数:

方法一:

// 选择第k大的数(通过改进快速排序来实现)
        public static void SelectShort(int[] array, int low, int high, int k, out int value)
        {
            int i = low;
            int j = high;
            int tempItem = array[low];
            value = int.MinValue;

            while (low < high)
            {
                while (array[high] > tempItem
                    && high > low)
                {
                    high--;
                }

                if (low < high)
                {
                    array[low] = array[high];
                    low++;

                    while (array[low] <= tempItem
                        && low < high)
                    {
                        low++;
                    }

                    array[high] = array[low];
                    high--;
                }
            }

            array[low] = tempItem;


            if (low == array.Length - k)
            {
                value = array[low];
                return;
            }
            else if (low < array.Length -k) // 第k个元素在右分支中
            {
                if (low + 1 < j)
                {
                    SelectShort(array, low + 1, j, k, out value);
                }               
            }
            else // (low > k-1)第k个元素在左分支中
            {
                if (i < low - 1)
                {
                    SelectShort(array, i, low - 1,k,out value);
                }               
            }            
        }

 方法二:

借助编程之美的思想,求前k个最大的数,其中最小的就是。

  // 创建最大堆
        public static void CreateStack(int[] array, int startIndex, int lastIndex)
        {
            for (int root = lastIndex / 2; root >= startIndex; root--)
            {
                int currentRoot = root;
                int leftLeafIndex = 2 * root + 1; // 左孩子
                int rightLeafIndex = leftLeafIndex +1; // 右孩子

                while (leftLeafIndex <= lastIndex)
                {
                    if (leftLeafIndex < lastIndex
                        && rightLeafIndex <= lastIndex
                        && array[leftLeafIndex] < array[rightLeafIndex])// 右孩子存在而且右孩子大于左孩子
                    {
                        leftLeafIndex++;
                    }

                    if (array[leftLeafIndex] > array[root])
                    {
                        int temp = array[root];
                        array[root] = array[leftLeafIndex];
                        array[leftLeafIndex] = temp;

                        currentRoot = 2 * currentRoot + 1; //继续寻找是否到了叶子结点
                        leftLeafIndex = 2 * currentRoot + 1;
                    }
                    else
                    {
                        break;
                    }
                }
            }
        }

        //堆排序
        public static void StackSort(int[] arrary)
        {
            CreateStack(arrary, 0, arrary.Length - 1);

            int temp;

            for (int j = arrary.Length - 1; j > 0; j--)
            {
                temp = arrary[j];
                arrary[j] = arrary[0];
                arrary[0] = temp;

                CreateStack(arrary, 0, j - 1);
            }
        }

 

posted on 2014-01-07 14:52  higirle  阅读(356)  评论(0编辑  收藏  举报