จะได้รับชุดคีย์ที่กำหนดไว้ล่วงหน้าแล้วจะเรียงลำดับคีย์ใหม่เพื่อให้ใช้จำนวนโหนดขั้นต่ำเมื่อแทรกลงใน B-Tree ได้อย่างไร

ดังนั้นฉันจึงมีปัญหาซึ่งฉันค่อนข้างแน่ใจว่าสามารถแก้ไขได้ แต่หลังจากการคิดและการอภิปรายหลายชั่วโมง ก็มีความคืบหน้าเพียงบางส่วนเท่านั้น

ประเด็นมีดังนี้ ฉันกำลังสร้าง BTree ที่อาจมีคีย์ไม่กี่ล้านคีย์ เมื่อค้นหา BTree จะมีเพจตามความต้องการจากดิสก์ไปยังหน่วยความจำ และแต่ละเพจที่ใช้งานอยู่มีราคาค่อนข้างแพง สิ่งนี้หมายความว่าเราต้องการที่จะสำรวจโหนดน้อยที่สุดเท่าที่จะเป็นไปได้ (แม้ว่าหลังจากโหนดถูกสำรวจไปแล้ว ค่าใช้จ่ายในการสำรวจผ่านโหนดนั้น จนถึงโหนดนั้นคือ 0) เป็นผลให้เราไม่ต้องการเปลืองพื้นที่ด้วยการมีโหนดจำนวนมากใกล้ความจุขั้นต่ำ ตามทฤษฎี สิ่งนี้ควรป้องกันได้ (ด้วยเหตุผล) เนื่องจากโครงสร้างของต้นไม้ขึ้นอยู่กับลำดับที่ใส่กุญแจเข้าไป

ดังนั้น คำถามคือจะเรียงลำดับคีย์ใหม่ได้อย่างไร โดยหลังจากที่ BTree ถูกสร้างขึ้นแล้ว จะมีการใช้โหนดจำนวนน้อยที่สุด นี่คือตัวอย่าง:

ตัวอย่าง

ฉันสะดุดกับคำถามนี้ คุณควรแทรกชุดคีย์ที่รู้จักลงใน B-Tree เพื่อให้ได้ความสูงน้อยที่สุดตามลำดับใด ซึ่งน่าเสียดายที่ถามคำถามที่แตกต่างออกไปเล็กน้อย คำตอบดูเหมือนจะไม่สามารถแก้ปัญหาของฉันได้ นอกจากนี้ยังคุ้มค่าที่จะเพิ่มว่าเราต้องการการรับประกันทางคณิตศาสตร์ที่มาจากการไม่สร้างแผนภูมิด้วยตนเอง และใช้เฉพาะตัวเลือกการแทรกเท่านั้น เราไม่ต้องการสร้างต้นไม้ด้วยตนเอง ทำผิดพลาด แล้วพบว่าไม่สามารถค้นหาได้!

ฉันยังสะดุดกับงานวิจัย 2 ฉบับซึ่งใกล้จะแก้คำถามของฉันได้มากแต่ก็ยังไม่ค่อยมี! การเพิ่มประสิทธิภาพเวลาและพื้นที่ใน B-Trees และ ต้นไม้ 2,3 ต้นที่เหมาะสมที่สุด (โดยที่ฉันถ่ายภาพด้านบนมาจากอันที่จริง) พูดคุยและหาปริมาณความแตกต่างระหว่างพื้นที่ที่เหมาะสมที่สุด และเว้นวรรค BTrees ที่ไม่ดีนัก แต่อย่าอธิบายวิธีออกแบบลำดับการแทรกเท่าที่ฉันเห็น

ความช่วยเหลือใด ๆ เกี่ยวกับเรื่องนี้จะได้รับการชื่นชมอย่างมาก

ขอบคุณ

สามารถดูผลงานวิจัยได้ที่:

http://www.uqac.ca/rebaine/8INF805/Automne2007/Sujets2007Automne/p174-rosenberg.pdf

http://scholarship.claremont.edu/cgi/viewcontent.cgi?article=1143&context=hmc_fac_pub

แก้ไข:: ฉันลงเอยด้วยการเติมโครงกระดูก btree ที่สร้างขึ้นตามที่อธิบายไว้ในเอกสารด้านบนด้วยอัลกอริทึม FILLORDER ดังที่ได้กล่าวไว้ก่อนหน้านี้ ฉันหวังว่าจะหลีกเลี่ยงสิ่งนี้ แต่สุดท้ายฉันก็นำไปใช้ก่อนที่จะโพสต์คำตอบที่ยอดเยี่ยม 2 ข้อ!


person Squimmy    schedule 28.07.2014    source แหล่งที่มา
comment
คุณสามารถสร้าง b-tree เป็นกลุ่มได้อย่างง่ายดายโดยการเรียงลำดับรายการและสร้างแผนผังด้วยรายการที่เรียงลำดับนั้น คุณไม่จำเป็นต้องแทรกทีละรายการด้วยซ้ำ   -  person usr    schedule 28.07.2014
comment
ฉันกลัวว่าฉันไม่ค่อยตาม การแทรกรายการตามลำดับจะไม่ส่งผลให้ BTree มีพื้นที่เหมาะสมที่สุดเท่าที่ฉันเห็นใช่ไหม   -  person Squimmy    schedule 28.07.2014
comment
อัลกอริทึมไม่ทำงานโดยการแทรกรายการ คุณเรียงลำดับรายการ จากนั้นสร้างโหนดปลายสุดจากรายการนั้น ตอนนี้คุณมีโหนดใบที่สมบูรณ์แบบแล้ว ถัดไปคุณสร้างเลเยอร์เพิ่มเติมที่ด้านบนของโหนดใบเหล่านั้น สิ่งที่ RDBMS ทำคือมีกฎพิเศษสำหรับการแทรกที่ส่วนท้าย พวกเขาไม่ได้แบ่งหน้าเท่าๆ กัน แต่สร้างหน้าว่างใหม่ อย่าใช้อัลกอริธึม b-tree (จากวิกิพีเดีย) มากเกินไป คุณสามารถเล่นกับพวกเขาได้   -  person usr    schedule 28.07.2014
comment
อ้อเข้าใจแล้ว. ฉันลังเลมากที่จะสร้างต้นไม้จากใบไม้ แต่ถึงอย่างนั้นก็มีความเป็นไปได้ที่แมลงประหลาดจำนวนหนึ่งในล้านจะถูกแนะนำโดยเราไม่ได้คาดคิดมาก่อน และจบลงด้วยการสร้าง B-Tree ที่ไม่ถูกต้องซึ่งไม่สามารถค้นหาได้ จะสุดยอดเลย เป็นปัญหาสุดๆ ฉันไม่ได้กังวลเกี่ยวกับการแทรกคำหลังจริง ๆ หลังจากที่สร้างแล้ว เราไม่จำเป็นต้องทำการแทรกใดๆ กับมันจริงๆ   -  person Squimmy    schedule 28.07.2014
comment
แล้วการใช้ห้องสมุด b-tree ล่ะ? ใส่ตามลำดับ. ฉันว่าห้องสมุดที่ดีจะปรับให้เหมาะสมสำหรับกรณีนั้นเพราะมันเป็นเรื่องปกติ   -  person usr    schedule 28.07.2014
comment
หากพื้นที่ที่เหมาะสมคือตัวขับเคลื่อนหลักของคุณ คุณแน่ใจหรือไม่ว่า b - tree เป็นโครงสร้างข้อมูลที่เหมาะสมที่สุด อาร์เรย์ที่เรียงลำดับอย่างง่าย (เวกเตอร์) ให้พื้นที่แคชที่ดีขึ้น และยังคงความสามารถในการค้นหาด้วยความซับซ้อนของบันทึก (n)   -  person Chad    schedule 30.07.2014
comment
สิ่งนี้แตกต่างจากต้นไม้ไบนารี่ที่ปรับสมดุลในตัวเองมาตรฐานเช่นต้นไม้สีแดงดำหรือไม่? คุณแค่มองหาการรับประกันว่าความสูงเป็น log2(n) ใช่ไหม?   -  person Moby Disk    schedule 30.07.2014
comment
ต้นไม้สีแดงดำไม่มีการรับประกัน log2(n) การรับประกันเป็นเพียง O(log2(n)) และในความเป็นจริงสามารถมีขนาดใหญ่ถึง 2log2(n) และฉันคิดว่านั่นคือประเด็นของคำถามในระดับหนึ่ง คุณสามารถแทรกลำดับเฉพาะที่สร้างคุณลักษณะความสูงที่ดีกว่าที่อัลกอริทึมรับประกันได้ด้วยตัวเองหรือไม่ ดูความคิดเห็นถัดไปของฉัน (ยาวเกินไป)!   -  person Jeremy West    schedule 31.07.2014
comment
นี่เป็นเรื่องยากที่จะตอบโดยไม่รู้ว่าการแทรกทำงานอย่างไร ฉันสมมติว่าคุณมีการใช้งานกล่องดำที่ให้คุณแทรกรายการแล้ววางลงในแผนภูมิด้วยวิธีใดวิธีหนึ่ง จากนั้นคำตอบจะขึ้นอยู่กับว่าอัลกอริทึมตัดสินใจแยกบล็อกเมื่อใด และจะแยกบล็อกอย่างไรเมื่อแยก   -  person Jeremy West    schedule 31.07.2014


คำตอบ (5)


อัลกอริทึมด้านล่างควรใช้ได้กับ B-Trees ที่มีจำนวนคีย์ขั้นต่ำใน node = d และ maximum = 2*d ฉันคิดว่ามันสามารถวางนัยทั่วไปสำหรับคีย์สูงสุด 2*d + 1 ได้หากทราบวิธีการเลือกค่ามัธยฐาน

อัลกอริทึมด้านล่างได้รับการออกแบบมาเพื่อลดจำนวนโหนด ไม่ใช่แค่ความสูงของต้นไม้เท่านั้น

วิธีการขึ้นอยู่กับแนวคิดในการใส่คีย์ลงใน leaf ที่ไม่เต็ม หรือถ้า leaf ทั้งหมดเต็มเพื่อใส่คีย์ไว้ใต้โหนดที่ไม่เต็มต่ำสุด

แม่นยำยิ่งขึ้น ต้นไม้ที่สร้างโดยอัลกอริธึมที่เสนอนั้นตรงตามข้อกำหนดต่อไปนี้: มีความสูงขั้นต่ำที่เป็นไปได้ มีโหนดที่ไม่เต็มจำนวนไม่เกินสองโหนดในแต่ละระดับ (เป็นสองโหนดที่ถูกต้องที่สุดเสมอ)

เนื่องจากเรารู้ว่าจำนวนโหนดในระดับใด ๆ ยกเว้นรากจะเท่ากับผลรวมของหมายเลขโหนดและหมายเลขคีย์ทั้งหมดในระดับที่สูงกว่าอย่างเคร่งครัด เราสามารถพิสูจน์ได้ว่าไม่มีการจัดเรียงโหนดใหม่ที่ถูกต้องระหว่างระดับซึ่งจะลดจำนวนโหนดทั้งหมด ตัวอย่างเช่น การเพิ่มจำนวนคีย์ที่แทรกเหนือระดับใดระดับหนึ่งจะนำไปสู่การเพิ่มขึ้นของโหนดในระดับนั้น และส่งผลให้จำนวนโหนดทั้งหมดเพิ่มขึ้นด้วย แม้ว่าความพยายามที่จะลดจำนวนคีย์ที่สูงกว่าระดับที่กำหนดจะส่งผลให้จำนวนโหนดลดลงในระดับนั้น และไม่สามารถใส่คีย์ทั้งหมดในระดับนั้นได้โดยไม่เพิ่มความสูงของต้นไม้ นอกจากนี้ยังเห็นได้ชัดว่าการจัดเรียงปุ่มในระดับใดระดับหนึ่งถือเป็นระดับที่เหมาะสมที่สุด การใช้เหตุผลข้างต้นอาจสร้างการพิสูจน์ที่เป็นทางการมากขึ้นผ่านการอุปนัยทางคณิตศาสตร์ได้

แนวคิดคือการเก็บรายการตัวนับ (ขนาดรายการไม่ใหญ่เกินความสูงของต้นไม้) เพื่อติดตามจำนวนคีย์ที่เพิ่มในแต่ละระดับ เมื่อฉันได้เพิ่มคีย์ d ในบางระดับ หมายความว่าโหนดถูกเติมเต็มครึ่งหนึ่งที่สร้างขึ้นในระดับนั้น และหากมีคีย์เพียงพอที่จะเติมอีกครึ่งหนึ่งของโหนดนี้ เราควรข้ามคีย์นี้และเพิ่มรูทสำหรับระดับที่สูงกว่า ด้วยวิธีนี้ รูทจะถูกวางไว้ระหว่างครึ่งแรกของทรีย่อยก่อนหน้าและครึ่งแรกของทรีย่อยถัดไป มันจะทำให้เกิดการแตกแยก เมื่อรูทเข้ามาแทนที่และทรีย่อยสองครึ่งจะถูกแยกออกจากกัน สถานที่สำหรับกุญแจที่ข้ามจะปลอดภัยในขณะที่เราผ่านกุญแจที่ใหญ่กว่าและสามารถเติมได้ในภายหลัง

นี่คือโค้ดที่เกือบจะใช้งานได้ (หลอก) จำเป็นต้องเรียงลำดับอาร์เรย์:

PushArray(BTree bTree, int d, key[] Array)
{
    List<int> counters = new List<int>{0};
    //skip list will contain numbers of nodes to skip 
    //after filling node of some order in half
    List<int> skip  = new List<int>();
    List<Pair<int,int>> skipList = List<Pair<int,int>>();

    int i = -1;
    while(true)
    {     
       int order = 0;
       while(counters[order] == d) order += 1;
       for(int j = order - 1; j >= 0; j--) counters[j] = 0;

       if (counters.Lenght <= order + 1) counters.Add(0);
       counters[order] += 1;

       if (skip.Count <= order)
              skip.Add(i + 2);    
       if (order > 0)
           skipList.Add({i,order}); //list of skipped parts that will be needed later
       i += skip[order];

       if (i > N) break;

       bTree.Push(Array[i]);
    }

    //now we need to add all skipped keys in correct order
    foreach(Pair<int,int> p in skipList)
    {
        for(int i = p.2; i > 0; i--)
            PushArray(bTree, d, Array.SubArray(p.1 + skip[i - 1], skip[i] -1))
    }
}

ตัวอย่าง:

นี่คือวิธีการจัดเรียงตัวเลขและคีย์ตัวนับที่สอดคล้องกันสำหรับ d = 2 ในขณะที่ส่งผ่านอาร์เรย์ครั้งแรก ฉันทำเครื่องหมายคีย์ที่กดเข้าไปใน B-Tree ระหว่างการส่งครั้งแรก (ก่อนวนซ้ำด้วยการเรียกซ้ำ) ด้วย 'o' และข้ามด้วย 'x'

                                                              24
        4         9             14             19                            29 
0 1 2 3   5 6 7 8   10 11 12 13    15 16 17 18    20 21 22 23    25 26 27 28    30 ...
o o x x o o o x x o  o  o  x  x  x  x  x  x  x  x  x  x  x  x  o  o  o  x  x  o  o ...
1 2     0 1 2     0  1  2                                      0  1  2        0  1 ...
0 0     1 1 1     2  2  2                                      0  0  0        1  1 ...
0 0     0 0 0     0  0  0                                      1  1  1        1  1 ...
skip[0] = 1 
skip[1] = 3 
skip[2] = 13

เนื่องจากเราไม่วนซ้ำผ่านคีย์ที่ข้ามไป เราจึงมีความซับซ้อนของเวลา O(n) โดยไม่ต้องเพิ่มให้กับ B-Tree และสำหรับอาร์เรย์ที่เรียงลำดับ

ในรูปแบบนี้อาจไม่ชัดเจนว่ามันทำงานอย่างไรเมื่อมีคีย์ไม่เพียงพอที่จะเติมครึ่งหลังของโหนดหลังจากข้ามบล็อก แต่เรายังสามารถหลีกเลี่ยงการข้ามคีย์ข้าม [ลำดับ] ทั้งหมดได้หากความยาวรวมของอาร์เรย์น้อยกว่า ~ i + 2 * ข้าม[สั่งซื้อ] และข้ามเพื่อข้ามคีย์ [สั่งซื้อ - 1] แทน สตริงดังกล่าวหลังจากเปลี่ยนตัวนับ แต่ก่อนที่จะเปลี่ยนตัวแปร ฉันอาจถูกเพิ่ม:

while(order > 0 && i + 2*skip[order] > N) --order;

มันจะเป็นสาเหตุที่ถูกต้องหากจำนวนคีย์ทั้งหมดในระดับปัจจุบันน้อยกว่าหรือเท่ากับ 3*d คีย์เหล่านั้นจะยังคงถูกแบ่งอย่างถูกต้องหากเพิ่มคีย์เหล่านั้นในลำดับดั้งเดิม ดังกล่าวจะนำไปสู่การจัดเรียงคีย์ที่แตกต่างกันเล็กน้อยระหว่างสองโหนดสุดท้ายในบางระดับ แต่จะไม่ฝ่าฝืนข้อกำหนดใดๆ ที่อธิบายไว้ และอาจจะทำให้พฤติกรรมเข้าใจง่ายขึ้น

อาจสมเหตุสมผลที่จะค้นหาแอนิเมชันและดูวิธีการทำงาน นี่คือลำดับที่ควรสร้างขึ้นในช่วง 0..29: 0 1 4 5 6 9 10 11 24 25 26 29 /สิ้นสุดการส่งผ่านครั้งแรก< /em>/ 2 3 7 8 14 15 16 19 20 21 12 13 17 18 22 23 27 28 ป้อนคำอธิบายรูปภาพที่นี่

person Lurr    schedule 03.08.2014

อัลกอริธึมด้านล่างพยายามจัดเตรียมลำดับคีย์ เพื่อที่คุณไม่จำเป็นต้องมีอำนาจหรือความรู้เกี่ยวกับขั้นตอนการแทรก สมมติฐานเดียวคือโหนดทรีที่เติมมากเกินไปจะถูกแยกที่ตรงกลางหรือที่ตำแหน่งขององค์ประกอบที่แทรกสุดท้าย ไม่เช่นนั้น B-tree จะถือเป็นกล่องดำได้

เคล็ดลับคือการทริกเกอร์การแยกโหนดด้วยวิธีควบคุม ขั้นแรกให้คุณเติมโหนดให้ครบถ้วน ครึ่งซ้ายมีคีย์ที่อยู่ด้วยกัน และครึ่งขวามีคีย์อีกช่วงหนึ่งที่อยู่ด้วยกัน ในที่สุดคุณก็ใส่คีย์ที่อยู่ระหว่างสองช่วงนั้นแต่เป็นของทั้งสองช่วง ช่วงย่อยทั้งสองจะถูกแบ่งออกเป็นโหนดแยกกันและคีย์ที่แทรกสุดท้ายจะจบลงที่โหนดหลัก หลังจากแยกออกในลักษณะนี้แล้ว คุณสามารถเติมส่วนที่เหลือของโหนดย่อยทั้งสองเพื่อทำให้แผนผังมีขนาดกะทัดรัดที่สุดเท่าที่จะเป็นไปได้ วิธีนี้ยังใช้ได้กับโหนดพาเรนต์ที่มีโหนดย่อยมากกว่า 2 โหนด เพียงทำซ้ำกับโหนดย่อยตัวใดตัวหนึ่งจนกว่าจะสร้างโหนดย่อยตามจำนวนที่ต้องการ ด้านล่างนี้ ฉันใช้สิ่งที่เป็นแนวคิดโหนดลูกขวาสุดเป็น "พื้นที่แยก" (ขั้นตอนที่ 5 และ 6.1)

ใช้เคล็ดลับการแยกซ้ำๆ และองค์ประกอบทั้งหมดควรจะอยู่ในตำแหน่งที่เหมาะสมที่สุด (ซึ่งขึ้นอยู่กับจำนวนองค์ประกอบ) ฉันเชื่อว่าอัลกอริธึมด้านล่างรับประกันว่าความสูงของทรีนั้นน้อยที่สุดเสมอ และโหนดทั้งหมดยกเว้นรูทจะเต็มมากที่สุด อย่างไรก็ตาม ดังที่คุณอาจจินตนาการได้ว่าเป็นเรื่องยากที่จะแน่ใจได้อย่างสมบูรณ์หากไม่ได้ใช้งานและทดสอบอย่างละเอียดถี่ถ้วน ฉันได้ลองทำสิ่งนี้บนกระดาษแล้ว และฉันรู้สึกมั่นใจว่าอัลกอริธึมนี้หรือสิ่งที่คล้ายกันอย่างยิ่งควรจะทำงานได้

ต้นไม้โดยนัย T ด้วยปัจจัยการแตกแขนงสูงสุด M

ขั้นตอนสูงสุดที่มี คีย์ ยาว N:

  1. จัดเรียง คีย์
  2. ตั้งค่า minimal-tree-height เป็น ceil(log(N+1)/log(M))
  3. เรียก insert-chunk ด้วย chunk = keys และ H = minimal-tree-height.

ขั้นตอน insert-chunk ที่มีความยาว chunk L ความสูงของแผนผังย่อย H:

  1. If H is equal to 1:
    1. Insert all keys from the chunk into T
    2. กลับทันที.
  2. ตั้งค่าขนาดย่อยในอุดมคติ S เป็น pow(M, H - 1)
  3. กำหนดจำนวนของทรีย่อย T เป็น ceil((L + 1) / S)
  4. ตั้งค่าขนาดย่อยจริง S' เป็น ceil((L + 1) / T)
  5. เรียกซ้ำ insert-chunk ด้วย chunk' = คีย์ชั้นสุดท้าย ((S - 1) / 2) คีย์ของ chunk em> และ H' = H - 1.
  6. For each of the ceil(L / S') subchunks (of size S') except for the last with index I:
    1. Recursively call insert-chunk with chunk' = the first ceil((S - 1) / 2) keys of subchunk I and H' = H - 1.
    2. ใส่คีย์สุดท้ายของกลุ่มย่อย I ลงใน T (การแทรกนี้มีจุดประสงค์เพื่อกระตุ้นให้เกิดการแยก)
    3. เรียกซ้ำ insert-chunk ด้วย chunk' = คีย์ที่เหลือของ subchunk I (ถ้ามี) และ H' = H - 1.
  7. เรียกซ้ำ insert-chunk ด้วย chunk' = คีย์ที่เหลือของส่วนย่อยสุดท้ายและ H' = H - 1.

โปรดทราบว่ากระบวนการเรียกซ้ำจะถูกเรียกสองครั้งสำหรับแต่ละแผนผังย่อย ไม่เป็นไร เนื่องจากการเรียกครั้งแรกจะสร้างทรีย่อยครึ่งหนึ่งที่สมบูรณ์เสมอ

person Julian    schedule 31.07.2014

นี่คือวิธีที่จะนำไปสู่ความสูงขั้นต่ำใน BST ใด ๆ (รวมถึง b tree) :-

  1. จัดเรียงอาร์เรย์
  2. สมมติว่าคุณสามารถมีคีย์ m ใน b tree ได้
  3. แบ่งอาร์เรย์ซ้ำในส่วนเท่า ๆ กันของ m+1 โดยใช้คีย์ m ในพาเรนต์
  4. สร้างแผนผังลูกของคีย์ที่เรียงลำดับ n/(m+1) โดยใช้การเรียกซ้ำ

ตัวอย่าง : -

m = 2 array = [1 2 3 4 5 6 7 8 9 10]

divide array into three parts :-

root = [4,8]

recursively solve :-

child1 = [1 2 3]

root1 = [2]

left1 = [1]

right1 = [3]

similarly for all childs solve recursively.
person Vikram Bhat    schedule 31.07.2014

นี่เกี่ยวกับการเพิ่มประสิทธิภาพขั้นตอนการสร้างหรือการปรับโครงสร้างต้นไม้ให้เหมาะสมหรือไม่?

คุณสามารถสร้าง B-Tree ที่มีประสิทธิภาพสูงสุดได้อย่างชัดเจนโดยการสร้าง Balanced Binary Tree แบบเต็มก่อน จากนั้นจึงทำสัญญาโหนด

ในระดับใดก็ตามในไบนารีทรี ช่องว่างของตัวเลขระหว่างสองโหนดประกอบด้วยตัวเลขทั้งหมดระหว่างสองค่านั้นตามคำจำกัดความของไบนารีทรี และนี่คือคำจำกัดความของ B-Tree ไม่มากก็น้อย คุณเพียงแค่เริ่มทำสัญญาการแบ่งไบนารีทรีเป็นโหนด B-Tree เนื่องจากต้นไม้ไบนารีมีความสมดุลโดยการก่อสร้าง ช่องว่างระหว่างโหนดในระดับเดียวกันจึงมีจำนวนโหนดเท่ากันเสมอ (สมมติว่าต้นไม้เต็มแล้ว) ดังนั้น BTree ที่สร้างขึ้นจึงรับประกันความสมดุล

ในทางปฏิบัตินี่อาจเป็นวิธีที่ค่อนข้างช้าในการสร้าง BTree แต่แน่นอนว่ามันตรงตามเกณฑ์ของคุณสำหรับการสร้าง B-Tree ที่เหมาะสมที่สุด และวรรณกรรมเกี่ยวกับการสร้าง binary tree ที่สมดุลก็ครอบคลุมครบถ้วน

=====================================

ในกรณีของคุณ ที่ซึ่งคุณอาจถอดชั้นวาง "ดีกว่า" ออกจากเวอร์ชันที่เหมาะสมที่สุดที่สร้างขึ้น คุณเคยคิดบ้างไหมว่าการเปลี่ยนจำนวนโหนดลูกสามารถมีได้? แผนภาพของคุณดูเหมือนต้นไม้ 2-3 ต้นแบบคลาสสิก แต่เป็นไปได้อย่างสมบูรณ์แบบที่จะมีต้นไม้ 3-4 ต้น หรือต้นไม้ 3-5 ต้น ซึ่งหมายความว่าทุกโหนดจะมีลูกอย่างน้อยสามคน

person phil_20686    schedule 06.08.2014
comment
ไม่ทราบว่ามี 3-3 ต้นได้หรือเปล่าคะ? มีใครรู้บ้าง? - person phil_20686; 06.08.2014
comment
คุณไม่สามารถรองรับทั้ง 3-3 ไม่ 3-4 ไม่ 3-5 โดยใช้อัลกอริทึม B-tree แบบคลาสสิกเพียง 3-6 หรือ 3-7 ฉันไม่แน่ใจว่าต้นไม้ 3-3 ต้นไม่สามารถประดิษฐ์ขึ้นมาได้เลย แต่เห็นได้ชัดว่าคุณไม่สามารถเก็บคีย์ n ไว้ในแผนผังได้หากทุกโหนดมี 3 คีย์และ n ไม่สามารถหารด้วย 3 ได้ ดังนั้นคุณจะต้องมีบัฟเฟอร์เพิ่มเติม เพื่อเก็บคีย์ไว้ n%3 อันเป็นอย่างน้อย - person Lurr; 06.08.2014
comment
นี่ไม่ใช่ข้อจำกัดที่ยากเนื่องจากคุณสามารถมีโหนดใบที่เทียบเท่ากับค่าว่างได้ เช่น. เพิ่ม long.minvalue ลงในรายการ เนื่องจากพวกมันจะเป็นโหนดที่ต่ำที่สุดในแผนผังเสมอ คุณสามารถติดตามและลบพวกมันได้อย่างง่ายดายหากคุณต้องการเพิ่มโหนด 3-6 และ 3-7 จะสะดวกกว่าเมื่อคุณหลีกเลี่ยงภาวะแทรกซ้อนนั้น ปัญหาข้อ 3-3 คือการปรับสมดุลจะต้องเกิดขึ้นทุกครั้งที่มีการลบโหนดออก - person phil_20686; 06.08.2014

คำถามของคุณเกี่ยวกับการเพิ่มประสิทธิภาพ btree ไม่น่าเป็นไปได้ที่คุณจะทำเช่นนี้เพียงเพื่อความสนุกสนาน ดังนั้นฉันจึงสรุปได้ว่าคุณต้องการเพิ่มประสิทธิภาพการเข้าถึงข้อมูล - อาจเป็นส่วนหนึ่งของการเขียนโปรแกรมฐานข้อมูลหรืออะไรทำนองนี้ คุณเขียนว่า: "เมื่อค้นหา BTree มันจะถูกเพจตามความต้องการจากดิสก์ลงในหน่วยความจำ" ซึ่งหมายความว่าคุณมีหน่วยความจำไม่เพียงพอที่จะทำการแคชประเภทใด ๆ หรือคุณมีนโยบายที่จะใช้หน่วยความจำให้น้อยที่สุดเท่าที่จะทำได้ ไม่ว่าจะด้วยวิธีใด นี่อาจเป็นสาเหตุว่าทำไมคำตอบสำหรับคำถามของคุณจึงไม่เป็นที่พอใจ ให้ฉันอธิบายว่าทำไม

เมื่อพูดถึงการเพิ่มประสิทธิภาพการเข้าถึงข้อมูล หน่วยความจำคือเพื่อนของคุณ ไม่สำคัญว่าคุณจะอ่านหรือเขียนการเพิ่มประสิทธิภาพที่คุณต้องการหน่วยความจำ การเพิ่มประสิทธิภาพการเขียนทุกประเภทจะทำงานบนสมมติฐานที่ว่าสามารถอ่านข้อมูลได้อย่างรวดเร็ว (จากหน่วยความจำ) - การเรียงลำดับต้องการข้อมูล หากคุณมีหน่วยความจำไม่เพียงพอสำหรับการเพิ่มประสิทธิภาพการอ่าน คุณจะไม่มีหน่วยความจำเพียงพอสำหรับการเพิ่มประสิทธิภาพการเขียนด้วย

ทันทีที่คุณยินดียอมรับการใช้หน่วยความจำบางส่วนเป็นอย่างน้อย คุณสามารถคิดใหม่เกี่ยวกับคำสั่งของคุณ "เมื่อค้นหา BTree จะถูกเพจตามความต้องการจากดิสก์ไปยังหน่วยความจำ" ซึ่งทำให้มีพื้นที่สำหรับสร้างสมดุลระหว่างการเพิ่มประสิทธิภาพการอ่านและเขียน BTREE ที่ได้รับการปรับให้เหมาะสมสูงสุดคือการเพิ่มประสิทธิภาพการเขียนให้สูงสุด ในสถานการณ์การเข้าถึงข้อมูลส่วนใหญ่ ฉันรู้ว่าคุณจะได้รับการเขียนเมื่ออ่าน 10-100 ครั้ง นั่นหมายความว่าการเพิ่มประสิทธิภาพการเขียนให้สูงสุดมีแนวโน้มที่จะให้ประสิทธิภาพที่ไม่ดีในแง่ของการเพิ่มประสิทธิภาพการเข้าถึงข้อมูล นั่นคือเหตุผลที่ฐานข้อมูลยอมรับรอบการปรับโครงสร้าง การสิ้นเปลืองพื้นที่หลัก btree ที่ไม่สมดุล และสิ่งต่างๆ เช่นนั้น...

person Quicker    schedule 05.08.2014