<!DOCTYPE HTML>
<html>
<head>
<title>排序算法</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<style>
</style>
</head>
<body>
<!-- content goes here -->
<input type="text" id="num">
<button onclick="sort()">开始排序</button>
<div id="msg"></div>
</body>
</html>
<script type="text/javascript" src="./mytools.js"></script>
<script type="text/javascript">
/*冒泡排序法 由大到小 (适合于基本已经排序完成 只有小部分需要交换的排序)
每两个相邻的数进行比较,若小则交换,
一次循环后,最后一个为最小数,开始下一次循环
若没有发生交换则说明排序完成
*/
function bubble_sort(arr)
{
var isSorted = true;
for(var i=0;i<arr.length;i++)
{
for(var j=0;j<arr.length-1-i;j++){
if(arr[j]<arr[j+1])
{
var temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
isSorted = false;
}
}
if(isSorted) //没有发生交换则说明排序完成
{
break;
}
}
}
/*比较排序法 由大到小
从第一个数开始,和后面的每一个数比较,可得到最大值
开始下一次循环得到第二小的值
全部循环完成排序
*/
function compare_sort(arr)
{
for(var i=0;i<arr.length-1;i++)
{
var n = i;
for(var j=i+1;j<arr.length;j++){
if(arr[j]>arr[n])
{
n=j; //只比较并记录位置 不进行交换
}
}
if(n!=i) //进行实际交换
{
var temp = arr[i];
arr[i] = arr[n];
arr[n] = temp;
}
}
}
/*插入排序法 由大到小
第一个数算已完排序,第二个数开始往已排序组里插入数据
直到全部循环完成排序
实例:
10 9 15 11 23 6 10
10 9 15 11 23 6 10 i=1 j=0 temp=9 arr[j]>temp 一次循环完成
10 9 9 11 23 6 10 i=2 j=1 temp=15
10 10 9 11 23 6 10 i=2 j=0 temp=15
15 10 9 11 23 6 10 i=2 j=-1 temp=15 j<0 二次循环完成
15 10 9 9 23 6 10 i=3 j=2 temp=11
15 10 10 9 23 6 10 i=3 j=1 temp=11
15 11 10 9 23 6 10 i=3 j=0 temp=11 arr[j]>temp三次循环完成
*/
function insert_sort(arr)
{
for(var i=1;i<arr.length;i++) //默认arr[0]已经排序完成 从arr[1]开始比较插入
{
var temp = arr[i]; //保存要插入的值
for(var j=i-1;j>=0&&arr[j]<temp;j--){ //由右向左开始比较 如果小于要插入的值则依次向右移位 直到最左或者遇到比插入值大的数
arr[j+1]=arr[j];
}
if(j+1!=i) //如果j+1==i则说明不需要移动
{
arr[j+1]=temp; //插入值
}
}
}
/*快速排序(分治排序)法 由大到小
找一个基准数并保存,数组空出位置
从右到左开始循环,如果遇到比基准数大的则保存到空出的的位置,空出本位置
从左到右开始循环,如果遇到比基准数小的则保存到空出的的位置,空出本位置
一直到左右循环相遇 一次循环结束 用基准数填充空位
左右半边数组开始递归
实例:
19 7 23 49 33 22 0 5 11 3
__ 7 23 49 33 22 0 5 11 3 key=19 _left=0 _right=9
22 7 23 49 33 __ 0 5 11 3 22>19 _left=0 _right=5 移动到空位 从右到左开始循环,如果遇到比基准数大的则保存到空出的的位置,空出本位置
22 __ 23 49 33 7 0 5 11 3 7<19 _left=1 _right=5 移动到空位 从左到右开始循环,如果遇到比基准数小的则保存到空出的的位置,空出本位置
22 33 23 49 __ 7 0 5 11 3 33>19 _left=1 _right=4 移动到空位 从右到左开始循环,如果遇到比基准数大的则保存到空出的的位置,空出本位置
22 33 23 49 __ 7 0 5 11 3 _left=4 _right=4 _left不小于_right 一次循环结束
22 33 23 49 | 19 | 7 0 5 11 3 用基准数填充空位 在基准数位置分割数组 开始递归
__ 33 23 49 (22) | 19 | _ 0 5 11 3 (7)
49 33 23 __ (22) | 19 | 11 0 5 _ 3 (7)
49 33 23 22 (22) | 19 | 11 _ 5 0 3 (7)
49 33 23 22 (22) | 19 | 11 7 5 0 3 (7)
49 33 23 | 22 | 19 | 11 | 7 | 5 0 3
__ 33 23 (49) | 22 | 19 | 11 | 7 | _ 0 3 (5)
49 33 23 (49) | 22 | 19 | 11 | 7 | 5 0 3 (5)
49 | __ 23 (33) | 22 | 19 | 11 | 7 | 5 | _ 3 (0)
49 | 33 23 (33) | 22 | 19 | 11 | 7 | 5 | 3 _ (0)
49 | 33 23 (33) | 22 | 19 | 11 | 7 | 5 | 3 0 (0)
49 | 33 | 23 | 22 | 19 | 11 | 7 | 5 | 3 | 0 排序完成
*/
function quick_sort (arr, left, right) {
var pivot=0;
var _left = left;
var _right = right;
if(_left<_right) //最少需要两个数
{
var key=arr[_left]; //选择最左边的数为基准数(随便选) arr[_left]为空位
while(_left<_right) {
//从右到左开始循环,如果遇到比基准数大的则保存到空出的的位置,空出本位置
while(_left<_right && arr[_right]<=key) { //比基数小则向左移位
_right--;
}
arr[_left]=arr[_right]; //比基数大则填充空位 arr[_right]为空位
//从左到右开始循环,如果遇到比基准数小的则保存到空出的的位置,空出本位置
while(_left<_right && arr[_left]>=key) { //比基数大则向左移位
_left++;
}
arr[_right]=arr[_left]; //比基数小则填充空位 arr[_left]为空位
}
//用基准数填充空位(循环结束则必然_left==_right)
arr[_left]=key;
//在基准数位置分割数组
pivot = _left;
//对分割的两个数组递归排序
quick_sort(arr,left,pivot-1);
quick_sort(arr,pivot+1,right);
}
}
function sort(){
var num = document.getElementById("num").value;
var msgDiv = document.getElementById('msg');
if(num>100000) {
//数字太大显示太慢
msgDiv.innerHTML = "数字太大,请不要超过十万";
return;
}
//创建要排序的数组(一万以内的随机数)
var arr = [];
for(i=0;i<num;i++)
{
arr.push(Math.floor(Math.random()*10000));
}
//创建三个副本
var arr1 = arr.slice(0);
var arr2 = arr.slice(0);
var arr3 = arr.slice(0);
var watch = new StopWatch();
msgDiv.innerHTML = num+"个随机数开始排序:<br>";
watch.Start();
insert_sort(arr);
watch.Stop();
console.log("插入排序:"+watch.time);
msgDiv.innerHTML += "插入排序:"+watch.time + "<br>";
watch.Start();
bubble_sort(arr1);
watch.Stop();
console.log("冒泡排序:"+watch.time);
msgDiv.innerHTML += "冒泡排序:"+watch.time + "<br>";
watch.Start();
compare_sort(arr2);
watch.Stop();
console.log("比较排序:"+watch.time);
msgDiv.innerHTML += "比较排序:"+watch.time + "<br>";
watch.Start();
quick_sort(arr3,0,arr3.length-1);
watch.Stop();
console.log("快速排序:"+watch.time);
msgDiv.innerHTML += "快速排序:"+watch.time + "<br>";
/*//查看排序结果
var mshow = "";
arr3.forEach(function(i,index){
mshow += " | "+i;
if((index+1)%10==0)
{
mshow += " | <br>";
}
})
msgDiv.innerHTML += mshow;
*/
}
</script>
运行结果:
10000个随机数开始排序:
插入排序:31
冒泡排序:165
比较排序:63
快速排序:4
快速排序的优势还是很明显的。