数据结构与算法--排序
Posted 煜成'Studio
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构与算法--排序相关的知识,希望对你有一定的参考价值。
数据结构与算法–排序
大O表示法
O(1):常数的,变化曲线为水平的;
O(long(n)):对数的,变化曲线几乎水平,例如二分法;
O(n):线性的;O(nlog(n)):线性和对数乘积;
O(n2):平方;O(2n):指数的
排序算法有很多:
冒泡排序;选择排序;插入排序;归并排序;计数排序counting sort;基数排序radix sort;希尔排序;堆排序;桶排序
简单排序:冒泡排序;选择排序;插入排序
高级排序:快速排序;希尔排序
//创建列表类
function ArrayList()
//属性
this.array = [];
//方法
//将数据可以插入到数组中的方法
ArrayList.prototype.insert = function (item)
this.array.push(item);
//toString
ArrayList.prototype.toString = function ()
return this.array.join('-'); //将数组转换为字符串,并且中间以-分隔
//交换两个位置的数据
ArrayList.prototype.swap = function (m, n)
var temp = this.array[m];
this.array[m] = this.array[n];
this.array[n] = temp;
//简单排序
//冒泡排序
//冒泡排序的比较次数:(n-1)+(n-2)+...+1=n(n-1)/2,时间复杂度为O(n^2)
//冒泡排序的交换次数:如果平均两次比较才需要交换一次(不可能每次比较都交换一次),那么交换次数为n^2/4,时间复杂度为O(n^2)
ArrayList.prototype.bubbleSort = function ()
var length = this.array.length;
for (var i = length - 1; i >= 0; i--)
for (var j = 0; j < i; j++)
if (this.array[j] > this.array[j + 1])
this.swap(j, j + 1)
//选择排序
//选择排序的比较次数:(n-1)+(n-2)+...+1=n(n-1)/2,时间复杂度为O(n^2)
//选择排序的交换次数:n-1次,时间复杂度为O(n)
//选择排序通常认为在执行效率上是高于冒泡排序的。
ArrayList.prototype.selectionSort = function ()
var length = this.array.length;
for (var i = 0; i < length - 1; i++)
var min = i;
for (var j = i + 1; j < length; j++)
if (this.array[min] > this.array[j])
min = j;
this.swap(min, i);
//插入排序
//插入排序是简单排序中效率最好的一种,思路是局部有序,然后找一个标记的数和局部有序的序列中比较并插入
//插入排序的最多的比较次数1+2+...+n=n*(n-1)/2,平均比较次数为n*(n-1)/4,而冒泡排序和选择排序的平均比较次数为n*(n-1)/2,是插入排序的二倍
//插入排序的复制(比较并移位)次数,最多为n*(n-1)/2,平均为n*(n-1)/4,而且这种复制一次比冒泡排序和选择排序的那种交换更加节省性能。
ArrayList.prototype.insertionSort = function ()
var length = this.array.length;
//外层循环:从第一个位置开始获取数据,向前面局部有序进行插入
for (var i = 1; i < length; i++)
//内层循环:获取i位置元素,和前面的数据依次进行比较
var temp = this.array[i];
while (this.array[i - 1] > temp && i > 0)
this.array[i] = this.array[i - 1];
i--;
//将temp放置到i位置
this.array[i] = temp;
//高级排序
//希尔排序
//希尔排序的增量有希尔自己提出的增量、Hibbard增量序列、Sedgewick增量序列
//效率和增量有关,最坏的时间复杂度是O(n^2),通常情况下都是要好于O(n^2),大多数情况下效率都要好于简单排序,甚至在合适的猪呢个两和某些数量n的情况下,还要好于快速排序
ArrayList.prototype.shellSort = function ()
var length = this.array.length;
//初始化的增量
var gap = Math.floor(length / 2);
//while循环,gap不断减小
while (gap >= 1)
//以gap作为间隔进行分组,对分组进行插入排序
for (var i = gap; i < length; i++)
var temp = this.array[i];
//插入排序代码
while (this.array[i - gap] > temp && i > gap - 1)
this.array[i] = this.array[i - gap];
i -= gap;
this.array[i] = temp;
//增量变化
gap = Math.floor(gap / 2);
//快速排序
//ps:取一个随机数这个本身是一个非常耗性能的操作
//快速排序的效率是O(n*logn)
//选择枢纽,收、中、尾三个数的中位数
ArrayList.prototype.median = function (left, right)
var center = Math.floor((left + right) / 2);
if (this.array[left] > this.array[center])
this.swap(left, center);
if (this.array[center] > this.array[right])
this.swap(center, right);
if (this.array[left] > this.array[center]) //这一步的判断是必须的,因为上一步交换完之后不清楚首、中哪个数更大
this.swap(left, center);
//将center位置和right-1位置交换,最right肯定大于center,直接不用考虑了
this.swap(center, right - 1);
return this.array[right - 1]; //这是那个中位数
//快速排序代码
ArrayList.prototype.quickSort = function ()
this.quick(0, this.array.length - 1);
//递归代码
ArrayList.prototype.quick = function (left, right)
//结束条件
if (left >= right) return;
//获取枢纽
var pivort = this.median(left, right);
//定义变量,用于记录当前找到的位置
var i = left;
var j = right - 1;
//开始进行交换
while (true)
while (this.array[++i] < pivort) ;
while (this.array[--j] > pivort) ;
if (i < j)
this.swap(i, j);
else
break;
//将枢纽放置在正确的位置,也就是i的位置上
this.swap(i, right - 1);
//递归
this.quick(left, i - 1);
this.quick(i + 1, right);
//测试
var list = new ArrayList();
//插入元素
list.insert(66)
list.insert(88)
list.insert(12)
list.insert(87)
list.insert(100)
list.insert(5)
list.insert(566)
list.insert(23)
alert(list);
// //验证冒泡排序
// list.bubbleSort();
// alert(list);
//验证选择排序
// list.selectionSort();
// alert(list);
// //验证插入排序
// list.insertionSort();
// alert(list);
// //验证希尔排序
// list.shellSort();
// alert(list);
// //验证快速排序
list.quickSort();
alert(list);
以上是关于数据结构与算法--排序的主要内容,如果未能解决你的问题,请参考以下文章