二分查找、快速排序、归并排序(分而治之)

2023-11-08 20:38

本文主要是介绍二分查找、快速排序、归并排序(分而治之),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

顺序查找

  1.   如果线性表为无序表,即表中元素的排列是无序的,则不管线性表采用顺序存储还是链式存储,都必须使用顺序查找。
  2.   如果线性表有序,但采用链式存储结构,则也必须使用顺序查找。

二分查找

       必须遵循两个条件:数组有序、符合左闭右开原则(是一种区间无重复的思想)

      二分查找思想图:

 

 /****  二分查找*  binary search ,this  is  must be  order  array* @param array  源数组* @param fromIndex  开始索引* @param toIndex  结束索引* @param key  值* @return*/public static int binarySearch(int[] array, int fromIndex, int toIndex, int key) {int low = fromIndex;/**左开右闭原则,保持连续空间**/int high = toIndex - 1;while (low <= high) {/**查找中间的数**/int midIndex = (low + high) >> 1;int midValue = array[midIndex];/**如果大于中间数,左边查找**/if (key > midValue) {low = midIndex + 1;/**如果小于中间数,右边查找**/} else if (key < midValue) {high = midIndex - 1;} else {return midIndex;}}/**low+1表示找不到时停在了第low+1个元素的位置**/return -(low + 1);}

快速排序  

       快速排序(Quicksort)是对冒泡排序的一种改进。 [1] 

        快速排序由C. A. R. Hoare在1960年提出。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列

     应用场景

          数据量大并且是线性结构。

     缺点

  1.  有大量重复数据的时候,性能不好
  2.  单向链式结构处理性能不好(链式不建议不使用)

思想图:

    

 

 /*** 二叉树快速排序* quick sort ,this is  out of order*  其实就是中序的排法** @param array* @param begin 开始* @param end   结束*/public static void quickSortArray(int[] array, int begin, int end) {if (end - begin <= 0) return;int x = array[begin];int low = begin;int high = end;/**由于会从两头取数据,设置一个方向的标识位**/boolean direction = true;L:/**标签,跳出这个循环的位**/while (low < high) {/**从左往右找**/if (direction) {for (int i = high; i > low; i--) {if (array[i] <= x) {array[low++] = array[i];high = i;direction = !direction;continue L;}}/**上面条件不成立,说明指针重合了**/high = low;} else {for (int i = low; i < high; i++) {if (array[i] >= x) {array[high--] = array[i];low = i;direction = !direction;continue L;}}/**上面条件不成立,说明指针重合了**/low = high;}}/**把最后找到的值 放入中间位置开始完成左右两边的操作**/array[low] = x;quickSortArray(array, begin, low - 1);quickSortArray(array, low + 1, end);}

归并排序

        归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。归并排序是一种稳定的排序方法。
  应用场景
      数据量大并且有很多重复数据,链式结构
  缺点
      需要空间足够大

思想图:

  

 /*** 归并排序* 后序* @param array* @param left* @param right*/public static void mergeSort(int array[], int left, int right) {if (left == right) {return;} else {int mid = (left + right) / 2;/**相当于后序排序 LRD* 最底层拆分对比*    左边到中间->中间到右边->归并* **/mergeSort(array, left, mid);mergeSort(array, mid + 1, right);merge(array, left, mid + 1, right);}}/****   array  归并* @param array* @param left* @param mid* @param right*/public static void merge(int[] array, int left, int mid, int right) {int leftSize = mid - left;int rightSize = right - mid + 1;/**拆分两个数组,填充数据,下标以index开始**/int[] leftArray = new int[leftSize];int[] rightArray = new int[rightSize];for (int i = left; i < mid; i++) {leftArray[i - left] = array[i];}for (int i = mid; i <= right; i++) {rightArray[i - mid] = array[i];}/**合并的操作**/int i = 0;int j = 0;int k = left;while (i < leftSize && j < rightSize) {if (leftArray[i] < rightArray[j]) {array[k] = leftArray[i];k++;i++;} else {array[k] = rightArray[j];k++;j++;}}/**如果左边还有剩下的,直接cpoy**/while (i < leftSize) {array[k] = leftArray[i];k++;i++;}/**如果右边还有剩下的,直接cpoy**/while (j < rightSize) {array[k] = rightArray[j];k++;j++;}}

 

这篇关于二分查找、快速排序、归并排序(分而治之)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/372365

相关文章

hdu2241(二分+合并数组)

题意:判断是否存在a+b+c = x,a,b,c分别属于集合A,B,C 如果用暴力会超时,所以这里用到了数组合并,将b,c数组合并成d,d数组存的是b,c数组元素的和,然后对d数组进行二分就可以了 代码如下(附注释): #include<iostream>#include<algorithm>#include<cstring>#include<stack>#include<que

hdu2289(简单二分)

虽说是简单二分,但是我还是wa死了  题意:已知圆台的体积,求高度 首先要知道圆台体积怎么求:设上下底的半径分别为r1,r2,高为h,V = PI*(r1*r1+r1*r2+r2*r2)*h/3 然后以h进行二分 代码如下: #include<iostream>#include<algorithm>#include<cstring>#include<stack>#includ

电脑桌面文件删除了怎么找回来?别急,快速恢复攻略在此

在日常使用电脑的过程中,我们经常会遇到这样的情况:一不小心,桌面上的某个重要文件被删除了。这时,大多数人可能会感到惊慌失措,不知所措。 其实,不必过于担心,因为有很多方法可以帮助我们找回被删除的桌面文件。下面,就让我们一起来了解一下这些恢复桌面文件的方法吧。 一、使用撤销操作 如果我们刚刚删除了桌面上的文件,并且还没有进行其他操作,那么可以尝试使用撤销操作来恢复文件。在键盘上同时按下“C

【数据结构】——原来排序算法搞懂这些就行,轻松拿捏

前言:快速排序的实现最重要的是找基准值,下面让我们来了解如何实现找基准值 基准值的注释:在快排的过程中,每一次我们要取一个元素作为枢纽值,以这个数字来将序列划分为两部分。 在此我们采用三数取中法,也就是取左端、中间、右端三个数,然后进行排序,将中间数作为枢纽值。 快速排序实现主框架: //快速排序 void QuickSort(int* arr, int left, int rig

usaco 1.3 Mixing Milk (结构体排序 qsort) and hdu 2020(sort)

到了这题学会了结构体排序 于是回去修改了 1.2 milking cows 的算法~ 结构体排序核心: 1.结构体定义 struct Milk{int price;int milks;}milk[5000]; 2.自定义的比较函数,若返回值为正,qsort 函数判定a>b ;为负,a<b;为0,a==b; int milkcmp(const void *va,c

hdu 1285(拓扑排序)

题意: 给各个队间的胜负关系,让排名次,名词相同按从小到大排。 解析: 拓扑排序是应用于有向无回路图(Direct Acyclic Graph,简称DAG)上的一种排序方式,对一个有向无回路图进行拓扑排序后,所有的顶点形成一个序列,对所有边(u,v),满足u 在v 的前面。该序列说明了顶点表示的事件或状态发生的整体顺序。比较经典的是在工程活动上,某些工程完成后,另一些工程才能继续,此时

poj 2976 分数规划二分贪心(部分对总体的贡献度) poj 3111

poj 2976: 题意: 在n场考试中,每场考试共有b题,答对的题目有a题。 允许去掉k场考试,求能达到的最高正确率是多少。 解析: 假设已知准确率为x,则每场考试对于准确率的贡献值为: a - b * x,将贡献值大的排序排在前面舍弃掉后k个。 然后二分x就行了。 代码: #include <iostream>#include <cstdio>#incl

poj 3104 二分答案

题意: n件湿度为num的衣服,每秒钟自己可以蒸发掉1个湿度。 然而如果使用了暖炉,每秒可以烧掉k个湿度,但不计算蒸发了。 现在问这么多的衣服,怎么烧事件最短。 解析: 二分答案咯。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <c

poj 3258 二分最小值最大

题意: 有一些石头排成一条线,第一个和最后一个不能去掉。 其余的共可以去掉m块,要使去掉后石头间距的最小值最大。 解析: 二分石头,最小值最大。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <c

poj 2594 二分图最大独立集

题意: 求一张图的最大独立集,这题不同的地方在于,间接相邻的点也可以有一条边,所以用floyd来把间接相邻的边也连起来。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <sta