二分查找法优化插入排序

通俗的插排是对一个整型数组进行升序排序,可以看出每个元素插入到队列中经过两个步骤:先是挨个比较,找到自己所在的位置;然后把后面的数据全部移位,然后把元素插入。

要把数据插入,移位是必不可少了。那么,挨个比较倒是可以优化,因为要插入的队列已经是排序好的,我们可以使用二分法来减少比较的次数。

二分法的时间复杂度为O(log 2 n),而线性查找的复杂度为O(n)。

在对50000个随机数进行测试比较中,发现加了二分查找的插排比普通的插排速度快了将近一倍!(通俗插排7888ms,优化插排4852ms)

下面是测试程序源码:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Diagnostics;
 4 using System.Linq;
 5 using System.Text;
 6 using System.Threading.Tasks;
 7
 8 namespace InsertSort
 9 {
10     class Program
11     {
12         static void Main(string[] args)
13         {
14             int[] arr = new int[50000];
15
16             Random rd = new Random();
17             for (int i = 0; i < arr.Length; i++)
18             {
19                 arr[i] = rd.Next();
20             }
21
22             Stopwatch watch = new Stopwatch();
23             watch.Start();
24             //InsertSortCommon(arr);        //通俗插排7888ms
25             InsertSortOptimize(arr);        //优化插排4852ms
26             watch.Stop();
27
28             Console.WriteLine(watch.ElapsedMilliseconds.ToString());
29         }
30
31         /// <summary>
32         /// 通俗插排
33         /// </summary>
34         public static void InsertSortCommon(int[] arr)
35         {
36             int temp, j;
37             for (int i = 1; i < arr.Length; i++)
38             {
39                 temp = arr[i];
40                 for (j = i - 1; j >= 0 && temp < arr[j]; j--)
41                 {
42                     arr[j + 1] = arr[j];
43                 }
44                 arr[j + 1] = temp;
45             }
46         }
47
48         /// <summary>
49         /// 优化插排
50         /// </summary>
51         public static void InsertSortOptimize(int[] arr)
52         {
53             int temp, j, position;
54             for (int i = 1; i < arr.Length; i++)
55             {
56                 temp = arr[i];
57                 position = BinSearchNum(arr, temp, 0, i - 1);
58                 for (j = i - 1; j >= position; j--)
59                     arr[j + 1] = arr[j];
60                 arr[j + 1] = temp;
61             }
62         }
63
64         /// <summary>
65         /// 二分查找(因为不是查找与其相等值得位置,所以和传统的二分查找略有不同)
66         /// </summary>
67         public static int BinSearchNum(int[] arr, int searchNum, int low, int high)
68         {
69             int mid = 0;
70             while (low <= high)
71             {
72                 mid = (low + high) / 2;
73                 if (searchNum < arr[mid])
74                     high = mid - 1;
75                 else if (searchNum > arr[mid])
76                     low = mid + 1;
77                 else
78                     return mid;
79             }
80             return low;//这块的返回值需要注意,为什么要这么写?
81         }
82     }
83 }

参考文献:

http://hi.baidu.com/sangwf/item/5cc1ae54d9a2889408be1722

时间: 2024-10-14 09:55:21

二分查找法优化插入排序的相关文章

Java学习 (七)、数组,查找算法,二分查找法,冒泡排序,选择排序,插入排序

一.常用数组查找算法 工作原理:它又称为顺序查找,在一列给定的值中进行搜索,从一端的开始逐一检查每个元素,知道找到所需元素的过程. 例1:查找指定的数在数组中出现的位置,找到返回下标,找不到返回-1 1 import java.util.Scanner; 2 public class LinearSearch{ 3 public static void main(String []argas) 4 { 5 int [] array={10,100,90,65,80,92}; 6 System.o

选择、冒泡排序,二分查找法以及一些for循环的灵活运用

import java.util.Arrays;//冒泡排序 public class Test { public static void main(String[] args) { int[] array = { 31, 22, 15, 77, 52, 32, 18, 25, 16, 7 }; // 冒泡 --> 两两比较 --> 提取出最大的数 在最后一位 //拿第一位和它后面的一位进行 两两比较 System.out.println(Arrays.toString(array)); fo

二分查找法

今年是大年初四,晚上闲的没事儿干,在手机上随手写了二分查找法,对有序数组或者循环有序数组都挺管用! public int binarySearch(int []nums,int key){ return binarySearch(nums,key,0,nums.length); } public int binarySearch(int []nums,int key,int left,int right){ int mid = (left + right) / 2; if(left <= rig

冒泡排序法与二分查找法

冒泡排序(Bubble Sort) 是一种计算机科学领域的较简单的排序算法. 它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成. 这个算法的名字由来是因为越大的元素会经由交换慢慢“浮”到数列的顶端,故名. 算法原理 冒泡排序算法的运作如下:(从后往前) 比较相邻的元素.如果第一个比第二个大,就交换他们两个. 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对.在这一点,最后的元素应该

【C/C++学院】(3)二维数组/二分查找法/指针/模块注射

1.二维数组 二维数组可以当做一个一维数组, 每一个元素又是一个一维数组. #include <stdio.h> #include <stdlib.h> void main() { int a[3][4] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }; for (int i = 0; i < 3; i++) { for (int j = 0; j < 4; j++) { printf("%d,%d,%d,%x,%x &

php 二分查找法算法详解

一.概念:二分查找又称折半查找,优点是比较次数少,查找速度快,平均性能好:其缺点是要求待查表为有序表,且插入删除困难.因此,折半查找方法适用于不经常变动而查找频繁的有序列表.首先,假设表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功:否则利用中间位置记录将表分成前.后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表.重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功. 二.代

[c/c++] programming之路(15)、多维数组和二分查找法,小外挂

一.多维数组 1 #include<stdio.h> 2 #include<stdlib.h> 3 4 void main(){ 5 int num[3][4]; 6 int i,j; 7 for (i = 0; i < 3; i++) 8 { 9 for (j = 0; j < 4; j++) 10 { 11 num[i][j]=4*i+j+1; 12 printf("%-3d",num[i][j]); 13 } 14 printf("\

二分查找法以及拉格朗日插值查找法

不管是二分查找法还是拉格朗日法,必须先排序,否则无法使用. 插值查找发速度比二分查找法要快 插值查找法,数据均匀是1次找到,不均匀是多次,即使这样这样它也是快于二分的. 那个1.0挺重要的一个技巧,将那个比例变成实数. #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include <stdlib.h> #define N 1024 void search(int a[N],int num) { int tou = 0; int

查询资料:二分查找法

二分查找 编辑 同义词 二分查找法一般指二分查找 二分查找又称折半查找,优点是比较次数少,查找速度快,平均性能好:其缺点是要求待查表为有序表,且插入删除困难.因此,折半查找方法适用于不经常变动而查找频繁的有序列表.首先,假设表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功:否则利用中间位置记录将表分成前.后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表.重复以上过程,直到找到满足条件的记录,使查找成功,或直到