摘要:前端必須要掌握常見的數據結構,學會這招,讓你對開發中的數據結構更加清晰一隊列像排隊一樣,隊列就是先進先出,排隊入場入隊列出隊列二棧像拿起堆放的柴火一樣,棧就是先進后出,離場時后進的人先出入棧出棧三鏈表鏈表讓我們刪除數據和新增數據更加方便指針
前端必須要掌握常見的數據結構,學會這招,讓你對開發中的數據結構更加清晰! 一.隊列
像排隊一樣,隊列就是先進先出,排隊入場!
class Queue {
constructor() {
this.arr = []
}
enqueue(element){ // 入隊列
this.arr.push(element)
}
dequeue(){ // 出隊列
return this.items.shift()
}
}
二.棧
像拿起堆放的柴火一樣,棧就是先進后出,離場時后進的人先出!
class Stack {
constructor(){
this.arr = [];
}
push(element){ // 入棧
this.arr.push(element);
}
pop() { // 出棧
return this.items.pop();
}
}
三.鏈表
鏈表讓我們刪除數據和新增數據更加方便!
head指針指向第一個存入的元素節點,每個節點都有next屬性指向一下一個元素節點,最后一個元素的指針指向null
創建一個節點,每個節點的結構非常簡單
class Node {
constructor(element){
this.element = element; // 每個節點保存的內容
this.next = null; // 保存的指針,指向下一個節點
}
}
構建鏈表
class LinkList {
constructor(){
this.head = null; // 表頭 默認指向第一個節點,沒有為null
this.length = 0;
}
append(element){
// 追加節點
const node = new Node(element);
if(this.head == null){
this.head = node; // 第一個節點就是表頭
}else{
let current = this.head;
// 從第一個節點查找到最后一個節點
while(current.next){
current = current.next;
}
current.next = node; // 找到最后一個節點添加next指向新增節點
}
this.length++; // 每增加一個長度
}
}
使用鏈表,不難看出鏈表的特點就是通過next來指向下一個節點(像鏈條一樣)
const ll = new LinkList();
ll.append(1);
ll.append(2);
console.log(ll); // head: Node { element: 1, next: Node { element: 2, next: null } }
實現鏈表的插入
insert(position,element){
// 插入的時候判斷插入的位置
if(position>=0 && position <=this.length){
const node = new Node(element); // 創建一個節點
if(position === 0){ // 如果位置是0
node.next = this.head; // 那么就讓當前節點變成頭
this.head = node;
}else{
let current = this.head; // 獲取頭節點查找位置
let previous = null;
let index = 0;
while(index++ < position){ // 查找到節點位置
previous = current;
current = current.next;
}
node.next = current; // 讓當前節點next是剛才找到的節點
previous.next = node; // 他的上一個節點的next是當前節點
}
this.length++;
}
}
實現鏈表的刪除
removeAt(position){
if(position > -1 && position < this.length){
if(position ==0){ // 如果是第一個直接改變指針
this.head = this.head.next
}else{
let index = 0;
let previous = null;
let current = this.head;
while(index++ < position){ // 找到要刪除的這一項,直接讓上一個指針指向下一個人
previous = current;
current = current.next
}
previous.next = current.next; // 上一個next直接指向下一個next
}
this.length--;
}
}
更新鏈表中的內容
update(position,element) {
if (position >= 0 && position < this.length) {
if (position === 0) {
// 根位置 直接更改跟的內容即可
this.head.element = element
}else{
let index = 0;
// 查找到要修改的項來更新
let current = this.head;
while(index++ < position){
current = current.next;
}
current.element = element;
}
}
}
四.集合
ES6已經為我們提供了Set的api,但是在某些時候(瀏覽器不支持的情況下),我們還是需要自己來實現Set的
class Set{
constructor(){
this.items = {};
}
has(value){ // 判斷
return this.items.hasOwnProperty(value);
}
add(value){ // 像集合中添加
if(!this.has(value)){
this.items[value] = value;
}
}
remove(value){ // 刪除集合中的某一項
if(this.has(value)){
delete this.items[value];
}
}
}
集合,常見的方法有:交集、并集、差集五.hash表
特點是查找速度快,但是存儲量需要手動擴展
class HashTable{
constructor(){
this.table = [];
}
calcuteHash(key){ // 通過put的key 計算hash戳,存到數組中
let hash = 0;
for(let s of key){
hash += s.charCodeAt();
}
return hash % 100; // 只能存放100個
}
get(key){ // 從hash表中取出值
let hash = this.calcuteHash(key);
return this.table[hash]
}
put(key,value){ // 像hash表中存入
let hash = this.calcuteHash(key);
this.table[hash] = value;
}
}
let hash = new HashTable();
hash.put("abc",1);
console.log(hash.get("abc"));
六.樹
叫做“樹”是因為它看起來像一棵倒掛的樹,也就是說它是根朝上,而葉朝下的。
前端最常考察的就是二叉樹!
二叉樹: 樹中的節點最多只能有兩個子節點
二叉查找樹:
若左子樹不空,則左子樹上所有節點的值均小于它的根節點的值
若右子樹不空,則右子樹上所有節點的值均大于它的根節點的值
class Node {
constructor(key){
this.key = key;
this.left = null; // 左樹
this.right = null;// 右樹
}
}
class BinarySearchTree{
constructor(){
this.root = null;
}
insert(key){
const newNode = new Node(key);
const insertNode = (node,newNode)=>{
// 看下是放在左邊還是右邊
if(newNode.key < node.key){ // left
if(node.left == null){
node.left = newNode;
}else{ // 如果節點已經有了那么繼續像當前節點插入
insertNode(node.left,newNode);
}
}else{ // right
if(node.right == null){
node.right = newNode;
}else{
insertNode(node.right,newNode);
}
}
}
if(!this.root){ // 如果根沒有值 那么他就是根
this.root = newNode;
}else{ // 插到某一側
insertNode(this.root,newNode)
}
}
}
let binaryTree = new BinarySearchTree();
binaryTree.insert(8);
binaryTree.insert(3);
binaryTree.insert(10);
七.圖
圖可以看成有關聯的樹,我們可以使用鄰接表來描述各個節點的關系
class Graph{
constructor(){
this.List = {};
}
addNode(v){
this.List[v] = [];
}
addRelation(v,w){
// 相互存儲關系
this.List[v].push(w);
this.List[w].push(v);
}
}
const graph = new Graph();
["A", "B", "C", "D", "E", "F", "G", "H", "I"].forEach(node => graph.addNode(node));
graph.addRelation("A", "B")
graph.addRelation("A", "C")
graph.addRelation("A", "D")
console.log(graph.List["A"]);
看到這里是不是對數據結構有了一定的認識啦!接下來就看大家的合理應用啦~
覺得本文對你有幫助嗎?請分享給更多人
關注「前端優選」加星標,提升前端技能
加我微信:webyouxuan
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://www.hztianpu.com/yun/116335.html
摘要:如果像本例中這樣的場景會遇到這樣一個問題,詳見鏈接當請求參數過長或為了安全,就需要用到下載。寫到這里自己都忍不住想錘自己,給自己挖坑不說,這樣來回請求下載,流量,真的是敗家。 這幾天一直在做遠程文件下載的事,現在總算有了解決,特來記錄一下踩過的坑和想揍自己的心 需求 應用場景是這樣的,底層邏輯數據請求接口是由Java寫的,也就是說原始文件存在Java服務端,返回時有加密措施 由于工作...
摘要:但是,你的連接數限制配置為允許單個連接數,單個連接數最大帶寬為。就降低單個連接數帶寬吧要知道大家誰沒事會用瀏覽器自帶下載器下載呢注本文只探討限速模塊在不同業務下的限速彩蛋偶爾發現,將連接數限制為迅雷不能高速下載了。 nginx 內置模塊限速怎么使用就不多說了,今天來說說連接數和單個連接數限速的事。 場景:A公司有100人,A公司只有一個公網IP,假設A公司可能有100個人同時在下載你的...
摘要:但是,你的連接數限制配置為允許單個連接數,單個連接數最大帶寬為。就降低單個連接數帶寬吧要知道大家誰沒事會用瀏覽器自帶下載器下載呢注本文只探討限速模塊在不同業務下的限速彩蛋偶爾發現,將連接數限制為迅雷不能高速下載了。 nginx 內置模塊限速怎么使用就不多說了,今天來說說連接數和單個連接數限速的事。 場景:A公司有100人,A公司只有一個公網IP,假設A公司可能有100個人同時在下載你的...
摘要:基本概念中有種簡單數據類型也稱為基本數據類型,存放在棧中和。在使用聲明變量但未對其加以初始化時,這個變量的值就是,例如類型是第二個只有一個值的數據類型,這個特殊的值是。類型阿拉伯數字的八進制十進制十六進制整數浮點數。 基本概念 ECMAScript 中有 5 種簡單數據類型(也稱為基本數據類型,存放在棧中):Undefined、Null、Boolean、Number 和String。還...
閱讀 1956·2023-04-25 14:33
閱讀 3534·2021-11-22 15:22
閱讀 3113·2021-09-30 09:48
閱讀 2990·2021-09-14 18:01
閱讀 1887·2019-08-30 15:55
閱讀 3192·2019-08-30 15:53
閱讀 2320·2019-08-30 15:44
閱讀 900·2019-08-30 10:58