예제 #1
0
        /// <summary>
        /// * 二分查找算法:
        /// * 要求:有序,线性结构
        /// * 时间复杂度O[log(n)]
        /// * 循环实现
        /// * middle = (low + high) / 2;
        /// </summary>
        /// <param name="arr"></param>
        /// <param name="des"></param>
        /// <returns></returns>
        public int Binary_Search(IpRecord[] arr, long key, out SearchRecord recorder)
        {
            recorder = new SearchRecord();

            int search_count = 0;

            int low  = 0;
            int high = arr.Length - 1;

            while (low <= high)
            {
                ++search_count;

                int middle = (low + high) / 2;
                //先拿中间的值与查找的值比较,大于中间的值,说明查找的值索引在[low,middle)

                recorder.Progress.Add(SearchRecord.FormatProgress(middle, middle));
                if (arr[middle].CompareTo(key) == 0)
                {
                    recorder.IpRecord = arr[middle];
                    recorder.Count    = search_count;
                    recorder.Index    = middle;

                    return(middle);
                }
                else if (arr[middle].CompareTo(key) > 0)   // > key
                {
                    high = middle - 1;

                    recorder.Progress.Add("*" + SearchRecord.FormatProgress(low, high));
                }
                else
                {
                    low = middle + 1;

                    recorder.Progress.Add("*" + SearchRecord.FormatProgress(low, high));
                }
            }

            recorder.Index = -1;
            return(-1);
        }
예제 #2
0
        /// <summary>
        /// * 斐波那契 查找:
        /// * 要求:有序,线性结构
        /// * 时间复杂度O[log(n)]
        /// * middle = low + Fib[k - 1] - 1;
        ///
        /// 修改部分:
        /// 传入数组之后不创建临时数组, 根据数组长度在斐波那契数组中index值,
        /// 判断 if (mid >= arr.Length) {
        ///     high = mid - 1; fibIndex = fibIndex - 1;
        /// } else {
        ///     // 原来判断方法
        /// }
        /// </summary>
        /// <param name="arr">需要查找的原数组</param>
        /// <param name="key">查找的元素</param>
        /// <param name="recorder"></param>
        /// <param name="fibIndex">数组长度在斐波那契数组中index值, 如果不提供, 会自动计算</param>
        /// <returns></returns>
        public int Fibonacci_Search_Improved(IpRecord[] arr, long key, out SearchRecord recorder, int fibIndex = -1)
        {
            recorder = new SearchRecord();

            int search_count = 0;

            int low  = 0;
            int high = arr.Length - 1;
            int mid  = 0;

            //斐波那契分割数值下标
            if (fibIndex < 0)
            {
                int k = 0;

                //获取斐波那契分割数值下标
                while (arr.Length > Fib[k] - 1)
                {
                    k++;
                }

                fibIndex = k;
            }

            while (low <= high)
            {
                ++search_count;

                // low:起始位置
                // 前半部分有f[k-1]个元素,由于下标从0开始
                // 则-1 获取 黄金分割位置元素的下标
                mid = low + Fib[fibIndex - 1] - 1;

                recorder.Progress.Add(SearchRecord.FormatProgress(mid, mid));

                if (mid >= arr.Length)
                {
                    // 如果超出数组长度, 选哟查找的元素肯定在分割点左侧
                    // 这样判断就不需要新建和补齐临时数组了
                    high = mid - 1;

                    fibIndex = fibIndex - 1;

                    recorder.Progress.Add(SearchRecord.FormatProgress(low, high));
                }
                else
                {
                    if (arr[mid].CompareTo(key) > 0)    // > key
                    {
                        // 查找前半部分,高位指针移动
                        high = mid - 1;
                        // (全部元素) = (前半部分)+(后半部分)
                        //   f[k]  =  f[k-1] + f[k-1]
                        // 因为前半部分有f[k-1]个元素,所以 k = k-1
                        fibIndex = fibIndex - 1;

                        recorder.Progress.Add(SearchRecord.FormatProgress(low, high));
                    }
                    else if (arr[mid].CompareTo(key) < 0)   // arr[mid] < key
                    {
                        // 查找后半部分,高位指针移动
                        low = mid + 1;
                        // (全部元素) = (前半部分)+(后半部分)
                        //   f[k]  =  f[k-1] + f[k-1]
                        // 因为后半部分有f[k-2]个元素,所以 k = k-2
                        fibIndex = fibIndex - 2;

                        recorder.Progress.Add(SearchRecord.FormatProgress(low, high));
                    }
                    else
                    {
                        recorder.IpRecord = arr[mid];
                        recorder.Count    = search_count;

                        recorder.Index = mid;
                        return(mid);
                    }
                }
            }

            recorder.Index = -1;
            return(-1);
        }