一、冒泡排序:兩兩比較,大的放後面,小的放前面;使用兩個for循環,一個數就不用比了,所以第一個for循環遍歷次數n-1次,第二個for比較次數n
// 冒泡排序:思路=》兩兩交換,大的放後面,小的放前面,第一次排序後最大值已在數組末尾
// 代碼實現:兩個for循環,外層循環控制排序的趟數,內層循環控制比較次數。每趟過後比較次數都應該減一
function sort (arr,n){
let temp
for(let i=0;i<n-1;i++){
for (let j=0;j<n-i-1;j++) {
if(arr[j]>arr[j+1]){
temp = arr[j+1]
arr[j+1] = arr[j]
arr[j] = temp
}
}
}
return arr
}
let arr = [3,2,5,7,9,4,1,6]
let n = arr.length
console.log(sort(arr,n));
// [1, 2, 3, 4, 5, 6, 7, 9]
function sort (arr,n){
let temp
for(let i=0;i<n-1;i++){
for (let j=i+1;j<n;j++) {
if(arr[i]<arr[j]){
temp = arr[j]
arr[j] = arr[i]
arr[i] = temp
}
}
}
return arr
}
let arr = [3,2,5,7,9,4,1,6]
let n = arr.length
console.log(sort(arr,n));
// [9, 7, 6, 5, 4, 3, 2, 1]
二、選擇排序
// 選擇排序:找到數組中最大的元素,與數組最後一位元素交換。當只有一個數時,則不需要選擇了,所以需要n-1趟排序
// 思路:兩個for循環,外層循環控制排序的趟數,內層循環找到當前趟數的最大值,隨後與當前趟數數組最後的一位元素交換
function sort (arr,n){
let temp
let max=0
for(let i=0;i<n-1;i++){
for (let j=0;j<n-i;j++) {
if(arr[j]>arr[max]){
max=j
}
}
temp=arr[max]
arr[max] = arr[n-1-i]
arr[n-1-i]=temp
}
return arr
}
let arr1 = [3,2,5,7,9,4,1,6,8]
let n1 = arr1.length
console.log(sort(arr1,n1));
//[1, 2, 3, 4, 5, 6, 7, 8, 9]
三、快速排序 :取一個數作爲基準值[以中間項爲基準值],小於這個基準數的放在左邊,大於基準值的放在右邊,遞歸
三種實現的方式,參考如下
/*
大致分三步:
1、找基準(一般是以中間項爲基準)
2、遍歷數組,小於基準的放在left,大於基準的放在right
3、遞歸
*/
function quickSort(arr){
//如果數組<=1,則直接返回
if(arr.length<=1){
return arr
}
let pointIndex = Math.floor(arr.length/2) //基準值
let left = []
let right = []
let point = arr.splice(pointIndex,1)[0] //把基準從原來的數組中刪除
for(let i=0;i<arr.length;i++){
// 小於基準的放在左邊
if(arr[i]<=point){
left.push(arr[i])
}else{ //大於基準的放右邊
right.push(arr[i])
}
}
//遞歸
return quickSort(left).concat([point],quickSort(right));
}
let arr = [3,2,5,7,9,4,1,6]
console.log(quickSort(arr));
// 快速排序:取一個數作爲基準值[以中間項爲基準值],小於這個基準數的放在左邊,大於基準值的放在右邊,遞歸
function sort (arr,l,r){
let i = l
let j =r
let c = Math.floor((l+r)/2) //取中間值作爲指點,比較
console.log('c==='+c);
let temp
// 左右兩端進行掃描,只要兩端還沒有交替,就一直掃描
while(i<=j){
// 尋找直到比支點大的數
while(arr[i]<arr[c]){
i++
console.log('i====='+i);
}
// 尋找直到比支點小的數
while(arr[c]<arr[j]){
j--
console.log('j===='+j);
}
// 此時找到了比支點小的數(右邊),比支點大的數(左邊),將他們交換位置
if(i<=j){
temp = arr[i]
arr[i] = arr[j]
arr[j] = temp
i++
j--
}
console.log(arr);
}
// “左邊”再做排序,直到左邊剩下一個數(遞歸出口)
if(l<j){
sort(arr,l,j)
}
// "右邊"再做排序,直到右邊剩下一個數(遞歸出口)
if(i<r){
sort(arr,i,r)
}
console.log(arr);
}
let arr1 = [3,2,5,7,9,4,1,6,8]
let n1 = arr1.length
sort(arr1,0,n1-1)
function quickSort(arr, left, right) {
/*
* len爲數組的長度;
* left爲需要數組中參與排序的起始點;right爲數組中參與排序的終止點;
* left如果有傳數字那麼就爲left,沒有傳參則爲0;
* right如果有傳參那麼就爲right,沒有傳參則爲len-1;
* 有傳參可能會部分排序可能不會排序,沒傳參默認排序整個數組;
* partitionIndex爲分組界限;
*/
var len = arr.length,
partitionIndex,
left = typeof left !== 'number' ? 0 : left,
right = typeof right !== 'number' ? len - 1 : right;
// 如果需要排序的起始索引小於終止索引則執行排序;遞歸的終止條件;
if (left < right) {
// partition的返回值作爲partitionIndex來分隔數組;
// 索引partitionIndex左邊的元素均小於arr[partitionIndex];
// 右邊的元素均大於arr[partitionIndex];
partitionIndex = partition(arr, left, right);
// 數組中小於arr[partitionIndex]的部分(索引left到partitionIndex-1)再次使用quickSort排序;
quickSort(arr, left, partitionIndex - 1);
// 數組中大於arr[partitionIndex]的部分(索引partitionIndex+1到right)再次使用quickSort排序;
quickSort(arr, partitionIndex + 1, right);
}
// 遞歸執行直到不滿足left<right;返回本身;
return arr;
}
function partition(arr, left, right) {
/*
* 這部分是具體實現排序的部分;
* 將left賦值給pivot,作爲參照物,因爲left在最左邊,只需要從左到右比較一遍即可判斷整個數組;
* index索引是arr中待交換位置;
*/
var pivot = left,
index = pivot + 1;
// for循環從參照物arr[pivot]下一個元素arr[pivot+1]開始一直比較到子數組結束arr[right];
for (var i = index; i <= right; i++) {
// 循環中如果有任何小於參照物的,就將他交換到index的位置,然後index向右移動到下一個位置;
if (arr[i] < arr[pivot]) {
swap(arr, i, index);
index++;
}
}
/*
* 因爲每次都是交換完後index移動到下一個位置,所以在循環結束時,index仍爲待交換的位置;
* 此時索引pivot+1到index-1的元素都小於參照物arr[pivot];
*/
// 交換pivot和index-1索引的值之後index-1索引左邊全都是小於arr[index-1]的元素;
swap(arr, pivot, index - 1);
// 返回index-1作爲拆分子數組的分界線;
return index - 1;
}
/*
* 普通的交換,將a[i]和a[j]的數值交換;
*/
function swap(arr, i, j) {
var temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
let arr1 = [3,2,5,7,9,4,1,6,8]
let n1 = arr1.length
console.log(quickSort(arr1,0,n1-1));
插入排序
歸併排序
堆排序
希爾排序
基數排序
遞歸