排序算法 -- 数据结构与算法的javascript描述 第12章
排序是常见的功能,给定一组数据,对其进行排序。
在此之前,我们需要准备个基础工作--自动生成数组,并可以对该组数据做任何处理。
/**
* 测试类 ,数组
* @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章的更多相关文章
- 列表的实现-----数据结构与算法JavaScript描述 第三章
实现一个列表 script var booklist = new List(); booklist.append('jsbook'); booklist.append('cssbook'); book ...
- 数据结构与算法分析——C语言描述 第三章的单链表
数据结构与算法分析--C语言描述 第三章的单链表 很基础的东西.走一遍流程.有人说学编程最简单最笨的方法就是把书上的代码敲一遍.这个我是头文件是照抄的..c源文件自己实现. list.h typede ...
- 排序算法总结第二弹----冒泡排序---javascript描述
上篇博文总结了选择排序,这篇来看冒泡排序,接上篇. 冒泡排序思想:若是正再将一组数据升序排序, 第一趟:比较相邻的数据,当左侧值大于右侧值将他们进行交换,将较小值向前浮动,大值向后冒泡,直至比较到最后 ...
- 检索算法 -- 数据结构与算法的javascript描述 第13章
检索算法-如何在列表中查找特定的值. 顺序查找 从列表的第一个元素开始对列表元素逐个进行判断,直到找到了想要的结果,它属于暴力查找技巧的一种,在执行查找时可能会访问到数据结构里的所有元素. 代码: / ...
- 字典 -- 数据结构与算法的javascript描述 第七章
字典 字典是一种以键-值对形式存储数据的数据结构 最基本功能规划 add 添加数据到字典 remove 从字典中移除数据 get 从字典中取出数据 count 统计字典数据量 find 查找数据在字典 ...
- 读书笔记《数据结构与算法JavaScript描述》第一章
第一章JavaScript的编程环境和模型 1.2JavaScript编程实践 1.2.1 声明和初始化变量 JavaScript中的变量默认为全局变量,如果初始化未被声明的变量,该变量就成了一个全局 ...
- 链表的实现 -- 数据结构与算法的javascript描述 第六章
链表 链表是由一组节点组成的集合.每个节点都使用一个对象的引用指向它的后继.指向另一个节点的引用叫做链 结构示意图 : 链表头需要我们标识 head { element:head,next:obj1 ...
- 队列的实现 -- 数据结构与算法的javascript描述 第五章
队列也是列表的一种,有不同于列表的规则. 先进先出 入队方法 出队方法 可以找到队首 可以找到队尾 可以查看队列有多长 可以查看队列是否为空 这是一个基本的需求,围绕他来实现,当然我们可以自己扩展列表 ...
- 栈的实现 -- 数据结构与算法的javascript描述 第四章
栈 :last-in-first-out 栈有自己特殊的规则,只能 后进入的元素 ,最先被推出来,我们只需要模拟这个规则,实现这个规则就好. peek是返回栈顶元素(最后一个进入的). /** * 栈 ...
随机推荐
- poj 1458 Common Subsequence_最长公共子串
题意:略 求最长公共子串 #include<iostream> #include<cstdio> #include<string> using namespace ...
- python list求交集
方法一: a=[1,2,3] b=[1,3,4] c=list(set(a).intersection(set(b))) print c #[1,3] 这种方法是先把list转换为set,再用set求 ...
- hdu 5595 GTW likes math(暴力枚举查询)
思路:直接暴力枚举区间[l,r]的整数值,然后max和min就可以了. AC代码: #pragma comment(linker, "/STACK:1024000000,1024000000 ...
- [Linux] rlwrap - 解决Linux下sqlplus退格、上翻键乱码问题
在Linux下使用sqlplus你会发现:退格键无法正常使用(乱码),上翻键也无法正常显示历史功能,非常讨厌! 为了让退格键和上翻键在sqlplus里正常发挥它的作用,我们必须安装一个软件 - rlw ...
- java整合easyui进行的增删改操作
首先发一下效果图 显示全部用户信息 加入用户信息 删除用户信息 编辑用户信息 以下就来介绍一下easyui的crud,在java中是怎么与后台进行交换的 前台html页面,我将它命名为crud1.ht ...
- 从U盘安装win8系统
http://blog.csdn.net/pipisorry/article/details/40662397 lz提示,下面也能够用于win7.linux等操作系统的安装 一.下载windows安装 ...
- 10个原生JavaScript技巧
这些代码片段主要由网友们平时分享的作品代码里面和经常去逛网站然后查看源文件收集到的.把平时网站上常用的一些实用功能代码片段通通收集起来,方便网友们学习使用,利用好的话可以加快网友们的开发速度,提高工作 ...
- php预定义常量&变量
PHP中可以使用预定义常量获取PHP中的信息,常用的预定义常量如下表所示. 常量名 功能 _FILE_ 默认常量,PHP程序文件名 _LINE_ 默认常量,PHP程序行数 PHP_VERSION ...
- dpkg, APT, aptitude常用命令
Install dpkg --install, -i [deb] apt-get install [package] aptitude install [package] Remove dpkg -- ...
- oracle中的初始化参数文件
oracle初始化参数文件管理 oracle实例是指运行状态下的oracle软件,是由内存结构跟一些进程结构组成的,主要实现数据库的访问跟控制功能,是oracle的核心. 初始化参数文件是oracle ...