JS实现数据结构与算法

news/2025/1/9 5:34:19/

队列

1、普通队列

利用数组push和shif 就可以简单实现

 2、利用链表的方式实现队列 

class MyQueue {constructor(){this.head = nullthis.tail = nullthis.length = 0}add(value){let node = {value}if(this.length === 0){this.head = nodethis.tail = node}else{this.tail.next = nodethis.tail = node}this.length++}delete(){if(this.length <= 0) {return null}let value = nullif(this.length === 1){value = this.head.valuethis.head = null}else{value = this.head.valuethis.head = this.head.next}return valuethis.length--}
}// 功能测试
const queue = new MyQueue()
queue.add(100)
console.log('length1', queue.length) // 1
queue.add(200)
console.log('length2', queue.length) // 2
console.log('delete1', queue.delete()) // 100
queue.add(300)
console.log('length3', queue.length) // 2
console.log('delete2', queue.delete()) // 200
console.log('length4', queue.length) // 1
console.log('delete3', queue.delete()) // 300
console.log('length5', queue.length) // 0

 

 栈 

1、普通栈

2、用Js链表实现入栈和出栈 

class MyNode{//这个类似于一个替换值tconstructor(val){this.value = valthis.next = null}
}
class MyStack{constructor(){this.stack = null}add(val){const node = new MyNode(val)//首先将入栈的值给t.value里:{value:100,next:null}node.next = this.stack//其次将上一个入栈的值赋值给t.next//形成新入的值在最外层,{value:200,next:{value:100,next:null}}this.stack = node//最后将t的整体包裹了新入栈的数据的对象赋值给当前的内容console.log('this.next',this.stack);}delete(){const t = this.stack//当前栈已空,直接返回,t是 MyStack.stackif(t === null){return '当前栈已空'}else{//将内层的next的赋值给原本的值,实现出栈this.stack = t.nextreturn t.value}}
}
const stack = new MyStack()
stack.add(100)
stack.add(200)
console.log('delete',stack.delete());
console.log('delete',stack.delete());
console.log('delete',stack.delete());

3、用栈来翻转字符串,只能用push和pop两个API 

function onStack(val){let arr1 = []//入栈for(let i of val){arr1.push(i)}let arr2 = ''let popValue = null//出栈while(arr1.length){popValue = arr1.pop()arr2 += popValue}return arr2
}
console.log(onStack('12345'));

排序 

1、冒泡排序

2、选择排序 

3、快速排序

注意:快速排序的规则就是先找中间的数,比中间大的放在左边,小的放在右边,再去对两边的数进行同样的操作。

注意:循环一次是O(n),双层循环是O(n^2),二分查找O(logn),快速排序是O(n*logn)

function quickSort(arr) {if(arr.length <= 0){return arr}let midIndex = Math.floor(arr.length/2) let midValue = arr[midIndex]let left = []let right = []for(let i = 0; i < arr.length; i++){if(i !== midIndex){if(midValue > arr[i]){left.push(arr[i])}else{right.push(arr[i])}}}return [...quickSort(left),midValue,...quickSort(right)]}let arr = [12, 45, 78, 25, 12, 3, 45, 74, 1, 14, 85]console.log(quickSort(arr));

 

查找

1、二分查找

注意:二分查找首先是查找的内容是已排序

           时间复杂度是O(logn)

          需要找的数先去找数组中中间的值,去作对比,大于就往右边找,小于就往左边找。下一次继续这个操作。

          方法:递归或循环

          求中间元素的值mid,即:mid = left + (right - left) / 2 得到中间下标

function find(arr, x) {let left = 0let right = arr.length - 1let mid = 0while (left <= right) {mid = Math.floor(left + (right - left) / 2)if (arr[mid] === x) {return {type: true,position: mid}} else if (arr[mid] < x) {left = mid + 1} else {right = mid - 1}}return {type: false,position: null}
}let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]
let x = 3
console.log(find(arr, x));

 

1、树的优先遍历

 

 一、树的深度优先结果:ABCGDEFHL 

 

 

 注意:

  • 访问根节点;
  • 对根节点的children持续进行深度优先遍历(递归);
function dfs(root) {console.log(root.value)if(root.children){root.children.forEach(dfs)}
}
dfs(tree) // 这个tree就是前面定义的那个树

 

 二、广度优先遍历结果:ABECGDFHL

注意:广度优先遍历是,先遍历根节点,再同层从左到右遍历

 

注意:

  • 创建要给队列,把根节点入队;
  • 把队头出队并访问;
  • 把队头的children依次入队;
  • 重复执行2、3步,直到队列为空。
function deep(tree){let queue = []queue.push(tree)while(queue.length > 0){const node = queue.shift()console.log(node.value);if(node.children){node.children.forEach(val => {queue.push(val)})}}}

 

2、二叉树

 一、用JS对象表达树

let tree = {value:'A',left:{value:'B',left:{value:'C',left:null,right:{value:'G',left:null,right:null}},right:{value:'D',left:null,right:null}},right:{value:'E',left:{value:'F',left:{value:'H',left:null,right:null},right:{value:'L',left:null,right:null}},right:null}
}

3、二叉树的前、中、后序遍历

 

 1、前序遍历:中、左、右 

 

2、中序遍历:左、中、右  

 

 3、后序遍历:左、中、右

 


http://www.ppmy.cn/news/1211958.html

相关文章

GPT 学习法:复杂文献轻松的完美理解、在庞大的不确性中找到确定性

GPT 学习法&#xff1a;复杂文献轻松的完美理解、在庞大的不确性中找到确定性 复杂文献 - 基础理解GPT 理解法 - 举例子、归纳、逻辑链推导本质、图示、概念放大器GPT 分析法 - 二分、矩阵、公式、要素、过程 做复杂题&#xff1a;在庞大的不确性中找到确定性思维追踪&#xff…

Ocelot:.NET开源API网关提供路由管理、服务发现、鉴权限流等功能

随着微服务的兴起&#xff0c;API网关越来越常见。API网关是连接应用程序和用户之间的桥梁&#xff0c;就像一个交通指挥员&#xff0c;负责处理所有进出应用的数据和请求&#xff0c;确保安全、高效、有序地流通。 今天给大家推荐一个.NET开源API网关。 01 项目简介 Ocelot…

【蓝桥每日一题]-快速幂,倍增,滑动窗口(保姆级教程 篇1) #麦森数 #青蛙跳

之前是考试准备&#xff0c;所以有几天没更新&#xff0c;今天开始继续更新 目录 快速幂模板 题目&#xff1a;麦森数 思路&#xff1a; 题目&#xff1a;青蛙跳 思路&#xff1a; 快速幂模板 #include <bits/stdc.h> #define ll long long using namespa…

Blender--》点线面操作及其面操作的详解

接下来我会在three.js专栏中分享关于3D建模知识的文章&#xff0c;如果学习three朋友并且想了解和学习3D建模&#xff0c;欢迎关注本专栏&#xff0c;关于这款3D建模软件blender的安装&#xff0c;我在前面的文章已经讲解过了&#xff0c;如果不了解的朋友可以去考考古&#xf…

软件自动化测试平台

软件测试分类黑盒、白盒、功能、API、接口、压力测试和性能测试&#xff0c; 自动化测试平台是一种用于自动化执行软件测试过程的工具。 一、自动化测试平台-功能性 1. 接口自动化&#xff1a;对接软件的接口进行测试&#xff0c;验证接口的功能和性能。 2. Web 自动化&…

【ARM Coresight OpenOCD 系列 3 -- OpenOCD 常用命令与扫描链scan_chain】

文章目录 1.1 TAP Declaration1.1.1 扫描链 1.2 Autoprobing1.3 DAP declaration (ARMv6-M, ARMv7 and ARMv8 targets) 1.1 TAP Declaration 测试访问端口&#xff08;TAP&#xff09;是JTAG的核心。TAP扮演许多角色&#xff0c;包括&#xff1a; 调试目标&#xff1a;CPU TA…

docker下的nginx代理转发到tomcat

多次尝试失败原因&#xff0c;修改nginx配置文件以后&#xff0c;需要./nginx.sh -s reload 下&#xff0c;之前一直不转发&#xff0c;好像完全没有跳转的意思&#xff0c;后来查了多篇文档&#xff0c;最简单的方法如下 docker 安装 nginx 和tomcat就不多说了&#xff0c;可…

Rust5.1 Error Handling

Rust学习笔记 Rust编程语言入门教程课程笔记 参考教材: The Rust Programming Language (by Steve Klabnik and Carol Nichols, with contributions from the Rust Community) Lecture 9: Error Handling use std::error::Error; use std::io::ErrorKind; use std::fs::Fil…