1 )普通版
// version 1
function gnomeSort() {
const len: number = this.length;
for(let i: number = 1; i < len;) {
// 短路保护 贪心比较当前两个
if(i < 1 || this[i-1] <= this[i]) {
++ i; // 正确,则递增,这里有个性能的问题,当一轮比较结束,还需要自增移动到之前已经比较好的位置,重复性太大
} else {
// 逆序,则交换
[this[i-1], this[i]] = [this[i], this[i-1]]
-- i; // i回退进行比较,直到当前所有都有序
}
}
}
const arr: number[] = [5,4,3,2,1];
arr.gnomeSort();
console.log(arr); // [1, 2, 3, 4, 5]
2 )优化版
// version 2 改进了不需要重复比较已经有序的元素了, 也就是说不需要自己再往回走了
function gnomeSort() {
const len: number = this.length;
// k是当前比较的位置, 从1 ~ len-1
for(let k: number = 1; k < len; ++ k) {
// 通过i进行内部比较排序, 逆序,则交换
for(let i: number = k; i > 0 && this[i-1] > this[i]; --i) {
[this[i-1], this[i]] = [this[i], this[i-1]]
}
}
}
const arr: number[] = [5,4,3,2,1];
arr.gnomeSort();
console.log(arr); // [1, 2, 3, 4, 5]