复习了一下数据结构的排序算法,一年之前学的东西,现在拿来练习时,感慨挺多的。
写在前面的话
可能马上就要面试了,我还是有点慌的,今天看了数据结构的排序,并尝试着用js来写了一下,虽然没有什么实际的意义,但还是有点个人的理解和感悟和大家分享:有人说编程的世界就是数据结构和算法,我觉得并不是。更确切的说,数据结构和算法是思想和灵魂,语言就是表达和实现思想的工具。可能你熟悉了一种语言,你就会用这门语言固定的工具去套用那些思想来完成一个任务,而换了一个语言,你仍然会用你熟悉的语言的工具方法去实现一个任务。
那现在有了飞机,你还用跑步去目的地么?
了解一个算法的思想是很重要的,实现一个算法可能是很简单的。一切所谓的伟大的前提,都是你敢想。
几种排序的思想灵魂—–遍历次数,结束条件
先说冒泡:一次排序之后,总会把最大的找出来。冒泡是相邻的两个比较,大小交换,标号下移,在重复此过程。结束条件:直到一次排序过程中没有交换,说明已经有序,结束。
var bubbleSort=function(arry){
var change=0;
for(var i=arry.length-1;i>=0&&change==0;i--){
change=1;//用来记录是否有交换
for(var j=0;j<i;j++){//从头开始一次排序,j<i,每当一次排序结束时,总会有一个最大值,这样,接下来的排序就应该少用一个。
if(arry[j]>arry[j+1]){
var temp=arry[j];
arry[j]=arry[j+1];
arry[j+1]=temp;
change=0;
}
}
}
return arry;
};
外层循环是排序的次数,内层的循环是遍历元素交换。
再说快排:理论上讲,冒泡和快排都是一种借助了交换的方法。
快排的基本思想就是二分,找到一个key作为基本点进行左右二分,这个key被形象的称为“枢轴”。一次快排中,比key小的被分到一起成为新的快排对象,比key大的被分到一起成为新的快排对象,接下来。。。没错,接下来就是递归的过程了。
这里,我先用原始的方法写了一遍,原始方法是利用下标来完成移动的过程的。
function qSort(arry,i,j){
if(i>j){return;}//递归出口,i>j时,说明找到key的位置,结束
var low=i ;
var high=j;
var key=arry[i];
while(i<j){
while((i<j)&&(arry[j]>=key)) --j;//找位子
arry[i]=arry[j];
while((i<j)&&(arry[i]<=key)) ++i;//找位子
arry[j]=arry[i];
}
arry[i]=key;//到这里,就是一次二分,你可以把下面的递归注释,来看看结果。
qSort(arry,low,i-1);//开始递归。
qSort(arry,i+1,high);
}
var ay=[3,2,4,6,1,8,0];
qSort(ay);
alert(ay);
其实,我们再来理解一下,我把比key大的放一组,比key小的放一组,在对大的和小的做重复的操作,那么,真正结束的条件应该是直到当你分的组里面只有一个元素,那就是key的时候,你就分完了,整体也就有序了。
js提供了丰富的数据操作,就是不想让你把时间花在来回弄下标玩,把二分的思想最直接的表现出来,应该是这样的代码(我逛博客时发现的!)
function qSort(arry){
if(arry.length==0)
return [];
var right=[],left=[];
var key=arry[0];
for(var i=1;i<arry.length;i++){
if(arry[i]>key){
right.push(arry[i]);//分组
}else{
left.push(arry[i]);//分组
}
}
return qSort(left).concat(key,qSort(right));//递归
}
document.write(qSort([3,1,2,6,4]));
插入排序
每一次排序结束,之前的部分都会是有序的,这就意味着,你是在一个有序的数列的基础上排序的。你需要用你接下来的元素和这个有序的数列比较,并插入到应该在的位子,知道遍历了所有的元素。
一个要注意的地方就是当你知道了要插入的位子时的插入操作,可能简单的想,就插入进去被,然后后面的依次后移,这种方法完全可以,你需要一个新的数组,向这个数组中不断的插入新的元素,来完成排序。
也可以不用,当你找到了要插入的位子时,以此时你的元素key位子为起点,向插入的位子,也就是向前位移,这是一个元素覆盖的过程,到你指定要插入的位子时,将此位置覆盖为key,完成移动。
function insetSort(arry){
var i= 1;
for(i;i<arry.length;i++){
var key=arry[i];
var j=0;
while((j<i)&&(arry[j]<key)) ++j;//找位子
if(i!=j){
for(i;i>j;i--){
arry[i]=arry[i-1];
}
arry[j]=key;
}
}
}
var ay=[3,2,4,6,1,8,0];
insetSort(ay);
alert(ay);
若有不足,希望指点提出,感谢各位。