// 交换函数
function swap(arr,i,j) {
var temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
// 冒泡排序
function bubleSort(arr) {
var flag=true;
for(var i=0,len=arr.length;i<len&&flag;i++){
flag=false;
for(var j=len-1;j>i;j--){
if(arr[j]<arr[j-1]){
swap(arr,j,j-1);
flag=true;
}
}
}
return arr;
}
console.log('冒泡排序:',bubleSort([8,3,5,1,5,2,1]));
console.log('冒泡排序:',bubleSort([]));
// 选择排序
function selectSort(arr) {
for(var i=0,len=arr.length;i<len-1;i++){
var index=i;
for(var j=i+1;j<len;j++){
if(arr[j]<arr[index]){
index=j;
}
}
if(i!==index){
swap(arr,i,index);
}
}
return arr;
}
console.log('选择排序:',selectSort([8,3,5,1,5,2,1]));
// 直接插入排序
function insertSort(arr) {
for(var i=1,len=arr.length;i<len;i++){
var temp;
if(arr[i]<arr[i-1]){
temp=arr[i];
for(var j=i-1;arr[j]>temp;j--){
arr[j+1]=arr[j];
}
arr[j+1]=temp;
}
}
return arr;
}
console.log('直接插入排序:',insertSort([8,3,5,1,5,2,1]));
//希尔排序
function shellSort(arr){
var increment=arr.length;
do{
increment=Math.floor(increment/3)+1; // 注意js中的取整运算
for(var i=increment,len=arr.length;i<len;i++){
if(arr[i]<arr[i-increment]){
var temp=arr[i];
for(var j=i-increment;j>=0&&temp<arr[j];j-=increment){
arr[j+increment]=arr[j];
}
arr[j+increment]=temp;
}
}
}while(increment>1);
return arr;
}
console.log('希尔排序:',shellSort([8,3,5,1,5,2,1]));
//堆排序
function heapSort(arr) {
for(var i=Math.floor(arr.length/2)-1;i>=0;i--){ // 构建大顶堆
heapAdjust(arr,i,arr.length-1);
}
for(var j=arr.length-1;j>=0;j--){
//将堆顶元素与最后一个元素交换
var temp=arr[0];
arr[0]=arr[j];
arr[j]=temp;
//调整前j-1个元素组成的堆
heapAdjust(arr,0,j-1);
}
return arr;
}
function heapAdjust(arr,s,m) { // s是要调整元素的下标,m是堆中最后一个元素的下标
var temp,j;
temp=arr[s];
for(j=2*s+1;j<=m;j=2*j+1){
if(j<m&&arr[j]<arr[j+1])
j++;
if(temp>=arr[j]) // 如果arr[s]比其左右子节点都大,则跳出循环,此结点调整完毕
break;
arr[s]=arr[j]; // 否则当前结点的值被较大子节点代替
s=j; // 并将当前结点(接下来要调整的结点)设为较大子节点
}
arr[s]=temp;
}
console.log('堆排序:',heapSort([8,3,5,1,5,2,1]));
console.log('堆排序:',heapSort([1,2]));
//归并排序
function mergeSort(arr) {
if(arr.length===0){return [];}
Msort(arr,arr,0,arr.length-1);
return arr;
}
function Msort(arr,res,s,t) {
var m;
var TR2=[];
if(s===t){
res[s]=arr[s];
}else{
m=Math.floor((s+t)/2);
Msort(arr,TR2,s,m);
Msort(arr,TR2,m+1,t);
Merge(TR2,res,s,m,t);
}
}
// 将有序的SL[i...m]和SL[m+1...n]合并为有序的res[i...n]
function Merge(SL,res,i,m,n) {
var j,k,p;
for(k=i,j=m+1;i<=m&&j<=n;k++){ //从头开始遍历两个有序数组,直到有一个遍历到最后
if(SL[i]<SL[j]) { // 较小的放在前面
res[k]=SL[i++];
}else{
res[k]=SL[j++];
}
}
if(i<=m){
for(p=0;p<=m-i;p++){res[k+p]=SL[i+p];}
}
if(j<=n){
for(p=0;p<=n-j;p++){res[k+p]=SL[j+p];}
}
}
console.log('归并排序:',mergeSort([8,3,5,1,5,2,1]));
console.log('归并排序:',mergeSort([]));
// 快速排序
function QuikSort(arr) {
Qsort(arr,0,arr.length-1);
return arr;
}
function Qsort(arr,low,high) {
var pivot;
if(low<high){
pivot=Partition(arr,low,high);
Qsort(arr,low,pivot-1);
Qsort(arr,pivot+1,high);
}
}
function Partition(arr,low,high) {
// 三数取中,作为枢轴
var m=low+Math.floor((high-low)/2);
if(arr[low]>arr[high])
swap(arr,low,high);
if(arr[m]>arr[high])
swap(arr,m,high);
if(arr[m]>arr[low])
swap(arr,m,low);
var pivotkey=arr[low];// 此时low已经是三者中的中间值
var temp=pivotkey;// 替换的方法,而非交换的方法
while (low<high){
while (low<high&&arr[high]>=pivotkey){high--;}
//swap(arr,high,low); // 交换的方法
arr[low]=arr[high]; //采用替换的方法
while (low<high&&arr[low]<=pivotkey){low++;}
//swap(arr,low,high);
arr[high]=arr[low]; // 替换的方法
}
arr[low]=temp; // 替换的方法
return low; // 返回枢轴所在位置
}
console.log('快速排序:',QuikSort([50,10,90,30,70,40,60,80,20]));
console.log('快速排序:',QuikSort([2]));
js实现常见排序方法
最新推荐文章于 2023-05-08 17:03:37 发布