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

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

/**
* 测试类 ,数组
* @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. Matrix, Her, Transcendence

    The Matrix showed us a traditional perspective of computation theory, which is a hierarchical world ...

  2. hdu 4185 Oil Skimming(二分图匹配 经典建图+匈牙利模板)

    Problem Description Thanks to a certain "green" resources company, there is a new profitab ...

  3. get方式中文乱码问题

    <a target="_blank" href="ftpFileAction!downloadFile.action?filename=测试.xml"&g ...

  4. android开发 不注意的异常

    近期刚上班,做了一个应用,要上线.測试天天測试,天天有bug,个人总结了几个常常忽略的地方: 1:在 继承 BaseAdapter 的 @Override public int getCount() ...

  5. oracle子查询

    子查询:在一个查询的内部包含另外一个查询. 普通子查询 -- 查询出比7654工资还高的所有雇员的信息 select * from emp e where e.sal > (select sal ...

  6. 字符串对比.net String.EndsWith方法 (String)

    string str="web/abc.aspx"; if(str.EndsWith("abc.aspx")) { 此方法将 value 与位于此实例末尾.与 ...

  7. C# Winform下载文件并显示进度条

    private void btnDown_Click(object sender, EventArgs e) { DownloadFile("http://localhost:1928/We ...

  8. Oracle视图基础

    --表的另一种形式,看起来很像表 --用view可以实现复杂的query====select --创建一个视图 --当经常使用这个查询时封装成view /*create or replace 表示在创 ...

  9. 动态获取UIWebView的真正高度

    场景 在 App 中使用UIWebView加载网页, 与原生的 UI 显示在一起,一般情况下,webView 的 内容一页是肯定不够的,换句话说,webView 的高度是不定的,那如果原生的 UI是一 ...

  10. java集合类遍历删除方法测试以及使用场景记录

    package test0; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java. ...