排序是常见的功能,给定一组数据,对其进行排序。

在此之前,我们需要准备个基础工作--自动生成数组,并可以对该组数据做任何处理。

/**
* 测试类 ,数组
* @param numElements
* @constructor
*/
function CArray(numElements){
var me = this;
me.dataStore = [];
me.pos = 0;
me.numElements = numElements;
me.insert = insert;
me.toString = toString;
me.clear = clear;
me.setData = setData;
me.swap = swap;
me.bubbleSort = bubbleSort;
me.selectionSort = selectionSort;
me.insertionSort = insertionSort; for(var i=0;i<numElements;++i){
me.dataStore[i] = i ;
}
function insert(element){
me.dataStore[me.pos++] = element;
}
function toString(){
var restr = "";
for ( var i = 0; i < me.dataStore.length; ++i ) {
restr += me.dataStore[i] + " ";
if (i > 0 & i % 10 == 0) {
restr += "\n";
}
}
return restr;
}
function clear(){
for(var i=0;i<me.dataStore.length;++i){
me.dataStore[i]=0;
}
}
function setData(){
for ( var i = 0; i < me.numElements; ++i ) {
me.dataStore[i] = Math.floor(Math.random() * (me.numElements + 1));
}
}
}

用例:

var n= 10000;
var mynums = new CArray(n);
mynums.setData();

接下来是排序算法的实现

冒泡排序

//冒泡排序算法
//比较相邻的数据 左侧大于右侧时将他们进行互换。
function bubbleSort(){
var elen = me.dataStore.length;
var temp ;
for(var outer = elen; outer>=2;--outer){
for(var inner = 0;inner<=outer -1; ++inner){
if(me.dataStore[inner]>me.dataStore[inner+1]){
swap(me.dataStore,inner,inner+1)
}
}
//console.log(me.toString()) //打印这个排序过程。
}
}

测试:

var n= 10000;
console.time("bubble")
//冒泡排序
var mynums = new CArray(n);
mynums.setData();
mynums.bubbleSort();
console.timeEnd("bubble")

选择排序

选择排序从数组的开头开始,将第一个元素和其他元素进行比较。检查完所有元素后,最小的元素会被放到数组的第一个位置,然后算法会从第二个位置继续。这个过程一直进行,当进行到数组的倒数第二个位置时,所有的数据便完成了排序.

//选择排序
//将第一个元素与其他元素比较,较小的放到数组第一个位置 依次比较
function selectionSort(){
var min,temp ;
for(var outer = 0;outer<=me.dataStore.length-2;++outer){
min = outer;
//比较第一个元素 跟第二个元素(依次递增下标再比较,直到找到一个最小的)
for(var inner = outer+1;inner<=me.dataStore.length-1;++inner){
if(me.dataStore[inner]<me.dataStore[min]){
min = inner ;
}
}
swap(me.dataStore,outer,min)
//console.log(me.toString()) //打印这个排序过程。
}
}

测试:

var n = 1000;
//选择排序
var mynums = new CArray(n);
mynums.setData();
mynums.selectionSort(); console.timeEnd("select")

插入排序:

插入排序有两个循环。外循环将数组元素挨个移动,而内循环则对外循环中选中的元素及它后面的那个元素进行比较。如果外循环中选中的元素比内循环中选中的元素小,那么数组元素会向右移动,为内循环中的这个元素腾出位置

//插入排序
//将一堆数据开始排序,如果小,就往左放(此时数据已经在数组中占得一个下标,我们就把他下标右移一个位置,并把这个小的放左边)
function insertionSort(){
var temp,inner;
for(var outer=1;outer<=me.dataStore.length-1;++outer){
temp = me.dataStore[outer];
inner = outer;
while(inner>0&&(me.dataStore[inner-1]>=temp)){
me.dataStore[inner]=me.dataStore[inner-1];
--inner;
}
me.dataStore[inner]=temp;
// console.log(me.toString()) //打印这个排序过程。
}
}

测试:

//插入排序
var mynums = new CArray(n);
mynums.setData();
mynums.insertionSort(); console.timeEnd("insert")

高级排序

高级数据排序算法。它们通常被认为是处理大型数据集的最高效排序算法,它们处理的数据集可以达到上百万个元素,而不仅仅是几百个或者几千个。

希尔排序

希尔排序的工作原理是,通过定义一个间隔序列来表示在排序过程中进行比较的元素之间有多远的间隔,它会首先比较距离较远的元素,而非相邻的元素。和简单地比较相邻元素相比,使用这种方案可以使离正确位置很远的元素更快地回到合适的位置。

第一版:

//希尔排序
//定义间隔序列 在排序的时候到根据序列比较,动态调整序列的位置 。这种方案可以使离正确位置很远的元素更快地回到合适的位置。
//至于间隔序列是多少呢? 有很多个不同的序列 我们用的是Marcin Ciura 2001公开的序列 701 301 132 57 23 10 4 1
function shellsort(){
for (var g = 0; g < this.gaps.length; ++g) {
for (var i = this.gaps[g]; i < this.dataStore.length; ++i) {
var temp = this.dataStore[i];
for (var j = i; j >= this.gaps[g] && this.dataStore[j- this.gaps[g]] > temp;
j -= this.gaps[g]) {
this.dataStore[j] = this.dataStore[j - this.gaps[g]];
}
this.dataStore[j] = temp;
}
}
}
//定义间隔序列
function setGaps(arr){
me.gaps = arr;
}

第一版 我们需要遵循一个 固定的间隔序列。当你有不同数量的数据时,固定间隔序列会不适用现在的程序,所以呢,动态设定间隔序列就很有必要了。

第二版:

//希尔排序( 动态计算间隔序列)
function shellsort1(){
var N = this.dataStore.length;
var h = 1;
while (h < N/3) {
h = 3 * h + 1;
}
while (h >= 1) {
for (var i = h; i < N; i++) {
for (var j = i; j >= h && this.dataStore[j] < this.dataStore[j-h];j -= h) {
swap(this.dataStore, j, j-h);
}
}
h = (h-1)/3;
}
}

测试:

console.time("shell")
//希尔排序
var mynums = new CArray(n);
mynums.setData();
mynums.shellsort(); console.timeEnd("shell")
console.time("shell1")
//希尔排序
var mynums = new CArray(n);
mynums.setData();
mynums.shellsort1(); console.timeEnd("shell1")

归并排序

把一系列排好序的子序列合并成一个大的完整有序序列。

我们需要两个排好序的子数组,然后通过比较数据大小,先从最小的数据开始插入,最后合并得到第三个数组。

自顶向下的归并排序 因实现需要递归(数据多的话递归太深) 所以采取 自底向上的归并排序

自底向上的归并排序

这个算法首先将数据集分解为一组只有一个元素的数组。然后通过创建一组左右子数组将它们慢慢合并起来,每次合并都保存一部分排好序的数据,直到最后剩下的这个数组所有的数据都已完美排序

代码:

function mergeSort() {
if (this.dataStore.length < 2) {
return;
}
var step = 1;
var left, right;
while (step < this.dataStore.length) {
left = 0;
right = step;
while (right + step <= this.dataStore.length) {
mergeArrays(this.dataStore, left, left+step, right, right+step);
left = right + step;
right = left + step;
}
if (right < this.dataStore.length) {
mergeArrays(this.dataStore, left, left+step, right, this.dataStore.length);
}
//步进值
step *= 2;
}
}
function mergeArrays(arr, startLeft, stopLeft, startRight, stopRight) {
var rightArr = new Array(stopRight - startRight + 1);
var leftArr = new Array(stopLeft - startLeft + 1);
k = startRight;
//处理右边数组
for (var i = 0; i < (rightArr.length-1); ++i) {
rightArr[i] = arr[k];
++k;
}
//处理左边数组
k = startLeft;
for (var i = 0; i < (leftArr.length-1); ++i) {
leftArr[i] = arr[k];
++k;
}
rightArr[rightArr.length-1] = Infinity; // 哨兵值
leftArr[leftArr.length-1] = Infinity; // 哨兵值
//合并
var m = 0;
var n = 0;
for (var k = startLeft; k < stopRight; ++k) {
if (leftArr[m] <= rightArr[n]) {
arr[k] = leftArr[m];
m++;
} else {
arr[k] = rightArr[n];
n++;
}
}
//console.log("left array - ", leftArr);
//console.log("right array - ", rightArr);
}

测试:

console.time("mergeSort")
//归并排序
var mynums = new CArray(n);
mynums.setData();
mynums.mergeSort(); console.timeEnd("mergeSort")

通过测试,发现归并排序跟 希尔排序效率差不多(10000个数据)

快排

简单地讲 将数据分解为 大于或者小于 [基准值] 的2部分,通过递归的方式直至完成。

代码

function qSort(arr) {
if (arr.length == 0) {
return [];
}
var left = [];
var right = [];
var pivot = arr[0];
for (var i = 1; i < arr.length; i++) { if (arr[i] < pivot) {
left.push(arr[i]);
} else {
right.push(arr[i]);
}
}
return qSort(left).concat(pivot, qSort(right));
}

测试:

console.time("qSort")
//快速排序
var mynums = new CArray(n);
mynums.setData();
var list = mynums.getData();
mynums.qSort(list); console.timeEnd("qSort")

排序算法 -- 数据结构与算法的javascript描述 第12章的更多相关文章

  1. 列表的实现-----数据结构与算法JavaScript描述 第三章

    实现一个列表 script var booklist = new List(); booklist.append('jsbook'); booklist.append('cssbook'); book ...

  2. 数据结构与算法分析——C语言描述 第三章的单链表

    数据结构与算法分析--C语言描述 第三章的单链表 很基础的东西.走一遍流程.有人说学编程最简单最笨的方法就是把书上的代码敲一遍.这个我是头文件是照抄的..c源文件自己实现. list.h typede ...

  3. 排序算法总结第二弹----冒泡排序---javascript描述

    上篇博文总结了选择排序,这篇来看冒泡排序,接上篇. 冒泡排序思想:若是正再将一组数据升序排序, 第一趟:比较相邻的数据,当左侧值大于右侧值将他们进行交换,将较小值向前浮动,大值向后冒泡,直至比较到最后 ...

  4. 检索算法 -- 数据结构与算法的javascript描述 第13章

    检索算法-如何在列表中查找特定的值. 顺序查找 从列表的第一个元素开始对列表元素逐个进行判断,直到找到了想要的结果,它属于暴力查找技巧的一种,在执行查找时可能会访问到数据结构里的所有元素. 代码: / ...

  5. 字典 -- 数据结构与算法的javascript描述 第七章

    字典 字典是一种以键-值对形式存储数据的数据结构 最基本功能规划 add 添加数据到字典 remove 从字典中移除数据 get 从字典中取出数据 count 统计字典数据量 find 查找数据在字典 ...

  6. 读书笔记《数据结构与算法JavaScript描述》第一章

    第一章JavaScript的编程环境和模型 1.2JavaScript编程实践 1.2.1 声明和初始化变量 JavaScript中的变量默认为全局变量,如果初始化未被声明的变量,该变量就成了一个全局 ...

  7. 链表的实现 -- 数据结构与算法的javascript描述 第六章

    链表 链表是由一组节点组成的集合.每个节点都使用一个对象的引用指向它的后继.指向另一个节点的引用叫做链 结构示意图 : 链表头需要我们标识 head { element:head,next:obj1 ...

  8. 队列的实现 -- 数据结构与算法的javascript描述 第五章

    队列也是列表的一种,有不同于列表的规则. 先进先出 入队方法 出队方法 可以找到队首 可以找到队尾 可以查看队列有多长 可以查看队列是否为空 这是一个基本的需求,围绕他来实现,当然我们可以自己扩展列表 ...

  9. 栈的实现 -- 数据结构与算法的javascript描述 第四章

    栈 :last-in-first-out 栈有自己特殊的规则,只能 后进入的元素 ,最先被推出来,我们只需要模拟这个规则,实现这个规则就好. peek是返回栈顶元素(最后一个进入的). /** * 栈 ...

随机推荐

  1. Eclipse 支持jQuery 自动提示

    1.下载jQuery文件 http://download.csdn.net/detail/emoven/6294377 2.设置spket Window -> Preferences -> ...

  2. linux动态库加载的秘密

    摘自http://gotowqj.iteye.com/blog/1926734 摘自http://www.360doc.com/content/14/0313/13/12747488_36024641 ...

  3. Hadoop 7、MapReduce执行环境配置

    MR执行环境有两种:本地测试环境,服务器环境 本地测试环境(windows,用于测试) 1.下载Winddows版的Hadoop程序,解压后在Hadoop目录的bin目录放置一个winutils.ex ...

  4. SNMP协议具体解释

    简单网络管理协议(SNMP)是TCP/IP协议簇的一个应用层协议.在1988年被制定,并被Internet体系结构委员会(IAB)採纳作为一个短期的网络管理解决方式:因为SNMP的简单性,在Inter ...

  5. 依赖注入及AOP简述(三)——依赖注入的原理

    3.     “依赖注入”登场 于是诸多优秀的IT工程师开始想出了更加轻量便利.更加具有可测试性和可维护性的设计模式——IoC模式.IoC,即Inversion of Control的缩写,中文里被称 ...

  6. 绿色mysql启动脚本

    启动脚本如下:./mysqld_safe --defaults-file=/export/servers/mysql-5.5.38/my.cnf --ledir=/export/servers/mys ...

  7. SWFUpload的使用及其注意事项

    SWFUpload的使用: 添加Jquery    swfuploaad.js  handler.js文件 配置参数: upload_url:文件将要被传到的处理程序 post_params:{“”: ...

  8. 读书笔记一 Java程序员的基本修养(数组及其内存管理)

    1.1 数组初始化 1.1.1 java数组是静态的 java数组被初始化之后,该数组所占的内存空间.数组长度都是不可变的. java程序中的数组必须经过初始化才可使用. 数组的初始化有两种方式: 1 ...

  9. adb server didn t ack failed to start daemon

    关掉Ecilpse,打开cmd命令行 1)cd到sdk的platform-tools目录下, 2)执行  adb kill-server  ,出现  server not runing 提示 3)执行 ...

  10. jvm强制类型转换

    public class Integer_Object { public static void main(String[] args){ Object obj = new ooo(); // Int ...