入门算法-二分查找,二分排序,插入排序,冒泡排序

1.二分查找(nlogn)

二分查找,需要将业务模拟一个有序数组。然后查找某个值在该数组中的位置。

二分查找的关键是:

1)查找的值一定在某次的范围中间。即使值是最后一个,也要按照二分法的规则去查找。

2)有左右边界的查找范围作为一个循环不变式

function bsearch(A, x) { // A 是有序升数组;x是待查值; 结果要返回x在A中的位置
   // 循环不变式
   let l = 0,r = A.length-1, guess;
   while(i <= r) {
      guess = Math.floor((l+r)/2);
      if (A[guess] === x) {
         return guess;
      } else if (A[guess] > x) {
         r = guess - 1;
      } else {
         l = guess + 1;
      }
   }
   return -1; // 没找到
}

2. 二分排序

 // 主循环执行N-1次(N代表输入的数据长度)
function insertion_sort(A) { // 对无序数组A进行排列,排列时用到插入排序
    for (let i = 1; i < A.length; i++) { // 每次循环排序前i项,第一项默认已经排序,所以从i=1开始
        bSearch(A, i, A[i]);
    }
}
function bSearch(A, i, x) {
    let l = 0, r = i -1, guess;
    while(l<=r) {
        guess = Math.floor((l+r)/2);
        if (A[guess] === x) {
            r = guess;
        } else if (A[guess] > x) {
            r = guess - 1;
        } else {
            l = guess + 1;
        }
    }
    for (let j = i; j > r; j--) {
        A[j] = A[j-1];
    }
    A[r+1] = x;
}

3. 插入排序(n^2)

子问题: 在一个有序数组中插入一个新值,即插入第一个比待插数要大的值前面。

第一反应是用js实现

function jsInsert(A, x) { // A是有序数组,x是待插入值
   const index = A.findIndex(i => i > x); // index第一个比x大的值
   const insertIndex = index > -1 ? index : A.length;
   A.splice(insertIndex, 0, x);
}

考虑实现同样的问题,使用插入排序算法(从最大值开始比较)

 function insert(A, x) {// A是有序数组,x是待插入值
    let p = A.length - 1; // p代表下一个要比较的值所在的位置, p+1留空
    while(A[p] > x) { // 如果最后一个值大于x,则将最后一个值后移,原来的位置先保持原状
       A[p+1] = A[p];
       p--; // 下一个要比较的值的位置
    }
    A[p+1] = x;
 }

插入排序:对无序数组进行排序。

分为两步: 1)默认第一个值是已排序状态。

                2)将待排的下一个值插入已经排序的位置。循环不变式。

function insert(A, i, x) {// A和i可以定位已排序的数组, i可以表示已排序数组的长度   //运行次数按照最坏的计算是1+2+3....+N = (N**2)/2 - N/2
    let p = i - 1; // p指向下一个需要比较的值,i - 1是已排序数组的最后一个值的位置
    while(p >= 0 && A[p] > x) {
        A[p+1] = A[p]
        p--;
    }
    A[p+1] = x;
 }

function insertion_sort(A) { // 对无序数组A进行排列,排列时用到插入排序
    for (let i = 1; i < A.length; i++) { // 每次循环排序前i项,第一项默认已经排序,所以从i=1开始
        insert(A, i, A[i]); // A[i]从A[1]开始,即从第二项插入第一项组成的数组开始
    }
}

4. 冒泡排序(Bubble sort)/下沉排序(Sinking sort)

复杂度和插入排序相同

每次冒泡通过遍历两两比较(交换或者不交换N-1),排出一个最大值;第二次遍历N-1的数组;.....,一共遍历N-1次。

由描述可知,分为内存循环和外层循环

function bubble_sort(A) {
    for(let i = A.length - 1; i >= 1; i--) { // 外层循环遍历N-1次
        for (let j = 0; j<i; j++) { // 内层循环遍历交换N-1次。
            if (A[j] > A[j+1]) {
                swap(A,j,j+1)
            }
        }
    }
}
function swap(A,i,j) {
    var temp;
    temp = A[i];
    A[i] = A[j];
    A[j] = temp;
}

原文地址:https://www.cnblogs.com/lyraLee/p/11530827.html

时间: 2024-10-08 09:05:48

入门算法-二分查找,二分排序,插入排序,冒泡排序的相关文章

从二分查找到折半插入排序

目录 从二分查找到折半插入排序 折半插入排序性能 Code 从二分查找到折半插入排序 回忆直接插入排序的过程,发现每趟排序中进行了两个动作: \1. 从左边的已排序序列中找寻插入位置. \2. 给插入位置腾出空间,将插入元素复制到表中的插入位置. 步骤一在直接插入排序中是一个"Linear Search"顺序查找过程,而我们知道二分查找比顺序查找更优秀. 折半插入排序性能 Space Complexity: S(n)=O(1) Time Complexity: T(n)=O(\(n^2

查找与排序05,冒泡排序

在体验了"选择排序"和"插入排序",本篇体验的是"冒泡排序",依次遍历数组中的元素,按照升序排列,如果前一个位置元素比后一个位置元素大,两者就交换位置. 自定义一个处理整型数组的类,包含添加.显示.清除及冒泡方法以及获取数组长度的属性. class MyIntArray { private int[] arr; private int upper; //最大索引 private int index; //当前索引 public MyIntArra

Java笔记(07):常见对象--StringBuffer、二分查找及排序算法

1.StringBuffer类的构造方法 1 package cn.itcast_01; 2 3 /* 4 * 线程安全(多线程讲解) 5 * 安全 -- 同步 -- 数据是安全的 6 * 不安全 -- 不同步 -- 效率高一些 7 * 安全和效率问题是永远困扰我们的问题. 8 * 安全:医院的网站,银行网站 9 * 效率:新闻网站,论坛之类的 10 * 11 * StringBuffer: 12 * 线程安全的可变字符串. 13 * 14 * StringBuffer和String的区别? 1

算法整理-二分查找和排序

1.  二分查找 (1) 有序数组查找插入位置:  主要是终止条件的判断,如果查找不到需要被范围的插入位置为begin public: int searchInsert(vector<int>& nums, int target) { int len = nums.size(); return binarySearch(nums, target, 0, len-1); } private: int binarySearch(vector<int>& nums, in

二分查找法优化插入排序

通俗的插排是对一个整型数组进行升序排序,可以看出每个元素插入到队列中经过两个步骤:先是挨个比较,找到自己所在的位置:然后把后面的数据全部移位,然后把元素插入. 要把数据插入,移位是必不可少了.那么,挨个比较倒是可以优化,因为要插入的队列已经是排序好的,我们可以使用二分法来减少比较的次数. 二分法的时间复杂度为O(log 2 n),而线性查找的复杂度为O(n). 在对50000个随机数进行测试比较中,发现加了二分查找的插排比普通的插排速度快了将近一倍!(通俗插排7888ms,优化插排4852ms)

排序算法学习之简单排序(冒泡排序,简单选择排序,直接插入排序)

一.冒泡排序 冒泡排序算是最基础的一种算法了,复杂度为O(N^2),其基本思想是:从最低端数据开始,两两相邻比较,如果反序则交换.代码如下: /*最基本的冒泡排序*/ void BubbleSort1 (int n, int *array) /*little > big*/ { int i, j; for (i=0; i<n-1; i++) { for (j=n-1; j>i; j--) { if (array[j] < array[j-1]) { int temp = array

二分查找&amp;二分答案

原创建时间:2018-02-06 16:48:20 \(O(\log_2n)\)的优秀算法 二分查找 百度百科原话 二分查找也称折半查找(Binary Search),它是一种效率较高的查找方法.但是,折半查找要求线性表必须采用顺序存储结构,而且表中元素按关键字有序排列. 二分查找的时间复杂度是\(O(log_{2}n)\) 要求 查找的序列必须采用顺序存储结构 查找的序列必须是有序排列的 思路 将需要查找的序列进行排序(一般为升序排列) 将序列中间位置记录的元素与关键字比较 如果相等,则返回查

二分查找&amp;&amp;二分中位数

普通二分查找 1 int bs(int L,int R,int x) 2 {//在l到r区间上查找x,找不到就返回-1 3 int l=L,r=R; 4 while(l<=r){ 5 int m=l+r>>1; 6 if(a[m]==x){ 7 return m; 8 } 9 else if(a[m]>x){ 10 r=m-1; 11 } 12 else{ 13 l=m+1; 14 } 15 } 16 return -1; 17 } 普通版很简单就不详细总结了 二分查找中位数 题意

算法笔记_008:选择排序和冒泡排序【蛮力法】

目录 1 问题描述 2 解决方案 2.1 选择排序原理简介 2.2 具体编码(选择排序) 2.3 冒泡排序原理简介 2.4 具体编码(冒泡排序) 1 问题描述 给定一个可排序的n元素序列(例如,数字.字符和字符串),将它们按照非降序方式重新排列. 2 解决方案 2.1 选择排序原理简介 选择排序开始的时候,我们从第一个元素开始扫描整个列表,找到它的最小元素,然后和第一个元素交换,将最小元素和第一个元素交换位置:然后,我们从第二个元素开始扫描剩下的n-1个元素,找到这n-1个元素中的最小元素,将最

算法: 二分查找 冒泡 插入 选择排序

1 二分查找:二分查找从有序列表的候选区data[0:n]开始,通过对半查找的值与候选区中间的值进行比较 方法一:利用for循环, 时间复杂度是o(n) li = [1, 3, 5, 7, 9, 11, 15, 18, 20] def linear_serach(li, value): for i in range(len(li)): if li[i] == value: return i return print(linear_serach(li,3)) 方法二: 利用二分查找, 效率高, 时