(-1)写在前面

在一次面试中被问及快速排序,回来后又看了一次以前做过的案例,说来惭愧,时至今日还需要读好长时间,才能明白自己代码的意思,主要是缺少注释和图解,深有感慨,决定好好记录一下。

之所以使用二叉树,是因为用递归实现当数据量过大时会报栈溢出的错误,我试了一下别人的电脑也是这个问题。当然使用二叉树也会报内存不足,原因是无法创建那么长的数组,堆区内存溢出。个人感觉要比递归实现好的多。

(0)算法详解

程序随机产生数据,将其放在数组里。

a.将最小索引到最大索引之间的数据看做一个整体,程序已最小索引代表的数A为准

b.调换A的位置,使得A左边是比A大的数,A右边是比A小的数,此时A的索引被称为中间索引

c.最小索引到  中间索引-1被看为左孩子 ,中间索引+1 到最大索引被看做右孩子

已此图为例,说明程序流程:

每个节点代表一个数组片段,1是根节点,代表整个数组,每个片段都要经历a、b的操作

顺序为操作1,创建2,3,操作2,创建4,5,操作4,回到2,操作5,回到2,回到1,操作3,创建6,操作6,回到3,回到1,完事。

以下面这个数组为例,说明程序流程

int[] oop = {510, 107,948, 659, 955,438, 283,822};

第一次

a 步骤  最小索引0,最大索引7  A –>510

b步骤  [822, 955, 948, 659, 510, 438, 283, 107]

c  步骤 左孩子0-3  右孩子5-7

第二次

a 步骤  最小索引0,最大索引3  A –>822

b步骤  [948, 955, 822,659]

c  步骤 左孩子0-1  右孩子没有

第三次

a 步骤  最小索引0,最大索引1  A –>948

b步骤  [955, 948]

c  步骤 左孩子没有、  右孩子没有

第四次

a 步骤  最小索引5,最大索引7  A –>438

b步骤[438, 283, 107]

c  步骤 左孩子没有、, 右孩子6-7

第五次

a 步骤  最小索引6,最大索引7  A –>283

b步骤[283, 107]

c  步骤 左孩子没有、  右孩子没有

(2)具体实现

class Test

{

public static void main(String[] args)

{

int len = 8000000;

int[] oop = new int[len];

for(int i=0;i<len;i++)

oop[i] = (int)(Math.random()*1000);

Calendar c1 = Calendar.getInstance();

Sort.quick_sort(oop);

Calendar c2 = Calendar.getInstance();

System.out.println(c2.getTimeInMillis()-c1.getTimeInMillis());

}

}

class Binary

{

private int left,//最小索引

right;//最大索引

private Binary beforeBinary,//父节点

rightBinary,//左孩子

leftBinary;//右孩子

public Binary(int left,int right)

{

this.left= left;

this.right = right;

}

public void setLeft(int left)

{

this.left = left;

}

public void setRight(int right)

{

this.right = right;

}

public void setBefore(Binary beforeBinary)

{

this.beforeBinary = beforeBinary;

}

public void setRightBinary(Binary rightBinary)

{

this.rightBinary = rightBinary;

}

public void setLeftBinary(Binary leftBinary)

{

this.leftBinary = leftBinary;

}

public int getLeft()

{

return this.left;

}

public int getRight()

{

return this.right;

}

public Binary getBeforeBinary()

{

return this.beforeBinary;

}

public Binary getRightBinary()

{

return this.rightBinary;

}

public Binary getLeftBinary()

{

return this.leftBinary;

}

}

class Sort

{

public static void quick_sort(int[] oop)

{

Binary headBinary = new Binary(0,oop.length-1),

tempBinary  = headBinary;

int right,

left,

tempNumber;

boolean flag = true;

headBinary.setBefore(null);

do

{

left = tempBinary.getLeft();

right = tempBinary.getRight();

tempNumber = oop[left];

while(left<right)//结束循环后,tempNumber的左边是比他大的数,tempNumber的右边是比他小的数

{

while(left<right && tempNumber>=oop[right])//从右边找到比tempNumber大的数

right--;

if(left<right)

{

oop[left] = oop[right];//将右边的数赋值给左边的

left++;//缩减范围

}

while(left<right && tempNumber<=oop[left])//从左边开始找比tempNumber小的数

left++;

if(left<right)

{

oop[right] = oop[left];//将左边的数赋值给右边

right--;//缩减范围

}

}

//此时left==right

oop[left] = tempNumber;

if(right<tempBinary.getRight()-1)//创建左孩子

{

Binary c1 = new Binary(right+1,tempBinary.getRight());

tempBinary.setRightBinary(c1);

c1.setBefore(tempBinary);

}

if(left-1>tempBinary.getLeft()) //创建右孩子

{

Binary c1 = new Binary(tempBinary.getLeft(),left-1);

tempBinary.setLeftBinary(c1);

c1.setBefore(tempBinary);

}

flag = true;

do//操作A:(遍历左孩子、右孩子,如果左孩子、右孩子都被遍历,返回上次节点)重复A操作,直到遍历到跟节点

{

if(tempBinary.getLeftBinary() != null)//如果左孩子被创建了,就先遍历左孩子

{

Binary c1 = tempBinary.getLeftBinary();;

tempBinary.setLeftBinary(null);//最为重要,只要被遍历的左孩子就将起在上层节点的引用设为null,

tempBinary = c1;

flag = false;

}

else if(tempBinary.getRightBinary() != null)//右孩子总是左兄弟节点遍历后才被遍历

{

Binary c1 = tempBinary.getRightBinary();

tempBinary.setRightBinary(null);

tempBinary = c1;

flag = false;

}

else //左孩子。右孩子都被遍历返回父节点

{

if(tempBinary == headBinary) break;

tempBinary = tempBinary.getBeforeBinary();

}

}while(flag);

}while(tempBinary != headBinary);//当回溯到根节点时,说明排序完毕

}

}

(3)简单测试

80000000 内存溢出

8000000 66607ms

800000 1027ms

Java-使用二叉树实现快速排序-遁地龙卷风的更多相关文章

  1. 逻辑思维面试题-java后端面试-遁地龙卷风

    (-1)写在前面 最近参加了一次面试,对笔试题很感兴趣,就回来百度一下.通过对这些题目的思考让我想起了建模中的关联,感觉这些题如果没接触就是从0到1,考验逻辑思维的话从1到100会更好,并且编程简易模 ...

  2. jquery toggle方法使用出错?请看这里-遁地龙卷风

    这个函数在1.9之前和1.9之后的用法大不相同 1 1.9之间,用于点击元素时函数的轮流执行 toggle(function() { alert(1);//1,3,5,7... },function( ...

  3. JQuery data方法的使用-遁地龙卷风

    (-1)说明 我用的是chrome49,这个方法涉及到JQuery版本问题,我手里有3.0的,有1.9.1,后面将1.9.1及其以前的称为低版本,3.0称为高版本 测试例子用到的showMessage ...

  4. JQuery simpleModal插件的使用-遁地龙卷风

    (0)写在前面 jquery.simpleModal.浏览器这三者的兼容性,不仅显示在报错上,还体现在所呈现的效果不是预期上. 说一下我的环境 jquery-1.8.3.js jquery.simpl ...

  5. Java排序算法之快速排序

    Java排序算法之快速排序 快速排序(Quicksort)是对冒泡排序的一种改进. 快速排序由C. A. R. Hoare在1962年提出.它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分 ...

  6. java创建二叉树并实现非递归中序遍历二叉树

    java创建二叉树并递归遍历二叉树前面已有讲解:http://www.cnblogs.com/lixiaolun/p/4658659.html. 在此基础上添加了非递归中序遍历二叉树: 二叉树类的代码 ...

  7. Java实现二叉树及相关遍历方式

    Java实现二叉树及相关遍历方式 在计算机科学中.二叉树是每一个节点最多有两个子树的树结构.通常子树被称作"左子树"(left subtree)和"右子树"(r ...

  8. 数据结构(5):Java实现二叉树

    二叉树图: package com.test.Sort; import java.util.ArrayList; import java.util.LinkedList; public class B ...

  9. java实现二叉树的Node节点定义手撕8种遍历(一遍过)

    java实现二叉树的Node节点定义手撕8种遍历(一遍过) 用java的思想和程序从最基本的怎么将一个int型的数组变成Node树状结构说起,再到递归前序遍历,递归中序遍历,递归后序遍历,非递归前序遍 ...

随机推荐

  1. 设计与开发一款简单易用的Web报表工具(支持常用关系数据及hadoop、hbase等)

    EasyReport是一个简单易用的Web报表工具(支持Hadoop,HBase及各种关系型数据库),它的主要功能是把SQL语句查询出的行列结构转换成HTML表格(Table),并支持表格的跨行(Ro ...

  2. EF-InvalidOperation系列

    1.InvalidOperation强制转换为值类型 'System.Guid' 失败,因为实例化的值为 null.结果类型的泛型参数或查询必须使用可以为 null 的类型 错误信息: The cas ...

  3. SQL Server 解读【已分区索引的特殊指导原则】(3) - 非聚集索引分区

    一.前言 在MSDN上看到一篇关于SQL Server 表分区的文档:已分区索引的特殊指导原则,如果你对表分区没有实战经验的话是比较难理解文档里面描述的意思.这里我就里面的一些概念进行讲解,方便大家的 ...

  4. CSS系列:CSS中盒子之间的关系

    1. 标准文档流 标准文档流是值在不使用其他的雨排列和定位相关的特殊CSS规则时,各种元素的排列规则. 1.1 块级元素(block level) 块级元素不会排在同一行中,总是以一个块的形式表现出来 ...

  5. SQL Server 存储过程生成insert语句

    你肯定有过这样的烦恼,同样的表,不同的数据库,加入你不能执行select  insert 那么你肯定需要一条这样的存储过程,之需要传入表明,就会给你生成数据的插入语句. 当然数据表数量太大,你将最好用 ...

  6. 【结果很简单,过程很艰辛】记阿里云Ons消息队列服务.NET接口填坑过程

    Maybe 这个问题很简单,因为解决方法是非常简单,但填坑过程会把人逼疯,在阿里云ONS工作人员.同事和朋友的协助下,经过一天的调试和瞎捣鼓,终于解决了这个坑,把问题记下来,也许更多人在碰到类似问题的 ...

  7. 数据可视化-EChart2.0.0使用中遇到的2个问题

    之前项目中都是使用FusionChart和HighChart,基本都是没有购买商业许可.然后现在开发的系统需要交付给客户使用.所以现在图表控件不能直接使用FusionChart和HighChart,通 ...

  8. Windws Server 2008 R2 WEB环境配置之MYSQL 5.6.22安装配置

    版本选择 因为MySql的版本越来越多,而作为中小网站者可能没有足够的经济去购买商业版本,所以一般选择免费版,而且功能也是足够使用的. 有钱任性就下载企业版,哈哈. 目前使用最多的版本是mysql i ...

  9. iOS开发之SQLite--C语言接口规范(四) —— Result Values From A Query

    数据库的在上一篇博客中<SQLite之C语言接口规范(三)——Binding Values To Prepared Statements>用到了如何从查询结果中取出结果值.今天的博客就详细 ...

  10. Python学习第一弹——Python环境搭建

    一.Python简介: Python,是一种面向对象.解释型计算机程序设计语言,由Guido van Rossum于1989年底发明,第一个公开发行版发行于1991年.Python语法简洁而清晰,具有 ...