Skip to content

Commit c768c3c

Browse files
committed
update comment for bubblesort
1 parent 3579023 commit c768c3c

9 files changed

Lines changed: 1555 additions & 1270 deletions

File tree

sorting/bubblesort/BubbleSort.java

Lines changed: 235 additions & 297 deletions
Large diffs are not rendered by default.

sorting/bubblesort/BubbleSort.js

Lines changed: 190 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,111 +1,245 @@
11
/**
2-
* Copyright https://github.com/microwind All rights reserved.
2+
* Copyright © https://github.com/microwind All rights reserved.
33
* @author: jarryli@gmail.com
44
* @version: 1.0
55
*/
6+
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
7+
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
8+
if (ar || !(i in from)) {
9+
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
10+
ar[i] = from[i];
11+
}
12+
}
13+
return to.concat(ar || Array.prototype.slice.call(from));
14+
};
15+
/**
16+
* 冒泡排序算法实现
17+
* 提供四种不同的实现方式,适合不同场景和性能需求
18+
*/
619
var BubbleSort = /** @class */ (function () {
7-
function BubbleSort(arr) {
8-
this.bubbleSort1(arr.slice(0));
9-
this.bubbleSort2(arr.slice(0));
10-
this.bubbleSort3(arr.slice(0));
20+
function BubbleSort() {
1121
}
1222
/**
13-
* 冒泡排序升序,将最大的元素冒泡到最后
14-
* 时间复杂度:O(n²),空间复杂度:O(1),稳定性:稳定
23+
* 冒泡排序基础版本 - 升序排列
24+
*
25+
* 算法原理:
26+
* 1. 从数组左端开始,依次比较相邻元素
27+
* 2. 若左元素大于右元素,则交换位置
28+
* 3. 继续向后比较,直到数组末尾
29+
* 4. 重复以上过程,每轮都会将当前未排序部分的最大值"冒泡"到最后
30+
*
31+
* 生活类比:就像水中的气泡,轻的气泡会自然上浮到水面
32+
* 在排序中,大的数字会逐渐"上浮"到数组的右侧
33+
*
34+
* 时间复杂度:O(n²) - 需要比较 n*(n-1)/2 次
35+
* 空间复杂度:O(1) - 只使用常数个额外变量
36+
* 稳定性:稳定 - 相等元素的相对位置不会改变
37+
*
38+
* @param arr 待排序的数字数组
1539
*/
1640
BubbleSort.prototype.bubbleSort1 = function (arr) {
1741
var _a;
1842
console.log('bubbleSort1 from left to right:');
1943
var len = arr.length;
44+
// 外循环:控制排序轮数,每轮确定一个最大值的位置
2045
for (var i = 0; i < len; i++) {
46+
// 内循环:控制比较次数,len-i-1 避免重复比较已排序部分
2147
for (var j = 0; j < len - i - 1; j++) {
22-
// 自左往右每两个进行比较,把大的交换到右侧
23-
// 逐轮冒出最大数,已经排好序的不要再比较
48+
// 关键点:自左往右每两个进行比较,把大的交换到右侧
2449
if (arr[j] > arr[j + 1]) {
25-
;
50+
// TS特点:解构赋值交换
2651
_a = [arr[j + 1], arr[j]], arr[j] = _a[0], arr[j + 1] = _a[1];
2752
}
28-
// console.log('i=' + i, 'j=' + j, arr)
2953
}
3054
}
31-
console.log(arr);
55+
this.printArray(arr, '基础升序版本排序结果');
3256
};
3357
/**
34-
* 冒泡排序降序,将最小的元素冒泡到最后
35-
* 从右向左比较,逐轮冒出最小数
36-
* 时间复杂度:O(n²),空间复杂度:O(1),稳定性:稳定
58+
* 冒泡排序基础版本 - 降序排列
59+
*
60+
* 算法思路:
61+
* 与升序版本相反,从数组末尾开始比较
62+
* 每轮将当前未排序部分的最小值"下沉"到左侧
63+
*
64+
* 时间复杂度:O(n²) - 需要比较 n*(n-1)/2 次
65+
* 空间复杂度:O(1) - 只使用常数个额外变量
66+
* 稳定性:稳定 - 相等元素的相对位置不会改变
67+
*
68+
* @param arr 待排序的数字数组
3769
*/
3870
BubbleSort.prototype.bubbleSort2 = function (arr) {
3971
var _a;
4072
console.log('bubbleSort2 from right to left:');
4173
var len = arr.length;
74+
// 外循环:控制排序轮数,每轮确定一个最小值的位置
4275
for (var i = 0; i < len; i++) {
76+
// 内循环:从右向左比较,j > i 避免重复比较已排序部分
4377
for (var j = len - 1; j > i; j--) {
44-
// 自右往左每两个进行比较,把小的交换到右侧
45-
// 逐轮冒出最小数,已经排好序的不要再比较
78+
// 关键点:自右往左每两个进行比较,把小的交换到右侧
4679
if (arr[j - 1] < arr[j]) {
47-
;
80+
// TS特点:解构赋值交换
4881
_a = [arr[j], arr[j - 1]], arr[j - 1] = _a[0], arr[j] = _a[1];
4982
}
50-
// console.log('i=' + i, 'j=' + j, arr)
5183
}
5284
}
53-
console.log(arr);
85+
this.printArray(arr, '基础降序版本排序结果');
5486
};
5587
/**
56-
* 冒泡排序升序,增加交换标志优化
57-
* 当某一轮无交换时提前终止,针对有序情况优化
88+
* 冒泡排序优化版本
89+
*
90+
* 优化思路:
91+
* 增加一个标志位,记录某一轮是否发生了元素交换
92+
* 如果某一轮没有发生任何交换,说明数组已经完全有序
93+
* 此时可以提前终止排序过程,避免不必要的比较
94+
*
95+
* 优化效果:
96+
* - 对于完全有序的数组:时间复杂度从 O(n²) 优化到 O(n)
97+
* - 对于部分有序的数组:也会有明显的性能提升
98+
* - 对于完全逆序的数组:性能与基础版本相同
99+
*
58100
* 时间复杂度:最好O(n),最坏O(n²),空间复杂度:O(1)
101+
* 稳定性:稳定 - 相等元素的相对位置不会改变
102+
*
103+
* @param arr 待排序的数字数组
59104
*/
60105
BubbleSort.prototype.bubbleSort3 = function (arr) {
61106
var _a;
62107
console.log('bubbleSort3 add flag:');
63-
// 增加一个标志,如果某一轮没有进行过任何的交换
64-
// 则说明当前数组已排好序,则不必继续后面的遍历
108+
// 优化点:增加一个标志,如果某一轮没有进行过任何的交换
109+
// 则说明当前数组已排好序,则不必继续后面的遍历
65110
var len = arr.length;
66111
var flag = true;
112+
// 外循环:增加 flag 条件,当数组已有序时提前终止
67113
for (var i = 0; i < len && flag === true; i++) {
68-
flag = false;
69-
// console.warn('no. ' + i)
114+
flag = false; // 每轮开始时重置标志
115+
// 内循环:控制比较次数,len-i-1 避免重复比较已排序部分
70116
for (var j = 0; j < len - i - 1; j++) {
71-
// 自左往右每两个进行比较,把大的交换到右侧
72-
// 逐轮冒出最大数,已经排好序的不要再比较
117+
// 关键点:自左往右每两个进行比较,把大的交换到右侧
73118
if (arr[j] > arr[j + 1]) {
74-
flag = true;
119+
flag = true; // 发生交换,设置标志
120+
// TS特点:解构赋值交换
75121
_a = [arr[j + 1], arr[j]], arr[j] = _a[0], arr[j + 1] = _a[1];
76122
}
77-
// console.log('i=' + i, 'j=' + j, arr)
78123
}
79124
}
80-
console.log(arr);
125+
this.printArray(arr, '优化版本排序结果');
126+
};
127+
/**
128+
* 插入冒泡排序法,分为左右两个序列,左侧为已排序,将待排项与左侧逐个对比并交换位置
129+
*
130+
* 算法思路:
131+
* 将数组分为两部分:左侧已排序区域,右侧待排序区域
132+
* 每次从待排序区域取出第一个元素,插入到已排序区域的正确位置
133+
*
134+
* 这种方法结合了插入排序的思想,在某些情况下性能更好
135+
*
136+
* 时间复杂度:O(n²),空间复杂度:O(1)
137+
* 稳定性:稳定 - 相等元素的相对位置不会改变
138+
*
139+
* @param arr 待排序的数字数组
140+
*/
141+
BubbleSort.prototype.bubbleSort4 = function (arr) {
142+
var _a;
143+
console.log('bubbleSort4:');
144+
var len = arr.length;
145+
// 外循环:控制排序轮数,i 从 1 开始,因为第 0 个元素默认为已排序
146+
for (var i = 1; i < len; i++) {
147+
// 内循环:在已排序区域中查找插入位置
148+
for (var j = 0; j < i; j++) {
149+
// 关键点:如果待插入元素小于已排序区域的某个元素,则交换
150+
if (arr[j] > arr[i]) {
151+
// TS特点:解构赋值交换
152+
_a = [arr[j], arr[i]], arr[i] = _a[0], arr[j] = _a[1];
153+
}
154+
}
155+
}
156+
this.printArray(arr, '插入式版本排序结果');
157+
};
158+
/**
159+
* 打印数组内容的辅助函数
160+
* @param arr 要打印的数组
161+
* @param label 数组的标签说明
162+
*/
163+
BubbleSort.prototype.printArray = function (arr, label) {
164+
console.log("".concat(label, ": [").concat(arr.join(', '), "]"));
165+
};
166+
/**
167+
* 性能测试辅助函数
168+
* @param sortFunc 排序函数
169+
* @param arr 测试数组
170+
* @param name 测试名称
171+
*/
172+
BubbleSort.prototype.performanceTest = function (sortFunc, arr, name) {
173+
// 创建数组副本,避免修改原数组
174+
var testArr = __spreadArray([], arr, true);
175+
this.printArray(testArr, "".concat(name, "\u539F\u59CB\u6570\u7EC4"));
176+
// 开始计时
177+
console.time(name);
178+
sortFunc(testArr);
179+
console.timeEnd(name);
180+
this.printArray(testArr, "".concat(name, "\u6392\u5E8F\u7ED3\u679C"));
181+
console.log(''); // 空行分隔
182+
};
183+
/**
184+
* 主程序:算法演示和性能测试
185+
*/
186+
BubbleSort.prototype.run = function () {
187+
// 测试数据:包含重复元素和无序情况的典型数组
188+
var testData = [7, 11, 9, 10, 12, 13, 8];
189+
console.log('=== 冒泡排序算法演示 ===\n');
190+
// 测试1:基础升序版本
191+
this.performanceTest(this.bubbleSort1.bind(this), testData, '基础升序版本');
192+
// 测试2:基础降序版本
193+
this.performanceTest(this.bubbleSort2.bind(this), testData, '基础降序版本');
194+
// 测试3:优化版本
195+
this.performanceTest(this.bubbleSort3.bind(this), testData, '优化版本');
196+
// 测试4:插入式版本
197+
this.performanceTest(this.bubbleSort4.bind(this), testData, '插入式版本');
198+
console.log('=== 算法对比总结 ===');
199+
console.log('1. 基础版本:简单易懂,适合学习算法原理');
200+
console.log('2. 降序版本:展示算法的灵活性,可按需排序');
201+
console.log('3. 优化版本:通过标志位优化,适合实际应用');
202+
console.log('4. 插入式版本:结合其他排序思想,性能更稳定');
203+
console.log('\n建议:在实际项目中使用优化版本,在教学中使用基础版本');
81204
};
82205
return BubbleSort;
83206
}());
84-
;
85-
(function () {
86-
// test
87-
var arr = [7, 11, 9, 10, 12, 13, 8];
88-
console.time('bubbleSort');
89-
new BubbleSort(arr);
90-
console.timeEnd('bubbleSort');
91-
})();
92-
/*
93-
jarrys-MacBook-Pro:bubblesort jarry$ tsc BubbleSort.ts -t es2020
94-
jarrys-MacBook-Pro:bubblesort jarry$ node BubbleSort.js
207+
// 执行测试
208+
var sorter = new BubbleSort();
209+
sorter.run();
210+
/* 打印结果
211+
jarry@Mac bubblesort % ts-node BubbleSort.ts
212+
=== 冒泡排序算法演示 ===
213+
214+
基础升序版本原始数组: [7, 11, 9, 10, 12, 13, 8]
95215
bubbleSort1 from left to right:
96-
[
97-
7, 8, 9, 10,
98-
11, 12, 13
99-
]
216+
基础升序版本排序结果: [7, 8, 9, 10, 11, 12, 13]
217+
基础升序版本: 0.055ms
218+
基础升序版本排序结果: [7, 8, 9, 10, 11, 12, 13]
219+
220+
基础降序版本原始数组: [7, 11, 9, 10, 12, 13, 8]
100221
bubbleSort2 from right to left:
101-
[
102-
13, 12, 11, 10,
103-
9, 8, 7
104-
]
222+
基础降序版本排序结果: [13, 12, 11, 10, 9, 8, 7]
223+
基础降序版本: 0.064ms
224+
基础降序版本排序结果: [13, 12, 11, 10, 9, 8, 7]
225+
226+
优化版本原始数组: [7, 11, 9, 10, 12, 13, 8]
105227
bubbleSort3 add flag:
106-
[
107-
7, 8, 9, 10,
108-
11, 12, 13
109-
]
110-
bubbleSort: 8.312ms
111-
*/
228+
优化版本排序结果: [7, 8, 9, 10, 11, 12, 13]
229+
优化版本: 0.03ms
230+
优化版本排序结果: [7, 8, 9, 10, 11, 12, 13]
231+
232+
插入式版本原始数组: [7, 11, 9, 10, 12, 13, 8]
233+
bubbleSort4:
234+
插入式版本排序结果: [7, 8, 9, 10, 11, 12, 13]
235+
插入式版本: 0.025ms
236+
插入式版本排序结果: [7, 8, 9, 10, 11, 12, 13]
237+
238+
=== 算法对比总结 ===
239+
1. 基础版本:简单易懂,适合学习算法原理
240+
2. 降序版本:展示算法的灵活性,可按需排序
241+
3. 优化版本:通过标志位优化,适合实际应用
242+
4. 插入式版本:结合其他排序思想,性能更稳定
243+
244+
建议:在实际项目中使用优化版本,在教学中使用基础版本
245+
*/

0 commit comments

Comments
 (0)