前言
2022了 算法学习,一个多月了,收获还是有的,从刚开始的排序,到后来的链表,在到后来的二叉树,动态规划目前还是整的云里雾里的,起初只有冒泡能磕磕巴巴写出来,现在基数,冒泡,选择,插入,桶虽然也还是磕磕巴巴的,但是大概知道了是怎么一回事,前路未知,仍需努力,加油。未来也许就像这湖面上的远处的群山只见其形不见其本来面目,也许正是因为看不清晰所以才有那么吸引人吧。
原本觉得这个标题有点欠妥,后来觉得放在一起吧,毕竟很少有人能不被自身的心绪影响,索性就把2022的开头也记录在这里吧,也许是自己懒散惯了,也许是还未得其法门,学东西总是学不到精髓,也许是太心急了,很多时候我们追求快,追求极致,然后瞬时记忆,一闪而过,等到回过头来,在回首原来,我只是见过而并未掌握,不知道你们有没有过这种感觉,某个物件或者此词句在或者某个人,你脑袋里有大量的词来形容最后不知道从哪里开始,还有的时,明明不久之前见过可是就是说不出名字那张面容却清晰的很。见了个故人,听了他们的故事,好多话想说到了嘴边又不知该说什么,我们这一生究竟是为了什么?追求的到底是什么?为了梦想感觉是最扯淡的,彷佛除了高中毕业之后很少有人才谈这个词汇,朋友故人见面也从偷逃一节课去操场远远的看喜欢的那个女孩一眼,在食堂师傅那多吃一勺肉,逐渐到怎么还单身,怎么还没挣到钱,这个月花呗还上了没。你还有梦想吗。大家似乎都已遗忘。
可是回过头来,依然有看到现在“路飞”的小伙伴在精进自己这条道路上花功夫,磨砺己身,想想真的是不容易。有些事我们总以为很容易,可是做起来也很容易,但是坚持下来却不是那么容易的。
最后奉上一张我自认为拍的不错的图大家猜猜看这是那
冒泡
图示
function srot(arr) {
for(let i = 0; i < arr.length - 1; i++) {
// 边界减少
for(let j = 0; j < arr.length - i - 1; j++) {
// 如果当前值比后边的值大则交换位置
if(arr[j] > arr[j+1]){
let temp = arr[j+1];
arr[j+1] = arr[j];
arr[j] = temp;
}
}
}
return arr;
}
选择
图示
function sort(arr){
let minIndex; // 找到最小值
// 结束条件为啥是arr.length 因为 数组是从下标为0开始,所以实际长度为长度-1;
for(let i = 0; i < arr.length - 1; i++) {
minIndex = i;
// 第一个元素给了minIndex 所以 此处 为 i 的下一个元素
for(let j = i + 1; j < arr.length - 1; j++ ) {
if(arr[j] < arr[minIndex]){
// 记录最小的下标
minIndex = j;
}
}
let temp = arr[minIndex];
arr[minIndex] = arr[i];
arr[i] = temp;
}
return arr;
}
插入
图示
function insertionSort(arr){
let preIndex;
let current;
for(let i = 1 ; i < arr.length; i++){
preIndex = i - 1; // 记录游标位置
current = arr[i]; // 记录当前比较的值
// 此处条件有些难
while(preIndex >= 0 && arr[preIndex] > current){
// 使用游标交换
arr[preIndex+1] = arr[preIndex];
// 直到比较完
preIndex--;
}
arr[preIndex+1] = current;
}
return arr;
}
计数
图示
function sumSort(arr){
// 数组从0开始 但是我们0也要作为计数位置故此留出位置
let len = arr.length+1;
let newArr = [];
// 生成计数位置
for(let i = 0 ; i < len; i++){
// 初始化计数位置上的次数为0
let obj = { key: i, count: 0}
for(let j = 0 ; j < len - 1; j++) {
// 每个计数位置上出现一次 累加一次
if(arr[j] == i){
obj.count ++;
}
}
newArr.push(obj);
}
let result = [];
newArr.map((item) => {
// 如果累加次数不为零那么说明有数值需要排序
if(item.count) {
// 出现一次推入一次
for(let i = 0; i < item.count; i++) {
result.push(item.key)
}
}
})
return result;
}
二路归并排序
图解
function halfSort(arr) {
if (arr.length < 2) {
return arr;
}
let mind = Math.floor(arr.length / 2);
let left = arr.slice(0, mind);
let right = arr.slice(mind, arr.length);
return merge(halfSort(left), halfSort(right));
}
function merge(left, right) {
let arr = [];
while(left.length && right.length) {
if (left[0] < right[0]) {
arr.push(left.shift());
} else {
arr.push(right.shift());
}
}
// 左边和右边的长度如果不一致,那么直接把剩余的数据放到最后(因为已经是上一次排序后的)
return arr.concat(left,right);
}
桶排序
function buckSort(arr) {
// 找到最大最小生成桶
let max = arr[0];
let min = arr[0];
for(let i = 0; i < arr.length; i++) {
if(max < arr[i]){
max = arr[i];
}else if(min > arr[i]) {
min = arr[i];
}
}
let buckNum = parseInt((max - min) / arr.length) + 1;
// 生成排序同
let buckArr = new Array(buckNum);
for(let i = 0; i < buckNum; i++) {
buckArr[i] = new Array();
}
// 排序桶放入数据
for(let i of arr) {
let num = parseInt((i - min) / arr.length);
buckArr[num].push(i)
}
// 桶内排序
for(let i of buckArr) {
i.sort();
}
let arrIndex = 0;
for (let i = 0; i < buckArr.length; i++) {
for (let j = 0; j < buckArr[i].length; j++) {
arr[arrIndex++] = buckArr[i][j]
}
}
return arr
}