3.分治法02分治思想与实例
2018-01-04 19:27
169 查看
前言;上篇博文主要讲解了递归以及递归的一些常见算法,分治与递归在实际应用中通常结合使用。
分治的基本思想:将一个规模是n的问题分解为k个规模较小的问题,这些子问题相互独立且与原问题相同,递归的解决这些子问题,然后将各个子问题的解合并到原问题的解。
实例1---二分搜索技术
问题描述:二分搜索算法是运用分治思想的典型列子,问题是给定n个排好序的元素,在这n个元素中找出特定元素x,如果我们采用最容易想到的顺序搜索方法,则需要时间复杂度是0(n),但是题目有个排好序的这个条件,二分搜索就是充分利用这个排好条件实现的,最坏情况下需要0(logn)时间完成!
算法思想:将n个元素分成个数大致相同的两半(个数为奇数去中间的即可,个数是偶数的取n/2或者n/2+1都行),取a[n/2]与x比较 ,如果x=a[n/2]则输出; 如果X大于a[n/2]则数组a的右部分查找即可;如果x小于a[n/2] ,只要在数组a的做部分查找即可。
算法实现:
public class Test {
public static void main(String[] args) {
int[] a = {2, 5, 8, 12, 42, 56, 89, 102, 156 };
int b = serarch(a, 102, 9);
System.out.println(b);
}
public static int serarch(int[] a, int x, int n) {
int left = 0;
int right = n - 1;
while (left <= right) //跳出循环的条件是左边数大于右边的
{
int middle = (left + right) / 2;
if (x == a[middle])return middle;//中间的数恰好等于要找到的数
if (x > a[middle])left = middle + 1;//中间的数比要找到数小,到右边查找
else right = middle - 1;//中间的数比要找的数大,到左边查找
}
return -1;
}
}
实例2---快速排序
快速排序可以是说是排序算法中效率较高的一种排序算法,网上关于快速排序的讲解也是很多,本人先就自己的理解写一下对快速排序的理解
首先快速排序的思想是:
分解:对于给定的数组,找一个基准元素(这个基准元素可以是数组中任意一个元素,这也是快速排序的特点,能够快速定位一个指定的元素),然后这个数组依此基准元素分解成大小两部分,比如基准元素左边都是小于基准的元素,基准元素右边都是大于基准元素的,
递归:对这两部分元素采用分解中的方法分别分解
合并:把上面分解好的和即可
实例:对以下数组进行快速排序
首先:找一个基准元素(一般找第一个就可以了)10 ,把这个基准元素取出来,此时基准位为空
其次:定义两个变量i j。让一个从0位置开始 另一个从最后一个元素开始
然后:变量i通知变量j从右向左找一个比基准元素小的元素,直到找到小于基准元素的,本例中找到的7
接着:变量把找到的元素给变量i所指的基准空位
然后:变量j要求变量i从左向右找个比基准元素10大的元素给表变量j空的位置 本例中i找的是12
接着:变量i出现空位,要求变量j找个比10小的元素9放到i的空位置
然后:变量j要求变量i从左向右找个比基准元素10大的元素给表变量j空的位置 本例中i找的是15
接着:变量i出现空位,要求变量j找个比10小的元
a5b9
素放到i的空位置,发现从右到左没有比10小的元素,然后i与j相遇,这时候相遇的位置用之前的基准元素10填充最终第一趟排序结果就好了
第一躺将元素划分为两部分,小于与大于两部分,然后使用递归分别对左右两部分进行排序
算法实现:
实例3---合并排序
变量i
变量j
79
1015201211
分治的基本思想:将一个规模是n的问题分解为k个规模较小的问题,这些子问题相互独立且与原问题相同,递归的解决这些子问题,然后将各个子问题的解合并到原问题的解。
实例1---二分搜索技术
问题描述:二分搜索算法是运用分治思想的典型列子,问题是给定n个排好序的元素,在这n个元素中找出特定元素x,如果我们采用最容易想到的顺序搜索方法,则需要时间复杂度是0(n),但是题目有个排好序的这个条件,二分搜索就是充分利用这个排好条件实现的,最坏情况下需要0(logn)时间完成!
算法思想:将n个元素分成个数大致相同的两半(个数为奇数去中间的即可,个数是偶数的取n/2或者n/2+1都行),取a[n/2]与x比较 ,如果x=a[n/2]则输出; 如果X大于a[n/2]则数组a的右部分查找即可;如果x小于a[n/2] ,只要在数组a的做部分查找即可。
算法实现:
public class Test {
public static void main(String[] args) {
int[] a = {2, 5, 8, 12, 42, 56, 89, 102, 156 };
int b = serarch(a, 102, 9);
System.out.println(b);
}
public static int serarch(int[] a, int x, int n) {
int left = 0;
int right = n - 1;
while (left <= right) //跳出循环的条件是左边数大于右边的
{
int middle = (left + right) / 2;
if (x == a[middle])return middle;//中间的数恰好等于要找到的数
if (x > a[middle])left = middle + 1;//中间的数比要找到数小,到右边查找
else right = middle - 1;//中间的数比要找的数大,到左边查找
}
return -1;
}
}
实例2---快速排序
快速排序可以是说是排序算法中效率较高的一种排序算法,网上关于快速排序的讲解也是很多,本人先就自己的理解写一下对快速排序的理解
首先快速排序的思想是:
分解:对于给定的数组,找一个基准元素(这个基准元素可以是数组中任意一个元素,这也是快速排序的特点,能够快速定位一个指定的元素),然后这个数组依此基准元素分解成大小两部分,比如基准元素左边都是小于基准的元素,基准元素右边都是大于基准元素的,
递归:对这两部分元素采用分解中的方法分别分解
合并:把上面分解好的和即可
实例:对以下数组进行快速排序
10 | 12 | 15 | 10 | 9 | 20 | 7 | 11 |
12 | 15 | 10 | 9 | 20 | 7 | 11 |
变量i | 变量j | ||||||
12 | 15 | 10 | 9 | 20 | 7 | 11 |
变量i | 变量j | ||||||
12 | 15 | 10 | 9 | 20 | 7 | 11 |
变量i | 变量j | ||||||
7 | 12 | 15 | 10 | 9 | 20 | 11 |
变量i | 变量j | ||||||
7 | 15 | 10 | 9 | 20 | 12 | 11 |
变量i | 变量J | ||||||
7 | 9 | 15 | 10 | 20 | 12 | 11 |
变量i | 变量j | ||||||
7 | 9 | 10 | 15 | 20 | 12 | 11 |
a5b9
素放到i的空位置,发现从右到左没有比10小的元素,然后i与j相遇,这时候相遇的位置用之前的基准元素10填充最终第一趟排序结果就好了
变量i j | |||||||
7 | 9 | 10 | 10 | 15 | 20 | 12 | 11 |
算法实现:
实例3---合并排序
变量i
变量j
79
1015201211
相关文章推荐
- 高速排序(递归与分治的思想)
- 很久之前关于分治思想的一个简单程序
- 以下哪种排序算法用到了分治思想
- 递归和分治思想1 - 数据结构和算法31
- (分治思想)(归并排序)C - Ultra-QuickSort(7.2.2)
- 学习笔记之递归和分治思想
- [珠玑之椟]二分思想与分治法、排序思想
- 分治思想 - 二分搜索技术 - MATLAB代码 list是数据集合,x是要查找的数据。
- [珠玑之椟]二分思想与分治法、排序思想
- 2.2 分治法的基本思想
- 编程思想┊从实例谈面向对象编程(OOP)、工厂模式和重构
- 算法洗脑系列(8篇)——第五篇 分治思想
- SeleniumWebdriver测试环境配置及第一个脚本实例_02
- 编程思想:从实例谈面向对象编程(OOP)、工厂模式和重构
- A^B mod C的分治思想
- Java编程思想(02)——重构让代码更简洁(二)
- 最大子数组问题--分治法的思想
- OGG学习笔记02-单向复制配置实例
- C语言的递归思想实例分析
- Java的8大排序的基本思想及实例解读