Java排序算法分析与实现:快排、冒泡排序、选择排序、插入排序、归并排序(二)
一、概述:
上篇博客介绍了常见简单算法:冒泡排序、选择排序和插入排序。本文介绍高级排序算法:快速排序和归并排序。在开始介绍算法之前,首先介绍高级算法所需要的基础知识:划分、递归,并顺带介绍二分查找算法。
二、划分:
划分是快速排序的前提,即把数据分为两组,大于特定值的数据在一组,小于特定值的数据在另一组。快速排序即是由划分和递归操作来完成的。
(1)原理:
定义一个阈值,分别从最左面和最右面向中间遍历元素,左面找到一个大于阈值的数据便停止,右边找到一个小于阈值的数据便停止,如果此时左右两边都还没有走到中间,则交换左面大于阈值的数据和右面小于阈值的数据;重复上述过程,直到左面指针和右面指针相遇,此时左面数据均小于阈值,右面数据均大于阈值,划分结束。划分结束后,数据仍然是无序的,但更接近于有序。
(2)例子:
待划分数据:7, 6, 9, 8, 5,1,假设阈值为5
第一轮:左指针指向7,右指针指向1,左指针向后移,右指针向左移,发现左面第一个大于5的元素7,右面第一个小于5的元素1,交换7和1的位置,结果:1,6,9,8,5,7;
第二轮:从6开始找大于5的数字,找到6,右边从5起找小于5的数字,找到1,但此时由于6在1的右面,,即右指针<左指针,左右指针交叉,此时划分结束。原数列被划分为两部分,左侧子数列只有一个元素,即为1,其为小于阈值的子数列;右侧子数列包括5个元素,均为大于阈值5的元素。
(3)代码实现:
package com.test.insertsort; /**
* 划分、递归、快排
* @author bjh
*
*/
public class QuickSort { /**待排序、划分数组*/
private int[] array;
/**数组长度*/
private int length; public QuickSort(int[] array){
this.array = array;
this.length = array.length;
} /**
* 打印元素
*/
public void printArray(){
for(int i=0; i<length; i++){
System.out.print(array[i]+" ");
}
System.out.println();
} /**
* 划分
* @return 划分的分界点
*/
public int partition(int left, int right, int pivot){
//左指针的起点,left-1是由于在后面的循环中,每循环一次左指针都要右移,
//这样可以确保左指针从左边第一个元素开始,不然是从第二个开始
int leftpoint = left-1;
//右指针的起点,right+1是由于后面的循环中,每循环一次右指针都要左移,
//这样可以确保右指针从最右边开始,不然是从倒数第二个开始
int rightpoint = right+1;
while(true){
//找到左边大于pivot的数据,或者走到了最右边仍然没有找到比pivot大的数据
while(leftpoint<right && array[++leftpoint]<pivot);
//找到右边小于pivot的数据,或者走到了最左边仍然没有找到比pivot小的数据
while(rightpoint>left && array[--rightpoint]>pivot);
//左指针和右指针重叠或相交
if(leftpoint >= rightpoint){
break;
}else{
//交换左边大的和右边小的数据
swap(leftpoint,rightpoint);
}
}
//返回分界点,即右边子数组中最左边的点
return leftpoint;
} /**
* 交换数据
*/
public void swap(int leftpoint,int rightpoint){
int temp = array[leftpoint];
array[leftpoint] = array[rightpoint];
array[rightpoint] = temp;
} public static void main(String args[]){
int[] array = {99,78,26,17,82,36,9,81,22,100,30,20,17,85};
QuickSort qs = new QuickSort(array);
System.out.println("划分前的数据为:");
qs.printArray();
int bound = qs.partition(0, array.length-1, 50);
System.out.println("划分后的数据为:");
qs.printArray();
System.out.println("划分的分界点为:" + array[bound] + ",分界点的坐标为:" + bound);
} }
运行结果为:
持续更新中。。。。
Java排序算法分析与实现:快排、冒泡排序、选择排序、插入排序、归并排序(二)的更多相关文章
- 过三关 Java冒泡排序选择排序插入排序小练习
材料:猴子排序,按照身高来从小到大来排序. 第一关: 老猴子带领小猴子队伍按大小逐一比较,交换,开始高矮排列队伍.(冒泡排序) 第二关: 太慢了,给第一关增加难度,进行选择排序 第三关: 最后,尝试选 ...
- 归并排序 & 计数排序 & 基数排序 & 冒泡排序 & 选择排序 ----> 内部排序性能比较
2.3 归并排序 接口定义: int merge(void* data, int esize, int lpos, int dpos, int rpos, int (*compare)(const v ...
- 算法 排序lowB三人组 冒泡排序 选择排序 插入排序
参考博客:基于python的七种经典排序算法 [经典排序算法][集锦] 经典排序算法及python实现 首先明确,算法的实质 是 列表排序.具体就是操作的列表,将无序列表变成有序列表! 一 ...
- 学习C#之旅 冒泡排序,选择排序,插入排序,希尔排序[资料收集]
关于冒泡排序,选择排序,插入排序,希尔排序[资料收集] 以下资料来源与网络 冒泡排序:从后到前(或者从前到后)相邻的两个两两进行比较,不满足要求就位置进行交换,一轮下来选择出一个最小(或最大)的放到 ...
- C# 插入排序 冒泡排序 选择排序 高速排序 堆排序 归并排序 基数排序 希尔排序
C# 插入排序 冒泡排序 选择排序 高速排序 堆排序 归并排序 基数排序 希尔排序 以下列出了数据结构与算法的八种基本排序:插入排序 冒泡排序 选择排序 高速排序 堆排序 归并排序 基数排序 希尔排序 ...
- python算法(一)基本知识&冒泡排序&选择排序&插入排序
本节内容: 算法基本知识 冒泡排序 选择排序 插入排序 1. 算法基本知识 1.1 什么是算法? 算法(algorithm):就是定义良好的计算过程,他取一个或一组的值为输入,并产生出一个或一组值作为 ...
- C语言实现 冒泡排序 选择排序 希尔排序
// 冒泡排序 // 选择排序 // 希尔排序 // 快速排序 // 递归排序 // 堆排序 #define _CRT_SECURE_NO_WARNINGS #include <stdio.h& ...
- 数据结构和算法(Java版)快速学习(交换、选择、插入排序)
基本排序算法:交换.选择.插入排序 常用的交换排序又称之为:冒泡排序 一般河水中的冒泡,水底刚冒出来的时候是比较小的,随着慢慢向水面浮起会逐渐增大,冒泡排序由此物理规律得来. 冒泡算法的运作规律如下: ...
- C语言实现单向链表及其各种排序(含快排,选择,插入,冒泡)
#include<stdio.h> #include<malloc.h> #define LEN sizeof(struct Student) struct Student / ...
- HDOJ(HDU) 1862 EXCEL排序(类对象的快排)
Problem Description Excel可以对一组纪录按任意指定列排序.现请你编写程序实现类似功能. Input 测试输入包含若干测试用例.每个测试用例的第1行包含两个整数 N (<= ...
随机推荐
- C# new关键字和对象类型转换(双括号、is操作符、as操作符)
一.new关键字 CLR要求所有的对象都通过new来创建,代码如下: Object obj=new Object(); 以下是new操作符做的事情 1.计算类型及其所有基类型(一直到System.Ob ...
- Python中range()和len()
- 保存html上传文件过程中遇到的字节流和字符流问题总结
java字节流和字符流的区别以及相同 1. 字节流文件本身进行操作,字符流是通过缓存进行操作, 1.1 使用字节流不执行关闭操作 File f =new File("d:/test/test ...
- JDK动态代理[4]----ProxyGenerator生成代理类的字节码文件解析
通过前面几篇的分析,我们知道代理类是通过Proxy类的ProxyClassFactory工厂生成的,这个工厂类会去调用ProxyGenerator类的generateProxyClass()方法来生成 ...
- js获取样式、currentStyle和getComputedStyle的兼容写法
currentStyle获取计算后的样式,也叫当前样式.最终样式.优点:可以获取元素的最终样式,包括浏览器的默认值,而不像style只能获取行间样式,所以更常用到.注意:不能获取复合样式如backgr ...
- Git详解之六:Git工具
Git 工具 现在,你已经学习了管理或者维护 Git 仓库,实现代码控制所需的大多数日常命令和工作流程.你已经完成了跟踪和提交文件的基本任务,并且发挥了暂存区和轻量级的特性分支及合并的威力.(伯乐在线 ...
- c# 去除字符串中重复字符
String.Join 和 Distinct 方法 https://www.cnblogs.com/louby/p/6224960.html 1.在写程序中经常操作字符串,需要去重,以前我的用方式利用 ...
- Fiddler工具的界面说明
1.Fiddler界面说明 2.session的模块说明 包含部分如下: 注:标蓝色区域的内容为平时较常用的部分 3.session不同图标和不同颜色的含义 默认颜色的含义如下: 部分图标的含义如下: ...
- numpy库常用基本操作
NumPy数组的维数称为秩(rank),一维数组的秩为1,二维数组的秩为2,以此类推.在NumPy中,每一个线性的数组称为是一个轴(axes),秩其实是描述轴的数量.比如说,二维数组相当于是一个一维数 ...
- JS 对象API之判断父对象是否在子对象的原型链上
语法:父对象.prototype.isPrototypeOf(子对象) 代码栗子: function Student(){ this.name = "小马扎"; ; } var s ...