CompareTo 基于的排序算法(高级排序)

这个是今天学习MapReduce时发现的,自定义类后实现了WritableComparable<>接口后实现了接口中的compareTo方法,返回>1或者<1则会自动进行排序的方法。

然后特别好奇,查了查,学习下做一个总结。

首先说明 实现CompareTo方法的是使用了Collections.sort()和Arrays.sort()底层得算法,是timsort算法,插入排序和归并排序的高级合并 .

详情:https://blog.csdn.net/yangzhongblog/article/details/8184707

而这2个方法在底层实现时,使用到了object1.compareTo(object2)这种方法进行判断谁大谁小,从而调整数组,最终给你返回有序的集合,两个方法的排序算法实现有归并排序和快速排序。

详细将一下:归并排序是属于递归中的一种,而快速排序是是属于高级排序的,与其同时的 还有希尔排序,划分,基数排序。但最常用的还是快速排序。这里详解一下技术排序,归并排序我则在记录递归是将其一并总结。所以我来详解一下这个高级排序

高级排序

希尔排序:

    首次介绍下,希尔排序是基于插入排序的。插入排序利用临时变量比较和存储数据,交换位置来排序,所以虽然不是每个数据项都移动,但是数据项平均移动了n/2个位置,一共是n的平方/2次复制,插入排序的执行效率是O(N的平方).插入排序复制的次数太多,即数据项之间交换数据次数较多。希尔则避免了这个点。

n-增量排序:通过加大插入排序中的元素之间的间隔。n:是指元素之间的间隔几个元素

我们来看一下主要的 4- 增量排序的放的排序过程。所有元素在离它最终的有序序列中的位置相差不到两个单元,做到了数据的基本有序,希尔则是做到了数据的基本有序,通过创建这种交错的内部有序的数据项集合,把完成排序所需的工作降调到最小

那么我们来研究一下这个间隔,这个间隔到底是使用多少为合适,可以将希尔的作用发挥到及至。以及间隔的选用。

间隔是通过数组得到大小进行变化的。比如1000个数据,间隔则为364-->121-->40-->13-->4-->1 这个间隔序列是通过递归计算出来的

谈希尔适合的排序环境:

这里是我的个人见解,如有更好的见解,欢迎一起讨论!!!

希尔排序适合中量数据的基本有序排序,少量数据使用插入排序进行更为稳定。

走开走开~~代码来了

package AdvancedRanking.ShellSort;

public class ArraySh {

    //数组
private long[] theArray; //数组长度
private int nElems; public ArraySh(int max) {
theArray = new long[max];
nElems = 0;
} public void insert(long value) {
theArray[nElems] = value;
nElems++;
} public void display() {
System.out.print("A=");
for (int j = 0; j < nElems; j++) {
System.out.print(theArray[j] + " ");
}
System.out.println("");
} public void shellSort() {
int inner, outer;
long temp; //初始时元素之间的间隔
int h = 1;
while (h <= nElems / 3) {
h = h * 3 + 1;
} while (h > 0) {
for (outer = h; outer < nElems; outer++) {
temp = theArray[outer];
inner = outer;
while (inner > h - 1 && theArray[inner - h] >= temp) {
theArray[inner] = theArray[inner - h];
System.out.println(theArray[inner]);
inner -= h;
}
theArray[inner] = temp;
}
//结束时元素之间的间隔
h = (h - 1) / 3;
}
} public static void main(String[] args) {
int maxSize = 10;
ArraySh arr = new ArraySh(maxSize); for (int j = 0; j < maxSize; j++) {
long n = (int) (Math.random() * 99);
arr.insert(n);
}
arr.display();
arr.shellSort();
arr.display();
}
}

二.划分

package AdvancedRanking.PartitionSort;

public class ArrayPar {

    private long[] theArray;
private int nElems; public ArrayPar(int max) {
theArray = new long[max];
nElems = 0;
} public void insert(long value) {
theArray[nElems] = value;
nElems++;
} public int size() {
return nElems;
} public void display() {
System.out.print("A=");
for (int j = 0; j < nElems; j++) {
System.out.print(theArray[j] + " ");
}
System.out.println("");
} public int partitionIt(int left, int right, long pivot) {
int leftPtr = left - 1;
int rightPtr = right + 1;
while (true) {
//最大得
while (leftPtr < right && theArray[++leftPtr] > pivot) ;
//最小的
while (rightPtr > left && theArray[--rightPtr] > pivot) ; if (leftPtr > rightPtr) {
break;
} else {
swap(leftPtr, rightPtr);
}
}
return leftPtr;
} public void swap(int dex1, int dex2) {
long temp;
temp = theArray[dex1];
theArray[dex1] = theArray[dex2];
theArray[dex2] = temp;
} public static void main(String[] args) {
int maxSize = 10;
ArrayPar arr = new ArrayPar(maxSize);
for (int j = 0; j < maxSize; j++) {
long n = (int) (Math.random() * 199);
arr.insert(n);
}
arr.display();
long piovt = 99;
System.out.print("Piovt is " + piovt);
int size = arr.size(); int partDex = arr.partitionIt(0, size - 1, piovt);
System.out.println(", Partition is at index " + partDex);
arr.display();
}
}

划分算法是由两个指针开始工作的,两个指针分别指向数据的两头leftPtr初始化是在第一个数据项的左边的一位,rightPtr是在最后一个数据项的右边一位。他们分别要-1  +1

  //找小于于piovt
while (leftPtr < right && theArray[++leftPtr] > pivot) ;
   //找小于pivot
while (rightPtr > left && theArray[--rightPtr] > pivot) ;

划分算法运行时间为O(N),他其中的piovt枢纽,根据枢纽来移动指针和交换数据位置,虽然交换次数少,但是比较次数多。100个数大约交换25次,102次的比较。

快速排序:

CompareTo 基于的排序算法的更多相关文章

  1. Arrays.Sort()中的那些排序算法

    本文基于JDK 1.8.0_211撰写,基于java.util.Arrays.sort()方法浅谈目前Java所用到的排序算法,仅个人见解和笔记,若有问题欢迎指证,着重介绍其中的TimSort排序,其 ...

  2. 常见排序算法基于JS的实现

    一:冒泡排序 1. 原理 a. 从头开始比较相邻的两个待排序元素,如果前面元素大于后面元素,就将二个元素位置互换 b. 这样对序列的第0个元素到n-1个元素进行一次遍历后,最大的一个元素就“沉”到序列 ...

  3. 第32讲:List的基本操作实战与基于模式匹配的List排序算法实现

    今天来学习一下list的基本操作及基于模式匹配的排序操作 让我们从代码出发 val bigData = List("hadoop","spark") val d ...

  4. 排序算法总结(基于Java实现)

    前言 下面会讲到一些简单的排序算法(均基于java实现),并给出实现和效率分析. 使用的基类如下: 注意:抽象函数应为public的,我就不改代码了 public abstract class Sor ...

  5. 转载~基于比较的排序算法的最优下界为什么是O(nlogn)

    基于比较的排序算法的最优下界为什么是O(nlogn) 发表于2013/12/21 16:15:50  1024人阅读 分类: Algorithm 1.决策二叉树 回答这个问题之前我们先来玩一个猜数字的 ...

  6. 基于python的七种经典排序算法

    参考书目:<大话数据结构> 一.排序的基本概念和分类 所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作.排序算法,就是如何使得记录按照要求排列的方法. ...

  7. 八大排序算法---基于python

    本文节选自:http://python.jobbole.com/82270/ 本文用Python实现了插入排序.希尔排序.冒泡排序.快速排序.直接选择排序.堆排序.归并排序.基数排序. 1.插入排序 ...

  8. 温习排序算法(基于C指针)

    以前学过的数据结构课,貌似已经忘得一干二净了,偶然又翻起,书中最后一章详细介绍了7种排序算法,现在对其中4种做个总结.(为啥只总结4种,当然是因为偷懒,只想总结简单又常用的!) 先贴一张排序分类图: ...

  9. 基于python的七种经典排序算法(转)

    一.排序的基本概念和分类 所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作.排序算法,就是如何使得记录按照要求排列的方法. 排序的稳定性:经过某种排序后,如果两个 ...

随机推荐

  1. 深入理解char * ,char ** ,char a[ ] ,char *a[]

    1.数组的本质 数组是多个元素的集合,在内存中分布在地址相连的单元中,所以可以通过其下标访问不同单元的元素. 2.指针 指针也是一种变量,只不过它的内存单元中保存的是一个标识其他位置的地址.由于地址也 ...

  2. 【MySQL】【一】shell

    进入MySQL:mysql -u root -p 查看当前数据库下所有库:mysql> show databases; 切换到某库:mysql> use sys; 查看sys库下所有表:m ...

  3. Pandas 基础(3) - 生成 Dataframe 的几种方式

    这一节想总结一下 生成 Dataframe 的几种方式: CSV Excel python dictionary List of tuples List of dictionary 下面分别一一介绍具 ...

  4. sticky-footer的三种解决方案

    在网页设计中,Sticky footers设计是最古老和最常见的效果之一,大多数人都曾经经历过.它可以概括如下:如果页面内容不够长的时候,页脚块粘贴在视窗底部:如果内容足够长时,页脚块会被内容向下推送 ...

  5. 七牛云存储上传自有证书开启https访问

    虽然七牛云存储也提供免费SSL证书申请,但我就喜欢用其他平台申请的,于是在腾讯云申请了免费SSL证书,正准备在七牛上传,弹出的界面却让我傻了眼,如下图所示: 腾讯免费SSL证书提供了不同服务器环境的版 ...

  6. red hat7 系统可以ping通ip地址但是不能ping通域名

    在red hat7中ifconfig后出现这样的情况,ens33是物理网卡,与eth0一样只是不同的名字.但是只能ping通ip地址不能ping通域名. 解决方法: 在文件 /etc/resolv.c ...

  7. Java之——利用Comparator接口对多个排序条件进行处理

    转载自:http://blog.csdn.net/l1028386804/article/details/56513205 膜拜大神··· 一.需求 假设现在有个如此的需求:需要对一个这样的雇员列表进 ...

  8. include

    1. 自己写的文件都用:include "....." 2. 如果A类include了B,那么在主函数中,只用include A类,就可以使用B类了,但是此时不能再include ...

  9. nRF52832定时器

    1概述 定时器能够被配置为两种模式:定时模式和计数模式,nrf52832有五个定时器,timer0--timer4 . 2常用得函数 函数功能:初始化定时器 ret_code_t nrf_drv_ti ...

  10. Windows上结合使用Flume和Kafka

    Win7+Flume1.8.0 + Kafka1.0.0 1.目标 ①使用Flume作为Kafka的Producer: ②使用Kafka作为Flume的Sink: 其实以上两点是同一个事情在Flume ...