>[warning]冒泡排序(最經典的算法)
----
> 相鄰比較, 多跑幾次
----
看圖說話

這里使用JavaScript代碼實現:
1. 先學會交換2個變量的值
~~~
let a = 10, b = 20;
let c = a;
a = b;
b = c;
console.log(a, b);
~~~
2. 遍歷數組, 交換相鄰2個位置元素的值
~~~
let arr = [2, 5, 8, 1, 3, 4, 10, 9];
for (let i = 0; i < arr.length - 1; i++){
let c = arr[i + 1];
arr[i + 1] = arr[i];
arr[i] = c;
}
console.log(arr);
// 注意遍歷時長度要-1, 當i到7時i+1超出數組下標了, 會動態導致arr.length變大, 導致死循環
~~~
3. 遍歷一個數組, 當i位置元素大于i+1位置元素, 再交換相鄰2個元素位置
~~~
let arr = [2, 5, 8, 1, 3, 4, 10, 9];
for (let i = 0; i < arr.length - 1; i++){
if (arr[i] > arr[i + 1]){
let c = arr[i + 1];
arr[i + 1] = arr[i];
arr[i] = c;
}
}
console.log(arr);
~~~
4. 我們只需要讓上面的for循環的代碼多執行幾次, 就可以排好整個數組呢?
~~~
let arr = [2, 5, 8, 1, 3, 4, 10, 9];
for (let h = 0; h < arr.length; h++) {
for (let i = 0; i < arr.length - 1; i++) {
if (arr[i] > arr[i + 1]) {
let c = arr[i + 1];
arr[i + 1] = arr[i];
arr[i] = c;
}
}
}
console.log(arr);
~~~
-----------
## 擴展1:
~~~
// 外層循環可以優化
// 最壞情況, 當h的值為7時, 其實這個時候數組已經排好序了, 沒有必要再執行了, 所以最外層-1
~~~
優化后代碼
~~~
let arr = [2, 5, 8, 1, 3, 4, 10, 9];
for (let h = 0; h < arr.length - 1; h++) {
for (let i = 0; i < arr.length - 1; i++) {
if (arr[i] > arr[i + 1]) {
let c = arr[i + 1];
arr[i + 1] = arr[i];
arr[i] = c;
}
}
}
console.log(arr);
~~~
-----
## 擴展2:
~~~
// 內層循環可以優化
/*
* h的值, 數組結果
* 0 [2, 5, 1, 3, 4, 8, 9, 10]
* 1 [2, 1, 3, 4, 5, 8, 9, 10]
* h為1時, 下角標為7的元素, 不必再參加下次比較了, 因為它已經是最大了, 所以內層循環不光-1 還要 -h
*/
~~~
優化后代碼:
~~~
let arr = [2, 5, 8, 1, 3, 4, 10, 9];
for (let h = 0; h < arr.length - 1; h++) {
for (let i = 0; i < arr.length - 1 - h; i++) {
if (arr[i] > arr[i + 1]) {
let c = arr[i + 1];
arr[i + 1] = arr[i];
arr[i] = c;
}
}
}
console.log(arr);
~~~
-----
## 擴展3:
~~~
// 上面的代碼可以優化, 思考, 每次for循環后數組最新的情況得知
/*
* h的值; 數組結果
* 0 [2, 5, 1, 3, 4, 8, 9, 10]
* 1 [2, 1, 3, 4, 5, 8, 9, 10]
* 2 [1, 2, 3, 4, 5, 8, 9, 10]
* */
// 我們發現執行3次就排好序了, 但是代碼會繼續執行完畢, 直到h大于8才停止. 所以
// 如果內層if, 沒發生過交換, 就讓最外層循環停下來吧
~~~
優化后代碼:
~~~
let arr = [2, 5, 8, 1, 3, 4, 10, 9];
let flag = true; // 標記發生沒發生過交換
for (let h = 0; h < arr.length - 1 && flag; h++) {
flag = false;
for (let i = 0; i < arr.length - 1 - h; i++) {
if (arr[i] > arr[i + 1]) {
let c = arr[i + 1];
arr[i + 1] = arr[i];
arr[i] = c;
flag = true; // 發生交換了, 因為if里執行了
}
}
}
~~~
- web前端
- CSS問題
- 布局
- 雙飛翼布局_flex方式
- 雙飛翼布局_margin方式
- 圣杯布局_flex方式
- 圣杯布局_margin方式
- 子元素居中問題
- 彈性布局
- 概念_
- 標準模式與混雜模式
- 各種FC
- line-height
- vertical-align
- CSS3新特性
- 效果
- div添加箭頭
- CSS繪制三角形
- JavaScript
- 兼容
- 事件相關
- 原理
- Ajax原理
- 繼承原理
- 原型鏈繼承
- 組合繼承
- 寄生組合繼承
- 數據綁定
- 1單向數據綁定m到c到v
- 2偽雙向數據綁定
- 3雙向數據綁定
- socket.io
- 運行時
- this指向
- 0.1+0.2問題
- 對象/數組-深拷貝&淺拷貝
- 事件循環
- typeof
- instanceof
- 概念
- 閉包
- 回調函數
- Promise
- 原生對象
- Attribute和property區別
- 防抖函數
- 節流函數
- 語言類型
- Vue
- Vue優缺點
- 仿Vue源碼
- 1數據綁定_Observe
- 2數據綁定_訂閱者&觀察者定義
- 3數據綁定_Vue類實現
- 4數據綁定_Vue訪問data更改
- 5DOM編譯_Compile_雙大括號模板講解
- 6DOM編譯_v-model講解
- 7DOM編譯_v-on:事件綁定講解
- 項目總結
- 使用Svg圖標
- vueCli環境_真機測試
- vueCli集成環信SDK
- 父子組件雙向綁定
- React
- React優缺點
- 我的組件庫
- Vue的組件庫
- 環信_聊天組件
- 面試題
- HTML_分類
- CSS_分類
- JavaScript_分類
- VueJS_分類
- ReactJS_分類
- AngularJS_分類
- 瀏覽器端
- 筆試題
- CSS
- 特殊布局
- JavaScript_
- 經典_宏任務_微任務
- 瀏覽器問題
- CORS
- web服務器
- Apache
- 開啟跨域
- Nginx
- 常用命令
- 正向代理
- 反向代理
- 負載均衡
- mac安裝Nginx
- 配置80端口
- 算法
- 冒泡排序
- 選擇排序
- 合并對象_排序
- 楊輝三角
- 紅黑樹
- 計算機基礎
- 網絡相關
- OSI七層模型
- http協議
- http工作原理
- https協議
- GET和POST區別
- hosts文件
- php相關
- session機制
- Linux
- 阿里云服務器
- linux使用Mysql
- 安裝mysql
- 導入.sql文件
- 遠程連接mysql
- linux使用xampp
- 安裝Xampp
- 配置web訪問
- 域名綁定服務器
- linux搭建git服務器_apache下
- 代碼管理
- 什么是git
- 命令行_使用git
- .gitignore文件講解
- 軟件
- VSCode的安裝
- 理財
- 基金
- 攝影