- 浏览: 165552 次
- 性别:
- 来自: 广州
博客专栏
-
TCP/IP详解卷一>阅读...
浏览量:12266
文章分类
最新评论
-
master11:
你好,博主看完你的解释,好厉害啊!!佩服。如果想运行看一下效果 ...
数独人工解法的一些技巧及其python实现 -
evasiu:
<div class="quote_title ...
数独人工解法的一些技巧及其python实现 -
chenxun1012033254:
lz这么辛苦我也是醉了作为一名oier我说有一个算法叫做dan ...
数独人工解法的一些技巧及其python实现 -
xuyfiei:
lz很厉害,现在该是毕业了吧
恨毕业--读研一年总结 -
nphoenix:
呵呵 肯踏實的學東西已經很不錯了。畢業了工作之後,你就會發現個 ...
恨毕业--读研一年总结
年前实现了一个2-3树,后来就玩儿去了,再后来看书去了,所以就耽搁了。基本上网上找不到什么2-3树的实现,大概是因为这东西基本真正被用过吧。基于它的思想而发明的B树,B+树才是真正的大头,不过2-3树的模型比较简单,对我们理解B树和B+树的实现有很大的帮助,所以最终我还是通过自己的努力,实现了一个2-3树。
下面是2-3树的基本介绍:
2-3树不是一种二叉树,但他的形状满足以下性质:
(1)一个节点包含一个或两个键值
(2)每个内部节点有两个子节点(如果它有一个键值)或三个子节点(如果它有两个键值)
(3)所有叶节点都在树结构的同一层,因此树的高度总是平衡的。
对于每个结点, 左子树中所有后继结点的值都小于第一个键的值, 而其中间子树中所有结点的值都大于或等于第一个键的值。如果结点有右子树的话( 相应地, 结点存储两个键值) , 那么其中间子树中所有后继结点的值都小于第二个键的值, 而其右子树中所有后继结点的值都大于或等于第二个键的值。同时,同一层的键值从左到右增大。
2-3树的查找方法与二分查找树相似,从根节点出发,如果在根节点找到查找值则查找成功返回,否则根据节点键的规则递归地查找下去,直到找到或返回失败。
在2-3树中插入新值时并不为其开辟一个新的叶子节点来存储,也就是说,2-3树不是向下生长的。插入算法首先找到一个合适的叶子节点来存放该值,使树的性质不被破坏。如果该叶子节点只包含一个值(每个节点都最多有两个值),则简单将该值放入叶子节点即可。如果叶子结点本身已经包含两个值了,则需要为前加入的叶子开辟新的空间。设节点L为插入节点,但是已经满了,也就是,这个节点因为包含了三个值,所以必须进行分裂,设新分裂出来的节点为L’,则L将存储这三个值中最小的那个值,而L’则存储这三个值中最大的那个。处于中间的值将得到提升,作为插入值晋升到父节点去。如果父节点只包含一个键值,该值直接放入节点即可,否则,同样的“分裂-晋升”过程将在该父节点进行,一直递归到根节点为止。2-3的插入实现中利用了一个函数splitNode,它接收被插入节点的指针和插入的数据,并将指向L'指针和被往上传的值通过引用传回来。当插入结点已满时便启用这个函数。
从2-3树删除一个节点,有三种可能情况需要考虑:最简单的情况是,如果删除的值存储在有两个键值的节点上,直接删除该值并不影响树的性质与结构。如果被删除的值所在的节点只有它一个键值,被删除后该节点将为空,因此通过向兄弟节点借一个记录,并修改父节点来解决。如果兄弟节点不够借,则需要合并相邻节点,并影响双亲,可能导致树的高度下降。如果被删除的值是树的内部节点,则将被删除记录用右边子树中的最小键值代替,然后再根据第一、二种情况将该值删除。第一种情况的实现相当简单,只需要考虑如果删除的是左键值,那么要把右键值移过来而已。被借的情况由borrowLeft和borrowRight来实现,合并的情况由mergeLeft和mergeRight来实现。具体代码如下:
//TTTree.h #ifndef TTTREE_H #define TTTREE_H #include<iostream> #include<queue> using namespace std; template<class Elem, class Key, class KEComp, class EEComp> class TTTree : public Tree<Elem, Key, KEComp, EEComp>{ protected: using Tree<Elem, Key, KEComp, EEComp>::count; struct TTNode{ Elem elems[2]; TTNode* ptrs[3]; TTNode(){ ptrs[0] = ptrs[1] = ptrs[2] = 0; } TTNode( Elem empty ){ ptrs[0] = ptrs[1] = ptrs[2] = 0; elems[0] = elems[1] = empty; } }; TTNode* root; Elem EMPTY; int height; void splitNode( TTNode* subroot, TTNode* inPtr, Elem inVal, TTNode*& retPtr, Elem& retVal ); bool insertHelp( TTNode* subroot, const Elem& e, TTNode*& retPtr, Elem& retVal ); void clear( TTNode* subroot ); void borrowLeft( TTNode* subroot, int ptrIndex ); void borrowRight( TTNode* subroot, int ptrIndex ); void mergeLeft( TTNode* subroot, int ptrIndex ); void mergeRight( TTNode* subroot, int ptrIndex ); void removeHelp( TTNode* subroot, const Key& k, Elem& e ); public: TTTree( const Elem& em ){ root = 0; height = 0; EMPTY = em; } ~TTTree(){ clear( root ); } bool insert( const Elem& e); bool remove( const Key& k ,Elem& e ); bool search( const Key& k, Elem& e ); void print() const; }; #include "TTTree.cpp" #endif
//TTTree.cpp template<class Elem, class Key, class KEComp, class EEComp> bool TTTree<Elem, Key, KEComp, EEComp>:: search( const Key& k, Elem& e ){ TTNode* current=root; while( current != 0 ){ if( KEComp::eq( k, current->elems[0] ) ){ e = current->elems[0]; return true; } if( !EEComp::eq( EMPTY, current->elems[1] ) && KEComp::eq( k, current->elems[1] ) ){ e = current->elems[1]; return true; } if( KEComp::lt( k, current->elems[0] ) ) current = current->ptrs[0]; else if( EEComp::eq( EMPTY, current->elems[1] ) || KEComp::lt( k, current->elems[1] ) ) current = current->ptrs[1]; else current = current->ptrs[2]; } return false; } template<class Elem, class Key, class KEComp, class EEComp> void TTTree<Elem, Key, KEComp, EEComp>:: clear( TTNode* subroot ){ if( subroot == 0 ) return; for( int i=0; i<3; i++ ) clear( subroot->ptrs[i] ); delete subroot; } template<class Elem, class Key, class KEComp, class EEComp> void TTTree<Elem, Key, KEComp, EEComp>:: print() const{ if( root == 0 ){ cout<<"empty tree"<<endl; return; } queue<TTNode*> nodeQueue; nodeQueue.push(root); TTNode* current; int h = height; int intent=1; string BLANK=" "; for( int i=1; i<height; i++ ) intent *= 3; int num = 1; while( h>0 && !nodeQueue.empty() ){ for( int i=0; i<num; i++ ){ current = nodeQueue.front(); nodeQueue.pop(); if( current != 0 ){ for( int j=0; j<3; j++ ) nodeQueue.push( current->ptrs[j] ); for( int j=0; j<intent/2; j++ ) cout<<BLANK; cout<<"|"<<current->elems[0]<<"|"; if( EEComp::eq( EMPTY, current->elems[1] ) ) cout<<"__|"; else cout<<current->elems[1]<<"|"; for( int j=0; j<intent/2; j++ ) cout<<BLANK; }else{ for( int j=0; j<3; j++ ) nodeQueue.push( 0 ); for( int j=0; j<intent; j++ ) cout<<BLANK; } } cout<<endl; intent /= 3; num *= 3; h--; } } template<class Elem, class Key, class KEComp, class EEComp> void TTTree<Elem, Key, KEComp, EEComp>:: splitNode( TTNode* subroot, TTNode* inPtr, Elem inVal, TTNode*& retPtr, Elem& retVal ){ retPtr = new TTNode( EMPTY ); if( EEComp::lt( inVal, subroot->elems[0] ) ){ retVal = subroot->elems[0]; subroot->elems[0] = inVal; retPtr->elems[0] = subroot->elems[1]; retPtr->ptrs[0] = subroot->ptrs[1]; retPtr->ptrs[1] = subroot->ptrs[2]; subroot->ptrs[1] = inPtr; }else{ if( EEComp::lt( inVal, subroot->elems[1] ) ){ retVal = inVal; retPtr->elems[0] = subroot->elems[1]; retPtr->ptrs[0] = inPtr; retPtr->ptrs[1] = subroot->ptrs[2]; }else{ retVal = subroot->elems[1]; retPtr->elems[0]=inVal; retPtr->ptrs[0] = subroot->ptrs[2]; retPtr->ptrs[1] = inPtr; } } subroot->ptrs[2] = 0; subroot->elems[1] = EMPTY; } template<class Elem, class Key, class KEComp, class EEComp> bool TTTree<Elem, Key, KEComp, EEComp>:: insertHelp( TTNode* subroot, const Elem& e, TTNode*& retPtr, Elem& retVal ){ Elem tempRetVal; TTNode* tempRetPtr=0; if( subroot->ptrs[0] == 0 ){ //leaf if( EEComp::eq( EMPTY, subroot->elems[1] ) ){ if( EEComp::lt( e, subroot->elems[0] ) ){ subroot->elems[1] = subroot->elems[0]; subroot->elems[0] = e; }else subroot->elems[1] = e; }else splitNode( subroot, 0, e, retPtr, retVal ); }else if( EEComp::lt( e, subroot->elems[0] ) ) insertHelp( subroot->ptrs[0], e, tempRetPtr, tempRetVal ); else if( EEComp::eq( EMPTY, subroot->elems[1] ) || EEComp::lt( e, subroot->elems[1] ) ) insertHelp( subroot->ptrs[1], e, tempRetPtr, tempRetVal ); else insertHelp( subroot->ptrs[2], e, tempRetPtr, tempRetVal ); if( tempRetPtr != 0 ){ if( EEComp::eq( EMPTY, subroot->elems[1] ) ){ if( EEComp::lt( tempRetVal, subroot->elems[0] ) ){ subroot->elems[1] = subroot->elems[0]; subroot->elems[0] = tempRetVal; subroot->ptrs[2] = subroot->ptrs[1]; subroot->ptrs[1] = tempRetPtr; }else{ subroot->elems[1] = tempRetVal; subroot->ptrs[2] = tempRetPtr; } }else splitNode( subroot, tempRetPtr, tempRetVal, retPtr, retVal ); } return true; } template<class Elem, class Key, class KEComp, class EEComp> bool TTTree<Elem, Key, KEComp, EEComp>:: insert( const Elem& e ){ if( root == 0 ){ root = new TTNode( EMPTY ); root->elems[0] = e; height++; count++; return true; } Elem myRetVal; TTNode* myRetPtr = 0; if( insertHelp( root, e, myRetPtr, myRetVal ) ){ count++; if( myRetPtr != 0 ){ TTNode* temp = new TTNode(EMPTY); temp->elems[0] = myRetVal; temp->ptrs[0] = root; temp->ptrs[1] = myRetPtr; root = temp; height ++; } return true; } return false; } template<class Elem, class Key, class KEComp, class EEComp> void TTTree<Elem, Key, KEComp, EEComp>:: removeHelp( TTNode* subroot, const Key& k, Elem& e ){ if( subroot == 0 ){ e = EMPTY; return ; } e = EMPTY; Elem tempElem = EMPTY; int ptrIndex = -1; if( KEComp::eq( k, subroot->elems[0] ) ){ e = subroot->elems[0]; if( subroot->ptrs[0] == 0 ){ //leaf node if( !EEComp::eq( EMPTY, subroot->elems[1] ) ){ subroot->elems[0]=subroot->elems[1]; subroot->elems[1]= EMPTY; }else subroot->elems[0] = EMPTY; return ; }else{ //if not leaf node, find a leaf node to take place of it TTNode* replace=subroot->ptrs[1]; while( replace->ptrs[0] != 0 ) replace = replace->ptrs[0]; subroot->elems[0]=replace->elems[0]; ptrIndex = 1; removeHelp( subroot->ptrs[1], getKey(replace->elems[0]), tempElem ); tempElem = e; } }else if( !EEComp::eq( EMPTY, subroot->elems[1] ) && KEComp::eq( k, subroot->elems[1] ) ){ e = subroot->elems[1]; if( subroot->ptrs[0] == 0 ){ subroot->elems[1] = EMPTY; return; }else{ TTNode* replace=subroot->ptrs[2]; while( replace->ptrs[0] != 0 ) replace = replace->ptrs[0]; subroot->elems[1] = replace->elems[0]; ptrIndex = 2; removeHelp( subroot->ptrs[2], getKey( replace->elems[0] ), tempElem ); tempElem = e; } }else if( KEComp::lt( k, subroot->elems[0] ) ){ ptrIndex = 0; removeHelp( subroot->ptrs[0], k, tempElem ); }else if( EEComp::eq( EMPTY, subroot->elems[1] ) || KEComp::lt( k, subroot->elems[1] ) ){ ptrIndex = 1; removeHelp( subroot->ptrs[1], k, tempElem ); }else{ ptrIndex = 2; removeHelp( subroot->ptrs[2], k, tempElem ); } if( ptrIndex>=0 && !EEComp::eq( EMPTY, tempElem ) ){ e = tempElem; if( EEComp::eq( EMPTY, subroot->ptrs[ptrIndex]->elems[0]) ){ if( ptrIndex == 0 ){ if( !EEComp::eq( EMPTY, subroot->ptrs[1]->elems[1] ) ){ borrowRight( subroot, 0 ); }else if( EEComp::eq( EMPTY, subroot->elems[1] ) ){ mergeRight( subroot, 0 ); }else if( !EEComp::eq( EMPTY, subroot->ptrs[2]->elems[1] ) ){ borrowRight( subroot, 0 ); borrowRight( subroot, 1 ); }else{ borrowRight( subroot, 0 ); mergeRight( subroot, 1 ); } }else if( ptrIndex == 1 ){ if( !EEComp::eq( EMPTY, subroot->ptrs[0]->elems[1] ) ){ borrowLeft( subroot, 1 ); }else if( EEComp::eq( EMPTY, subroot->elems[1] ) ){ mergeLeft( subroot, 1 ); }else if( !EEComp::eq( EMPTY, subroot->ptrs[2]->elems[1] ) ){ borrowRight( subroot, 1 ); }else{ mergeRight( subroot, 1 ); } }else if( ptrIndex == 2 ){ if( !EEComp::eq( EMPTY, subroot->ptrs[1]->elems[1] ) ){ borrowLeft( subroot, 2 ); }else if( !EEComp::eq( EMPTY, subroot->ptrs[0]->elems[1] ) ){ borrowLeft( subroot, 1 ); borrowLeft( subroot, 2 ); }else{ mergeLeft( subroot, 2 ); } } } } } template<class Elem, class Key, class KEComp, class EEComp> void TTTree<Elem, Key, KEComp, EEComp>:: borrowRight( TTNode* subroot, int ptrIndex ){ if( ptrIndex<0 || ptrIndex>1 ) return; subroot->ptrs[ptrIndex]->elems[0] = subroot->elems[ptrIndex]; subroot->elems[ptrIndex] = subroot->ptrs[ptrIndex+1]->elems[0]; subroot->ptrs[ptrIndex+1]->elems[0] = subroot->ptrs[ptrIndex+1]->elems[1]; subroot->ptrs[ptrIndex+1]->elems[1] = EMPTY; subroot->ptrs[ptrIndex]->ptrs[1] = subroot->ptrs[ptrIndex+1]->ptrs[0]; subroot->ptrs[ptrIndex+1]->ptrs[0] = subroot->ptrs[ptrIndex+1]->ptrs[1]; subroot->ptrs[ptrIndex+1]->ptrs[1] = subroot->ptrs[ptrIndex+1]->ptrs[2]; subroot->ptrs[ptrIndex+1]->ptrs[2] = 0; } template<class Elem, class Key, class KEComp, class EEComp> void TTTree<Elem, Key, KEComp, EEComp>:: borrowLeft( TTNode* subroot, int ptrIndex ){ if( ptrIndex>2 || ptrIndex<1 ) return; subroot->ptrs[ptrIndex]->elems[1] = subroot->ptrs[ptrIndex]->elems[0]; subroot->ptrs[ptrIndex]->elems[0] = subroot->elems[ptrIndex-1]; subroot->elems[ptrIndex-1] = subroot->ptrs[ptrIndex-1]->elems[1]; subroot->ptrs[ptrIndex-1]->elems[1] = EMPTY; subroot->ptrs[ptrIndex]->ptrs[1] = subroot->ptrs[ptrIndex]->ptrs[0]; subroot->ptrs[ptrIndex]->ptrs[0] = subroot->ptrs[ptrIndex-1]->ptrs[2]; subroot->ptrs[ptrIndex-1]->ptrs[2] = 0; } template<class Elem, class Key, class KEComp, class EEComp> void TTTree<Elem, Key, KEComp, EEComp>:: mergeRight( TTNode* subroot, int ptrIndex ){ if( ptrIndex<0 || ptrIndex>1 ) return; subroot->ptrs[ptrIndex]->elems[0] = subroot->elems[ptrIndex]; subroot->elems[ptrIndex] = EMPTY; subroot->ptrs[ptrIndex]->elems[1] = subroot->ptrs[ptrIndex+1]->elems[0]; subroot->ptrs[ptrIndex]->ptrs[1] = subroot->ptrs[ptrIndex+1]->ptrs[0]; subroot->ptrs[ptrIndex]->ptrs[2] = subroot->ptrs[ptrIndex+1]->ptrs[1]; delete subroot->ptrs[ptrIndex+1]; subroot->ptrs[ptrIndex+1] = 0; } template<class Elem, class Key, class KEComp, class EEComp> void TTTree<Elem, Key, KEComp, EEComp>:: mergeLeft( TTNode* subroot, int ptrIndex ){ if( ptrIndex<1 || ptrIndex>2 ) return; subroot->ptrs[ptrIndex-1]->elems[1] = subroot->elems[ptrIndex-1]; subroot->elems[ptrIndex-1] = EMPTY; subroot->ptrs[ptrIndex-1]->ptrs[2] = subroot->ptrs[ptrIndex]->ptrs[0]; delete subroot->ptrs[ptrIndex]; subroot->ptrs[ptrIndex] = 0; } template<class Elem, class Key, class KEComp, class EEComp> bool TTTree<Elem, Key, KEComp, EEComp>:: remove( const Key& k, Elem& e ){ e = EMPTY; removeHelp( root, k, e ); if( e == EMPTY ) return false; if( EEComp::eq( EMPTY, root->elems[0] ) ){ TTNode* temp = root; root = root->ptrs[0]; height --; } return true; }
发表评论
-
我对KM算法的理解
2012-12-26 15:47 25451一般对KM算法的描述, ... -
一个小题目(单词统计)
2012-08-14 23:12 1264今天休息的时候看到一个关于单词统计的小题目: 统计一段由字符 ... -
数独人工解法的一些技巧及其python实现
2012-06-13 16:31 6471这段日子实现了十几种 ... -
Eva'Sudoku-0.1新鲜出炉啦~~
2012-05-27 21:06 1275呵呵,经过将近一个星期的对pygame的了解与熟悉,我终于磕磕 ... -
产生数独迷题
2012-05-24 18:13 1881随着数独解题算法DLX的 ... -
解数独——dancing link X
2012-05-21 22:59 7868折腾了一个星期,发现 ... -
编程之美续
2012-04-06 15:37 1035看完编程之美后看很多题,都会发现原来只是里面一些题目的变种(也 ... -
编程之美
2012-04-02 16:54 1362前段日子又看了编程之美,后来闲着无聊学python去了,想着书 ... -
数据结构 -- 二叉树(BST, AVLTree, RBTree, SplayTree)
2012-01-17 21:31 2705在《基于树的索引结构介绍》(http://philoscien ... -
编程珠玑--关于查找(二分法、自组织链、哈希)
2011-12-31 19:36 2034查找是我们现实生活中 ... -
编程珠玑 -- 关于堆
2011-12-28 15:31 1097堆是这样一种数据结构,它首先是一棵二叉树,而且还是一棵完全二叉 ... -
编程珠玑 -- 关于排序
2011-12-27 20:12 897《编程珠玑》主要提到 ... -
图论--旅行商问题
2011-05-04 14:57 1404五一果然基本献给了数据压缩(除了两个晚上用于打球),看了小波的 ... -
图论--寻找欧拉回路
2011-04-27 21:05 1729首先介绍一下fleury算法。 大概描述是这样子的: (1 ... -
图论--中国邮递员问题
2011-04-27 20:25 13917中国邮递员问题就比较 ... -
图论--关键路径
2011-04-27 19:37 1782最近忙着做作业。主要是《代数与图论》的一些算法的实现,五一估计 ... -
C语言中的文件操作
2011-04-16 11:34 729常常觉得,我对很多东西都是要求会用就好,不求甚解。比如说每次一 ...
相关推荐
企业数字化转型暨数据仓库(数仓)建设方案.pptx
2024年中国LED切割灯行业研究报告
在当今快速发展的人工智能领域中,一款集成了机器学习、深度学习、神经网络、图神经网络、卷积网络及多层感知机可视化功能的画图工具脱颖而出,成为全球范围内最受欢迎和认可的工具之一。这款工具不仅仅是一个简单的绘图软件,它的设计初衷是为了让复杂的网络结构和算法直观化,从而帮助研究者、学者及开发人员更容易地理解和分享他们的工作。 最令人印象深刻的特色之一是它基于PPT的编辑能力,这允许用户在熟悉的PPT编辑环境中创建、编辑和展示复杂的网络结构。用户可以利用拖拉组件、调整尺寸、修改颜色和形状等功能,无缝地将科研成果或项目展示集成到演示文稿中,极大地提高了工作的效率和表现力。 该工具不仅支持广泛的网络结构和模型,还包含丰富的库和模块,让用户能够轻松自定义和扩展自己的模型。它的用户界面友好、直观,无论是机器学习的新手还是资深研究员,都能快速上手,将精力更多地集中在创新和研究上,而不是图形的绘制和编辑上。 此外,它强大的共享和合作功能,使得团队成员可以实时共享他们的成果,促进了知识的交流和项目的进展。这款工具不仅改善了人工智能领域内部的工作方式,也为更广泛的受众提供了学习和理解复杂算法的窗口。 总
2024年中国B型超声诊断设备行业研究报告
Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。
Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。
内容概要:通过带着读者手写简化版 ajax请求框架,了解网络请求核心原理。在手写ajax的过程中会摘取整体框架中的核心逻辑,简化代码实现过程,保留核心功能,例如:XMLHttpRequest、jsonp请求、作用域、资源处理等内容实现。 适用人群:具备一定编程基础,工作1-3年的大前端开发、网络安全的研发人员 适用场景:金融支付、设备识别、IP 限制、网络监控、技术测试 能学到什么:手写ajax请求、兼容jsonp请求、动态添加meta标签、动态获取本地ip、处理403网络请求报错。 阅读建议:可以在以下框架中使用:react、react-native、vue、javaScript、web、jquery框架。在webapp工程,获取终端ip 获取本地ip 获取本机ip地址,403报错解决方案。
Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。
Stm32学习笔记,超详细
halcon 3D图像重建。
Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。
虚拟网卡库,Python或者C都可以调用,虚拟网卡
IEC 60364-7-721-2017 低压电气装置.第7-721部分:特殊装置或场所的要求.房车和机动房车中的电气装置.pdf
BS 1363-1-2023 :13A插头、插座、适配器和连接装置第1部分:可重新布线和不可重新布线的13A保险丝插头规范.pdf
平安业研一体 BizDevOps—降本增效与业务价值最大化实践-龚明杰
大学生,数学建模,美国大学生数学建模竞赛,MCM/ICM,历年美赛特等奖O奖论文
Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。
大学生,数学建模,美国大学生数学建模竞赛,MCM/ICM,2023年美赛特等奖O奖论文
超低溫冷凍櫃 Revco RLE 系列、Forma 89000 系列、HERAfreeze HLE 系列、 Thermo Scientific TLE 系列 安裝和操作
Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。