二分折半排序

板子:

插入后,每次与中间值相比较,再与左半部分中间值比较,再与右半部份中间值比较,直到找到它自己的位置,

待排序数据:2,1,6,7,4 数据部分:原文https://www.jianshu.com/p/93926f680184

取第一个元素作为有序表,剩余的元素作为无序表

   其中有序表:2;无序表:1,6,7,4

第一次比较,从无序表中取出第一个数 1,与中间值2比较,1<2,1插到2的前面,得到

   有序表:1,2;无序表:6,7,4

第二次比较,从无序表中取出第一个数 6,与中间值1比较,6>1,要放在1的后面,再与后半区(有序表:2)的中间值2比较,6>2,6插入到2的后面,得到

   有序表:1,2,6;无序表:7,4

第三次比较,从无序表中取出第一个数 7,与中间值2比较,7>2,7放在2后面,再与后半区(有序表:6)的中间值6比较,7>6,7放在6后面,得到

   有序表:1,2,6,7;无序表:4

第四次比较,从无序表中取出第一个数 4,与中间值2比较,4>2,4放在2后面,再与后半区(有序表:6,7)的中间值6比较,4<6,4放在6前面,最终得到:

   1,2,4,6,7

数组版本;

 1 #include<iostream>
 2 #include<vector>
 3 #include<algorithm>
 4 using namespace std;
 5
 6 #include <stdio.h>
 7 #include <stdlib.h>
 8
 9 void BinInsertSort(int A[], int n)
10 {
11     int i, j, low, mid, high, temp;
12     for(i = 1; i <= n-1; i++)
13     {
14         temp = A[i];                    // 辅助变量temp用来保存待排序的元素
15         low = 0;
16         high = i-1;                     // 有序区间为[0,i-1]
17         while(low <= high)              // 在有序区间内采用折半查找,找到插入位置
18         {
19             mid = (low + high)/2;
20             if(A[mid] > temp)
21                 high = mid - 1;
22             else
23                 low = mid + 1;
24         }
25         for(j = i-1; j >= high+1; j--)  // 移动元素,腾出空间
26             A[j+1] = A[j];
27         A[high+1] = temp;               // 将待排序的元素插入
28     }
29 }
30
31 int main()
32 {
33     int n;
34     while(cin>>n){
35         int nums[10010];
36         for(int i =0;i<n;++i){
37             cin>>nums[i];
38         }
39         BinInsertSort(nums,n);
40         for(int i =0;i<n;++i){
41             cout<<nums[i]<<" ";
42         }
43     }
44     return 0;
45 }

vector版本;

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
void BinInsertSort(vector<int>& nums, int n)
{
    vector<int> v;
    for(int i=nums.size()-1;i>=0; i--)//for(int i=0; i<num.size()-1; i++)
    {
        int l=0,r=v.size();
        while(l<r)
        {
            int mid=(l+r)/2;
            if(nums[i]>v[mid]) l=mid+1;
            else r=mid;
        }
        v.insert(v.begin()+r,nums[i]);
    }
    for(vector<int> ::iterator it=v.begin();it!=v.end();it++)
     cout<<*it<<" ";
}

int main()
{
    int n;
    while(cin>>n){
        vector<int > nums(n);
        for(int i =0;i<n;++i){
            cin>>nums[i];
        }
        BinInsertSort(nums,n);
    }
    return 0;}

原文地址:https://www.cnblogs.com/sweetlittlebaby/p/12693153.html

时间: 2024-08-30 16:47:56

二分折半排序的相关文章

Java 实现二分(折半)插入排序

设有一个序列a[0],a[1]...a[n];其中a[i-1]前是已经有序的,当插入时a[i]时,利用二分法搜索a[i]插入的位置 效率:O(N^2),对于初始基本有序的序列,效率上不如直接插入排序:对于随机无序的序列,效率比直接插入排序要高 /* * 二分(折半)插入排序 * 设有一个序列a[0],a[1]...a[n];其中a[i-1]前是已经有序的,当插入时a[i]时,利用二分法搜索a[i]插入的位置 */ public class BinaryInsertSort { public st

Codeforces Round #417 (Div. 2) C. Sagheer and Nubian Market 二分答案 +排序

Codeforces Round #417 (Div. 2) C. Sagheer and Nubian Market 二分答案 +排序 题意 有 a[ i ] 个数 要求选最多的数 使其和不超过 S ,且在此情况下,和最小选最多数情况下 和最小 且 每个数有加成 如果选了 k个数 那么加成后 就是 a[ i ] + k*i ; 题解 二分mid 表示选了个数 加成一下,将加成以后结果排序一下 , 若前 mid数 和大于 s 则此方案不可行 PS 要用 long long ..... 还有 co

折半排序 (稳定的排序)

$arr=array('','7','9','11','2','5','13','10','14','12');    $n=count($arr);     for($i=2;$i<$n;$i++)     {           $low=1;$high=$i-1;           $arr[0]=$arr[$i];           while($low<=$high)           {               $m=intval(($low+$high)/2);    

java实现折半排序算法

折半插入排序法,又称二分插入排序法,是直接插入排序法的改良版,也需要执行i-1趟插入,不同之处在于,第i趟插入,先找出第i+1个元素应该插入的的位置,假定前i个数据是已经处于有序状态. 折半插入排序(binary insertion sort)是对插入排序算法的一种改进,由于排序算法过程中,就是不断的依次将元素插入前面已排好序的序列中.由于前半部分为已排好序的数列,这样我们不用按顺序依次寻找插入点,可以采用折半查找的方法来加快寻找插入点的速度.来自codego.net源码参考

POJ - 2785 - 4 Values whose Sum is 0 - 二分折半查找

2017-08-01 21:29:14 writer:pprp 参考:http://blog.csdn.net/piaocoder/article/details/45584763 算法分析:直接暴力复杂度过高,所以要用二分的方法,分成两半复杂度就会大大降低: 题目意思:给定4个n(1<=n<=4000)元素的集合 A.B.C.D ,从4个集合中分别选取一个元素a, b,c,d.求满足 a+b+c+d=0的个数 代码如下: //首先将前两列任意两项相加得到数组x,再将后两列任意两项相加取反得到

CF #CROC 2016 - Elimination Round D. Robot Rapping Results Report 二分+拓扑排序

题目链接:http://codeforces.com/contest/655/problem/D 大意是给若干对偏序,问最少需要前多少对关系,可以确定所有的大小关系. 解法是二分答案,利用拓扑排序看是否所有关系被唯一确定.即任意一次只能有1个元素入度为0入队. 1 #include <iostream> 2 #include <vector> 3 #include <algorithm> 4 #include <string> 5 #include <

二分查找排序

static final int N=15; static void quickSort(int[] arr,int left,int right) //快速排序算法 { int f,t; int rtemp,ltemp; ltemp=left; rtemp=right; f=arr[(left+right)/2]; //确定分界值 while(ltemp<rtemp){ while(arr[ltemp]<f) ++ltemp; while(arr[rtemp]>f) --rtemp;

POJ - 3977 Subset(二分+折半枚举)

题意:有一个N(N <= 35)个数的集合,每个数的绝对值小于等于1015,找一个非空子集,使该子集中所有元素的和的绝对值最小,若有多个,则输出个数最小的那个. 分析: 1.将集合中的元素分成两半,分别二进制枚举子集并记录子集所对应的和以及元素个数. 2.枚举其中一半,二分查找另一半,不断取最小值. #pragma comment(linker, "/STACK:102400000, 102400000") #include<cstdio> #include<c

51nod 1001 数组中和等于K的数对【二分查找/排序】

1001 数组中和等于K的数对 基准时间限制:1 秒 空间限制:131072 KB 分值: 5 难度:1级算法题  收藏  关注 给出一个整数K和一个无序数组A,A的元素为N个互不相同的整数,找出数组A中所有和等于K的数对.例如K = 8,数组A:{-1,6,5,3,4,2,9,0,8},所有和等于8的数对包括(-1,9),(0,8),(2,6),(3,5). Input 第1行:用空格隔开的2个数,K N,N为A数组的长度.(2 <= N <= 50000,-10^9 <= K <