摘要:切記,紅黑樹在旋轉(zhuǎn)和顏色變換的過(guò)程中,必須遵守紅黑樹的幾條規(guī)則。樹的外部存儲(chǔ)磁盤布局計(jì)算機(jī)中的機(jī)械磁盤是由磁頭和圓盤組成,每個(gè)圓盤上劃分為多個(gè)磁道,每個(gè)磁道又劃分為多個(gè)扇區(qū)。
術(shù)語(yǔ)
根
????樹最頂端的節(jié)點(diǎn)稱為“根”,一棵樹只有一個(gè)根
父節(jié)點(diǎn)
????每個(gè)節(jié)點(diǎn)(除了根)都恰好有一條邊向上連接到另外一個(gè)節(jié)點(diǎn),上面這個(gè)節(jié)點(diǎn)就稱為下面節(jié)點(diǎn)的“父節(jié)點(diǎn)”
子節(jié)點(diǎn)
????每個(gè)節(jié)點(diǎn)都可能有一條或者多條邊向下連接到其它節(jié)點(diǎn),下面的這些節(jié)點(diǎn)就稱為它的“子節(jié)點(diǎn)”
葉節(jié)點(diǎn)
????沒(méi)有子節(jié)點(diǎn)的節(jié)點(diǎn)稱為“葉子節(jié)點(diǎn)”或者簡(jiǎn)稱為“葉節(jié)點(diǎn)”
子樹
????每個(gè)節(jié)點(diǎn)可以作為“子樹”的根,它和它所有的子節(jié)點(diǎn)構(gòu)成了這棵樹的子樹
路徑
????設(shè)想順著連接節(jié)點(diǎn)的邊從一個(gè)節(jié)點(diǎn)走到另一個(gè)節(jié)點(diǎn),所經(jīng)過(guò)節(jié)點(diǎn)的順序排列就稱為“路徑”
????如果一棵樹中每個(gè)節(jié)點(diǎn)最多只能有兩個(gè)子節(jié)點(diǎn),這樣的樹就稱為“二叉樹”,二叉樹每個(gè)節(jié)點(diǎn)的兩個(gè)子節(jié)點(diǎn)稱為“左子節(jié)點(diǎn)”和“右子節(jié)點(diǎn)”。
????如果我們給二叉樹加一個(gè)額外的條件,就可以得到一種被稱作二叉搜索樹(binary search tree)的特殊二叉樹。二叉搜索樹要求:每個(gè)節(jié)點(diǎn)都不比它左子樹的任意元素小,而且不比它的右子樹的任意元素大。(如果我們假設(shè)樹中沒(méi)有重復(fù)的元素,那么上述要求可以寫成:每個(gè)節(jié)點(diǎn)比它左子樹的任意節(jié)點(diǎn)大,而且比它右子樹的任意節(jié)點(diǎn)小)
平衡二叉樹????平衡二叉樹(Balanced Binary Tree)具有以下性質(zhì):它是一棵空樹或它的左右兩個(gè)子樹的高度差的絕對(duì)值不超過(guò)1,并且左右兩個(gè)子樹都是一棵平衡二叉樹。
二叉搜索樹的查找過(guò)程????二叉搜索樹可以方便的實(shí)現(xiàn)搜索算法。在搜索元素x的時(shí)候,我們可以將x和根節(jié)點(diǎn)比較:
如果x等于根節(jié)點(diǎn),那么找到x,停止搜索 (終止條件)
如果x小于根節(jié)點(diǎn),那么搜索左子樹
如果x大于根節(jié)點(diǎn),那么搜索右子樹
????當(dāng)二叉搜索樹平衡時(shí)達(dá)到最高搜索效率,時(shí)間復(fù)雜度為O(logN);當(dāng)二叉搜索樹單調(diào)插入數(shù)據(jù)時(shí),搜索效率最低,此時(shí)二叉搜索樹相當(dāng)于鏈表,時(shí)間復(fù)雜度為O(N)
????二叉搜索樹的查找代碼如下(僅考慮數(shù)據(jù)不重復(fù)的情況):
public Node find(int key) { Node current = root; while (current.data != key) { if (key < current.data) { current = current.left; } else { current = current.right; } if (current == null) { return null; } } return current; }二叉搜索樹插入過(guò)程
????二叉搜索樹的插入相對(duì)簡(jiǎn)單,二叉查找樹的插入過(guò)程如下:
若當(dāng)前的二叉搜索樹為空,則插入的元素為根節(jié)點(diǎn)
若插入的元素值小于根節(jié)點(diǎn)值,則將元素插入到左子樹中
若插入的元素值不小于根節(jié)點(diǎn)值,則將元素插入到右子樹中
????二叉搜索樹的插入代碼如下(僅考慮數(shù)據(jù)不重復(fù)的情況):
public void insert(int key, double data) { Node newNode = new Node(); newNode.key = key; newNode.data = data; if (root == null) { root = newNode; } else { Node current = root; Node parent; while (true) { parent = current; if (key < current.key) { current = current.left; if (current == null) { parent.left = newNode; return; } } else { current = current.right; if (current == null) { parent.right = newNode; return; } } } } }二叉搜索樹刪除過(guò)程
????二叉搜索樹刪除過(guò)程也分為三種情況:
待刪除節(jié)點(diǎn)是葉節(jié)點(diǎn),此時(shí)只要?jiǎng)h除該節(jié)點(diǎn),并修改其父節(jié)點(diǎn)的指針指向null即可
待刪除節(jié)點(diǎn)只有一個(gè)子節(jié)點(diǎn),此時(shí)只要將父節(jié)點(diǎn)的指針指向該節(jié)點(diǎn)的子樹即可
待刪除節(jié)點(diǎn)有兩個(gè)子節(jié)點(diǎn),此時(shí)需要找到該節(jié)點(diǎn)的后繼節(jié)點(diǎn),用后繼節(jié)點(diǎn)來(lái)代替它
如何查找后繼節(jié)點(diǎn)????一個(gè)節(jié)點(diǎn)的后繼節(jié)點(diǎn)即所有比該節(jié)點(diǎn)大的節(jié)點(diǎn)集合中最小的那個(gè)節(jié)點(diǎn)。為此可以查找該節(jié)點(diǎn)的右子樹的最左節(jié)點(diǎn)即可,如圖:
????查找后繼節(jié)點(diǎn)代碼如下:
private Node getSuccessor(Node delNode) { Node successorParent = delNode; Node successor = delNode; Node current = delNode.right; while (current != null) { successorParent = successor; successor = current; current = current.left; } // 節(jié)點(diǎn)移位,參照/docs/二叉搜索樹后繼節(jié)點(diǎn) if (successor != delNode.right) { successorParent.left = successor.right; successor.right = delNode.right; } return successor; }
????待刪除節(jié)點(diǎn)有兩個(gè)子節(jié)點(diǎn)的刪除過(guò)程如圖:
????刪除節(jié)點(diǎn)的代碼如下:
public void delete(int key) { Node current = root; Node parent = root; boolean isLeftChild = true; while (current.data != key) { parent = current; if (key < current.data) { isLeftChild = true; current = current.left; } else { isLeftChild = false; current = current.right; } if (current == null) { // 未找到待刪除的節(jié)點(diǎn) return; } } // 沒(méi)有子節(jié)點(diǎn) if (current.left == null && current.right == null) { if (current == root) { root = null; } else if (isLeftChild) { parent.left = null; } else { parent.right = null; } } else if (current.right == null) { // 只有左節(jié)點(diǎn) if (current == root) { root = current.left; } else if (isLeftChild) { parent.left = current.left; } else { parent.right = current.left; } } else if (current.left == null) { if (current == root) { root = current.right; } else if (isLeftChild) { parent.left = current.right; } else { parent.right = current.right; } } else { // 兩個(gè)節(jié)點(diǎn) Node successor = getSuccessor(current); if (current == root) { root = successor; } else if (isLeftChild) { parent.left = successor; } else { parent.right = successor; } successor.left = current.left; } }紅黑樹
????紅黑樹(英語(yǔ):Red–black tree)是平衡二叉搜索樹的一種實(shí)現(xiàn)方式,是在計(jì)算機(jī)科學(xué)中用到的一種數(shù)據(jù)結(jié)構(gòu),典型的用途是實(shí)現(xiàn)關(guān)聯(lián)數(shù)組。
????紅黑樹必須滿足以下的規(guī)則:
每一個(gè)節(jié)點(diǎn)不是紅色就是黑色
根總是黑色的
如果節(jié)點(diǎn)是紅色的,則它的子節(jié)點(diǎn)必須是黑色的(反之倒不一定必須為真)
該樹是完美黑色平衡的,即任意空鏈接到根結(jié)點(diǎn)的路徑上的黑鏈接數(shù)量相同
如果一個(gè)黑色節(jié)點(diǎn)下面有一個(gè)紅色節(jié)點(diǎn)和一個(gè)黑色節(jié)點(diǎn),那么紅色節(jié)點(diǎn)只能是左節(jié)點(diǎn)
旋轉(zhuǎn)????旋轉(zhuǎn)又分為左旋和右旋。通常左旋操作用于將一個(gè)向右傾斜的紅色鏈接旋轉(zhuǎn)為向左鏈接。
????左旋如圖所示:
代碼如下:
private Node rotateLeft(Node node) { Node x = node.right; node.right = x.left; x.left = node; x.color = x.left.color; x.left.color = RED; return x; }
????右旋如圖所示:
代碼如下:
private Node rotateRight(Node node) { Node x = node.left; node.left = x.right; x.right = node; x.color = x.right.color; x.right.color = RED; return x; }顏色變換
????在插入數(shù)據(jù)過(guò)程中,遇到一個(gè)黑色節(jié)點(diǎn)下面帶有兩個(gè)紅色的子節(jié)點(diǎn)就要進(jìn)行顏色變換。顏色變換規(guī)則如下:兩個(gè)紅色子節(jié)點(diǎn)變?yōu)楹谏谏腹?jié)點(diǎn)通常變?yōu)榧t色,如果父節(jié)點(diǎn)是根節(jié)點(diǎn)的話,則父節(jié)點(diǎn)繼續(xù)保持為黑色。
代碼如下:
private void flipColors(Node node) { node.color = !node.color; node.left.color = !node.left.color; node.right.color = !node.right.color; }紅黑樹的插入過(guò)程
????紅黑樹在插入時(shí),跟二叉搜索樹的插入規(guī)則是一致的,唯一不同的是,紅黑樹要保持自身的平衡,而這可以通過(guò)旋轉(zhuǎn)和顏色變換做到。切記,紅黑樹在旋轉(zhuǎn)和顏色變換的過(guò)程中,必須遵守紅黑樹的幾條規(guī)則。
代碼如下:
public void insert(int key) { root = insert(root, key); // 根節(jié)點(diǎn)只能是黑色 root.color = BLACK; } private Node insert(Node node, int key) { if (node == null) { return new Node(key, RED); } if (key < node.key) { node.left = insert(node.left, key); } else if (key > node.key) { node.right = insert(node.right, key); } else { node.key = key; } // 如果一個(gè)黑色節(jié)點(diǎn)下面的兩個(gè)節(jié)點(diǎn)一個(gè)黑色,一個(gè)紅色,則紅色節(jié)點(diǎn)只能是左節(jié)點(diǎn) if (isRed(node.right) && !isRed(node.left)) { node = rotateLeft(node); } // 紅色節(jié)點(diǎn)下面不能有紅色節(jié)點(diǎn) if (isRed(node.left) && isRed(node.left.left)) { node = rotateRight(node); } // 當(dāng)一個(gè)黑色節(jié)點(diǎn)下有兩個(gè)紅色節(jié)點(diǎn),則要進(jìn)行顏色變換 if (isRed(node.left) && isRed(node.right)) { flipColors(node); } return node; }紅黑樹的查找和刪除過(guò)程
????紅黑樹的查找跟二叉搜索樹的查找過(guò)程是完全一致的
????紅黑樹的刪除過(guò)程過(guò)于復(fù)雜,以致于很多程序員用不同的方法去規(guī)避它,其中一種方法是:為已刪除的節(jié)點(diǎn)做標(biāo)記而不實(shí)際刪除它。這里不做進(jìn)一步的討論。
????紅黑樹的詳細(xì)實(shí)現(xiàn)可以參考:紅黑樹完整代碼Java實(shí)現(xiàn)
2-3-4樹????2-3-4樹是一種多叉樹,名字中的2、3和4的含義是指一個(gè)節(jié)點(diǎn)可能含有的子節(jié)點(diǎn)的個(gè)數(shù)。2-3-4樹性質(zhì)如下:
任一節(jié)點(diǎn)只能是 2 度節(jié)點(diǎn)、3 度節(jié)點(diǎn)或 4 度節(jié)點(diǎn),不存在元素?cái)?shù)為 0 的節(jié)點(diǎn)(2度節(jié)點(diǎn)和3度節(jié)點(diǎn)是指該節(jié)點(diǎn)有2個(gè)或者3個(gè)子節(jié)點(diǎn))
所有葉子節(jié)點(diǎn)都擁有相同的深度(depth)
元素始終保持排序順序
????2-3-4樹結(jié)構(gòu)圖如下:
????為了方便起見(jiàn),用從0到2的數(shù)字給數(shù)據(jù)項(xiàng)編號(hào),用0到3給子節(jié)點(diǎn)鏈編號(hào)。節(jié)點(diǎn)中的數(shù)據(jù)項(xiàng)按照關(guān)鍵字升序排列,習(xí)慣上從左到右升序。還加上以下幾點(diǎn):
根是child0的子樹的所有子節(jié)點(diǎn)的關(guān)鍵字值小于key0
根是child1的子樹的所有子節(jié)點(diǎn)的關(guān)鍵字值大于key0并且小于key1
根是child2的子樹的所有子節(jié)點(diǎn)的關(guān)鍵字值大于key1并且小于key2
根是child3的子樹的所有子節(jié)點(diǎn)的關(guān)鍵字值大于key2
????如圖:
????2-3-4樹依靠節(jié)點(diǎn)分裂來(lái)保持自身的平衡性。2-3-4樹分裂的規(guī)則是自頂向下的,如果根節(jié)點(diǎn)或者待插入的節(jié)點(diǎn)中數(shù)據(jù)項(xiàng)已滿,就要進(jìn)行分裂,分裂規(guī)則如下:
創(chuàng)建一個(gè)空節(jié)點(diǎn),它是要分裂節(jié)點(diǎn)的兄弟,在要分裂節(jié)點(diǎn)的右邊
待分裂節(jié)點(diǎn)右邊的數(shù)據(jù)項(xiàng)移到右邊節(jié)點(diǎn)中,左邊的數(shù)據(jù)項(xiàng)保留在原有節(jié)點(diǎn)中,中間的數(shù)據(jù)項(xiàng)上升到父節(jié)點(diǎn)中
????如圖:
????2-3樹也是一種多叉樹,與2-3-4樹類似,現(xiàn)在在很多應(yīng)用程序中還在應(yīng)用,一些用于2-3樹的技術(shù)會(huì)在B-樹中應(yīng)用。
????2-3樹比2-3-4樹少一個(gè)數(shù)據(jù)項(xiàng)和一個(gè)子節(jié)點(diǎn)。節(jié)點(diǎn)可以保存1個(gè)或者2個(gè)數(shù)據(jù)項(xiàng),可以有0個(gè)、1個(gè)、2個(gè)或者3個(gè)子節(jié)點(diǎn)。其它方面,父節(jié)點(diǎn)和子節(jié)點(diǎn)的關(guān)鍵字值的排列順序和2-3-4樹是一樣的。
節(jié)點(diǎn)分裂????2-3樹節(jié)點(diǎn)分裂和2-4樹節(jié)點(diǎn)分裂有很大的不同。2-3樹節(jié)點(diǎn)分裂是自底向上的(即若插入數(shù)據(jù)時(shí)根節(jié)點(diǎn)數(shù)據(jù)項(xiàng)已滿,不進(jìn)行分裂,只有待插入的節(jié)點(diǎn)數(shù)據(jù)項(xiàng)滿時(shí)才進(jìn)行分裂),而且2-3樹節(jié)點(diǎn)分裂必須用到新數(shù)據(jù)項(xiàng)。
????計(jì)算機(jī)中的機(jī)械磁盤是由磁頭和圓盤組成,每個(gè)圓盤上劃分為多個(gè)磁道,每個(gè)磁道又劃分為多個(gè)扇區(qū)。
????磁盤的結(jié)構(gòu)圖如下:
????系統(tǒng)將文件存儲(chǔ)到磁盤上時(shí),按柱面、磁頭、扇區(qū)的方式進(jìn)行,即最先是第1磁道的第一磁頭(也就是第1盤面的第1磁道)下的所有扇區(qū),然后,是同一柱面的下一磁頭,……,一個(gè)柱面存儲(chǔ)滿后就推進(jìn)到下一個(gè)柱面,直到把文件內(nèi)容全部寫入磁盤。
????系統(tǒng)也以相同的順序讀出數(shù)據(jù)。讀出數(shù)據(jù)時(shí)通過(guò)告訴磁盤控制器要讀出扇區(qū)所在的柱面號(hào)、磁頭號(hào)和扇區(qū)號(hào)(物理地址的三個(gè)組成部分)進(jìn)行(目前多是通過(guò)LBA線性尋址的方式定位)。
磁盤預(yù)讀????由于存儲(chǔ)介質(zhì)的特性,磁盤本身存取就比主存慢很多,再加上機(jī)械運(yùn)動(dòng)耗費(fèi)(磁盤旋轉(zhuǎn)和磁頭移動(dòng)),磁盤的存取速度往往是主存的幾百分之一,因此為了提高效率,要盡量減少磁盤I/O。為了達(dá)到這個(gè)目的,磁盤往往不是嚴(yán)格按需讀取,而是每次都會(huì)預(yù)讀,即使只需要一個(gè)字節(jié),磁盤也會(huì)從這個(gè)位置開(kāi)始,順序向后讀取一定長(zhǎng)度的數(shù)據(jù)放入內(nèi)存。
????預(yù)讀的長(zhǎng)度一般為頁(yè)(page)的整倍數(shù)。頁(yè)是計(jì)算機(jī)管理存儲(chǔ)器的邏輯塊,硬件及操作系統(tǒng)往往將主存和磁盤存儲(chǔ)區(qū)分割為連續(xù)的大小相等的塊,每個(gè)存儲(chǔ)塊稱為一頁(yè)(在許多操作系統(tǒng)中,頁(yè)得大小通常為4k),主存和磁盤以頁(yè)為單位交換數(shù)據(jù)。當(dāng)程序要讀取的數(shù)據(jù)不在主存中時(shí),會(huì)觸發(fā)一個(gè)缺頁(yè)異常,此時(shí)系統(tǒng)會(huì)向磁盤發(fā)出讀盤信號(hào),磁盤會(huì)找到數(shù)據(jù)的起始位置并向后連續(xù)讀取一頁(yè)或幾頁(yè)載入內(nèi)存中,然后異常返回,程序繼續(xù)運(yùn)行(詳情請(qǐng)參考頁(yè)面置換算法以及虛擬內(nèi)存)。
擴(kuò)展每個(gè)扇區(qū)的弧長(zhǎng)是一樣的嗎?
????目前大多數(shù)教程中給出的圖片都是老式的機(jī)械磁盤的組成。在老式機(jī)械磁盤中,每個(gè)磁道的扇區(qū)弧長(zhǎng)是不一樣的。越靠?jī)?nèi)的磁道密度越大,存儲(chǔ)的數(shù)據(jù)也就越多;越靠外的磁道密度越小,存儲(chǔ)的數(shù)據(jù)也就越少。所以,雖然內(nèi)外磁道的扇區(qū)弧長(zhǎng)不一樣,由于密度的原因,每個(gè)扇區(qū)存儲(chǔ)的數(shù)據(jù)量仍然是一樣的,都是512B。在新式磁盤中,內(nèi)外磁道的扇區(qū)密度都是相同的,所以新式磁盤每個(gè)扇區(qū)的弧長(zhǎng)都是一樣的。
B-樹和B+樹????2-3樹和2-3-4樹是B樹的一種特例,B樹的操作與2-3樹和2-3-4樹大致相同,此處不在過(guò)多介紹。
B樹為何適于外部存儲(chǔ)????前面已經(jīng)簡(jiǎn)單介紹過(guò),磁盤控制器每次預(yù)讀幾個(gè)文件塊的內(nèi)容,所以對(duì)于磁盤讀寫來(lái)說(shuō),當(dāng)需要的數(shù)據(jù)都在一個(gè)文件塊中時(shí),磁盤讀寫次數(shù)最少,此時(shí)效率是最高的。而B樹設(shè)計(jì)將每個(gè)節(jié)點(diǎn)的數(shù)據(jù)項(xiàng)剛好填滿一個(gè)文件塊.
????假設(shè)這樣一種極端情況,如果每個(gè)文件塊中只有一條記錄是我們需要的。那么當(dāng)我們獲取第二條記錄時(shí)又要重新從磁盤加載新的文件塊。此時(shí)由于磁盤讀取次數(shù)增多,導(dǎo)致程序的性能大大下降。
B+樹????B+樹是B-樹的變形。B+樹與B樹的區(qū)別在于:
B+樹非葉子節(jié)點(diǎn)只保存索引,數(shù)據(jù)全部保存在葉子節(jié)點(diǎn)上
B+樹的所有的葉子節(jié)點(diǎn)組成了一張鏈表,便于數(shù)據(jù)遍歷
對(duì)于有M個(gè)數(shù)據(jù)項(xiàng)的B+樹,最多只會(huì)有M的子節(jié)點(diǎn)
如圖:
????基于上文對(duì)2-3-4樹和2-3樹的討論,傳統(tǒng)的B+樹也是按照50%的分裂方式,這樣節(jié)點(diǎn)分裂后,新的節(jié)點(diǎn)中只有原來(lái)一半的數(shù)據(jù)量,不但浪費(fèi)了空間,還造成節(jié)點(diǎn)的增多,從而加重磁盤IO的次數(shù)。在目前絕大部分關(guān)系型數(shù)據(jù)庫(kù)中,都針對(duì)B+樹索引的遞增/遞減插入進(jìn)行了優(yōu)化,新的分裂策略在插入新數(shù)據(jù)時(shí),不移動(dòng)原有頁(yè)面的任何記錄,只是將新插入的記錄寫到新頁(yè)面之中,這樣原有頁(yè)面的利用率仍然是100%。
????所以對(duì)于MySQL數(shù)據(jù)庫(kù)來(lái)說(shuō),使用自增主鍵插入數(shù)據(jù)時(shí)就會(huì)形成一個(gè)緊湊的索引結(jié)構(gòu),近似順序填滿。由于每次插入時(shí)也不需要移動(dòng)已有數(shù)據(jù),因此效率很高,也不會(huì)增加很多開(kāi)銷在維護(hù)索引上。
如圖:
從MySQL Bug#67718淺談B+樹索引的分裂優(yōu)化
紅黑樹完整代碼Java實(shí)現(xiàn)
硬盤的讀寫原理
Java數(shù)據(jù)結(jié)構(gòu)和算法 [美]Robert Lafore著
算法導(dǎo)論 [美]Thomas H.Cormen,[美]Charles E.Leiserson,[美]Ronald L.Rivest,[美]Clifford Stein 著
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/69356.html
摘要:在中渲染樹中的每個(gè)節(jié)點(diǎn)即是一個(gè)渲染器或者渲染器對(duì)象。計(jì)算的樣式每個(gè)渲染器對(duì)象代表一個(gè)矩形區(qū)域通常是和一個(gè)節(jié)點(diǎn)的盒模型相對(duì)應(yīng)。坐標(biāo)系統(tǒng)是相對(duì)于根渲染器的。根渲染器的定位為和大小即為瀏覽器窗口的可視化部分比如。渲染器作廢其在屏幕上的矩形區(qū)域。 原文請(qǐng)查閱這里,略有刪減,本文采用知識(shí)共享署名 4.0 國(guó)際許可協(xié)議共享,BY Troland。 本系列持續(xù)更新中,Github 地址請(qǐng)查閱這里。 ...
摘要:在中渲染樹中的每個(gè)節(jié)點(diǎn)即是一個(gè)渲染器或者渲染器對(duì)象。計(jì)算的樣式每個(gè)渲染器對(duì)象代表一個(gè)矩形區(qū)域通常是和一個(gè)節(jié)點(diǎn)的盒模型相對(duì)應(yīng)。坐標(biāo)系統(tǒng)是相對(duì)于根渲染器的。根渲染器的定位為和大小即為瀏覽器窗口的可視化部分比如。渲染器作廢其在屏幕上的矩形區(qū)域。 原文請(qǐng)查閱這里,略有刪減,本文采用知識(shí)共享署名 4.0 國(guó)際許可協(xié)議共享,BY Troland。 本系列持續(xù)更新中,Github 地址請(qǐng)查閱這里。 ...
摘要:在中渲染樹中的每個(gè)節(jié)點(diǎn)即是一個(gè)渲染器或者渲染器對(duì)象。計(jì)算的樣式每個(gè)渲染器對(duì)象代表一個(gè)矩形區(qū)域通常是和一個(gè)節(jié)點(diǎn)的盒模型相對(duì)應(yīng)。坐標(biāo)系統(tǒng)是相對(duì)于根渲染器的。根渲染器的定位為和大小即為瀏覽器窗口的可視化部分比如。渲染器作廢其在屏幕上的矩形區(qū)域。 原文請(qǐng)查閱這里,略有刪減,本文采用知識(shí)共享署名 4.0 國(guó)際許可協(xié)議共享,BY Troland。 本系列持續(xù)更新中,Github 地址請(qǐng)查閱這里。 ...
摘要:向影子樹添加的任何內(nèi)容都將成為宿主元素的本地元素,包括,這就是影子實(shí)現(xiàn)樣式作用域的方式。 這是專門探索 JavaScript 及其所構(gòu)建的組件的系列文章的第 17 篇。 想閱讀更多優(yōu)質(zhì)文章請(qǐng)猛戳GitHub博客,一年百來(lái)篇優(yōu)質(zhì)文章等著你! 如果你錯(cuò)過(guò)了前面的章節(jié),可以在這里找到它們: JavaScript 是如何工作的:引擎,運(yùn)行時(shí)和調(diào)用堆棧的概述! JavaScript 是如何工作...
閱讀 3427·2021-11-12 10:36
閱讀 2734·2021-11-11 16:55
閱讀 2957·2021-09-27 13:36
閱讀 1615·2021-08-05 10:01
閱讀 3555·2019-08-30 15:55
閱讀 765·2019-08-30 13:01
閱讀 1905·2019-08-29 17:16
閱讀 2376·2019-08-29 16:40