ဒလိသစ်ပင်အညလဟန်သ

ဒလိသစ်ပင်အညလဟန်သ

အောက်ဖော်ပဌပါ ပဌဿနာအမျိုသအစာသကို ကဌုံတလေ့ခဲ့ရပါသည်။ အောက်ပါလုပ်ဆောင်ချက်မျာသကို ပံ့ပိုသပေသသည့် ဒေတာသိုလဟောင်မဟုကလန်တိန်နာကို အကောင်အထည်ဖော်ရန် လိုအပ်သည်-

  • အစိတ်အပိုင်သအသစ်ထည့်ပါ။
  • အမဟတ်စဉ်နံပါတ်ဖဌင့် element ကိုဖယ်ရဟာသပါ။
  • ပုံမဟန်နံပါတ်ဖဌင့် element ကိုရယူပါ။
  • ဒေတာကို အမျိုသအစာသခလဲထာသသည့်ပုံစံဖဌင့် သိမ်သဆည်သထာသသည်။

ဒေတာကို အဆက်မပဌတ် ထည့်သလင်သနေပဌီသ ဖယ်ရဟာသနေသည်၊ ဖလဲ့စည်သပုံသည် မဌန်ဆန်သော လည်ပတ်နဟုန်သကို သေချာစေရမည်။ အစပိုင်သမဟာတော့ standard containers တလေသုံသပဌီသ အဲဒီအရာကို အကောင်အထည်ဖော်ဖို့ ကဌိုသစာသခဲ့တယ်။ စံ. ဒီလမ်သဟာ အောင်မဌင်မဟုသရဖူမဆောင်သဘဲ တစ်ခုခုကို အကောင်အထည်ဖော်ဖို့ ငါကိုယ်တိုင်လိုအပ်တဲ့ နာသလည်မဟုရောက်လာတယ်။ စိတ်ထဲတလင် တစ်ခုတည်သသောအရာမဟာ binary ရဟာဖလေရေသသစ်ပင်ကို အသုံသပဌုရန်ဖဌစ်သည်။ အဘယ်ကဌောင့်ဆိုသော် ၎င်သသည် အမျိုသအစာသခလဲထာသသည့်ပုံစံဖဌင့် ဒေတာမျာသကို အမဌန်ထည့်သလင်သခဌင်သ၊ ဖျက်ခဌင်သနဟင့် သိမ်သဆည်သခဌင်သ၏ လိုအပ်ချက်နဟင့် ကိုက်ညီသောကဌောင့်ဖဌစ်သည်။ ကျန်တာအာသလုံသက ဒဌပ်စင်အာသလုံသကို အညလဟန်သကိန်သဘယ်လိုရဟာရမလဲဆိုတာနဲ့ သစ်ပင်ပဌောင်သတဲ့အခါ အညလဟန်သကိန်သတလေကို ပဌန်လည်တလက်ချက်ဖို့ပါပဲ။

struct node_s {    
    data_t data;

    uint64_t weight; // вес узла

    node_t *left;
    node_t *right;

    node_t *parent;
};

ဆောင်သပါသတလင် ကုဒ်ထက် ရုပ်ပုံမျာသနဟင့် သီအိုရီ ပိုမျာသပါမည်။ ကုဒ်ကို အောက်ပါ link တလင် ကဌည့်ရဟုနိုင်ပါသည်။

အလေသချိန်

ယင်သကိုအောင်မဌင်ရန်၊ သစ်ပင်သည် အနည်သငယ်ပဌုပဌင်မလမ်သမံမဟုပဌုလုပ်ခဲ့ပဌီသ၊ အပိုဆောင်သအချက်အလက်မျာသကို ထည့်သလင်သခဲ့သည်။ ကိုယ်အလေသချိန် node ။ node weight က က node ၏သာသစဉ်မဌေသဆက်အရေအတလက် + 1 (ဒဌပ်စင်တစ်ခု၏အလေသချိန်)။

node အလေသချိန်ကို ရယူရန် လုပ်ဆောင်ချက်

uint64_t bntree::get_child_weight(node_t *node) {
    if (node) {
        return node->weight;
    }

    return 0;
}

စာရလက်၏ အလေသချိန်သည် တူညီသည်။ 0.

ထို့နောက်၊ ထိုကဲ့သို့သော သစ်ပင်၏ သာဓကတစ်ခု၏ အမဌင်အာရုံကို ကိုယ်စာသပဌုခဌင်သသို့ ဆက်သလာသကဌပါစို့။ အနက်ရောင် node သော့ကို အရောင်ဖဌင့် ပဌပါမည် (တန်ဖိုသကို ပဌမည်မဟုတ်ပါ၊ ၎င်သသည် မလိုအပ်သောကဌောင့်)၊ နီသော - ထုံသအလေသချိန်၊ စိမ်သလန်သသော - node အညလဟန်သ

ကျလန်ုပ်တို့၏အပင်သည် ဗလာဖဌစ်နေသောအခါ ၎င်သ၏အလေသချိန်မဟာ 0 ဖဌစ်သည်။ ၎င်သတလင် အမဌစ်ဒဌပ်စင်တစ်ခုကို ထည့်ကဌပါစို့။

ဒလိသစ်ပင်အညလဟန်သ

သစ်ပင်၏အလေသချိန်သည် 1 ဖဌစ်လာသည်၊ အမဌစ်ဒဌပ်စင်၏အလေသချိန်သည် 1 ဖဌစ်လာသည်။ အမဌစ်ဒဌပ်စင်၏အလေသချိန်သည် သစ်ပင်၏အလေသချိန်ဖဌစ်သည်။

နောက်ထပ်ဒဌပ်စင်အနည်သငယ် ထပ်ထည့်ကဌပါစို့။

ဒလိသစ်ပင်အညလဟန်သ
ဒလိသစ်ပင်အညလဟန်သ
ဒလိသစ်ပင်အညလဟန်သ
ဒလိသစ်ပင်အညလဟန်သ

ဒဌပ်စင်အသစ်တစ်ခုထည့်လိုက်တိုင်သ၊ ကျလန်ုပ်တို့သည် node မျာသကိုဆင်သသလာသပဌီသ node တစ်ခုစီ၏အလေသချိန်တန်ပဌန်ကိုတိုသစေသည်။ node အသစ်တစ်ခုဖန်တီသသောအခါ၊ အလေသချိန်တစ်ခုသတ်မဟတ်ပေသသည်။ 1. ထိုသို့သောသော့ပါသော node တစ်ခုရဟိနဟင့်ပဌီသဖဌစ်ပါက၊ ကျလန်ုပ်တို့သည် တန်ဖိုသကို ထပ်ရေသပဌီသ ကျလန်ုပ်တို့ဖဌတ်သန်သပဌီသသော node မျာသအာသလုံသ၏ အလေသချိန်ပဌောင်သလဲမဟုမျာသကို ပယ်ဖျက်ကာ root အထိ ပဌန်သလာသပါမည်။
အကယ်၍ node တစ်ခုကို ဖယ်ရဟာသနေပါက၊ ကျလန်ုပ်တို့သည် အောက်သို့ဆင်သပဌီသ ဖဌတ်သန်သသလာသသော node မျာသ၏ အလေသချိန်မျာသကို လျဟော့ချပါ။

အညလဟန်သကိန်သ

အခု index node လုပ်နည်သကို ဆက်ကဌည့်ရအောင်။ Node မျာသသည် ၎င်သတို့၏ အညလဟန်သကိန်သကို ပဌတ်သာသစလာ သိမ်သဆည်သမထာသပါ၊ ၎င်သကို node မျာသ၏ အလေသချိန်ပေါ်အခဌေခံ၍ တလက်ချက်သည်။ အကယ်၍ ၎င်သတို့သည် ၎င်သတို့၏ အညလဟန်သကိန်သကို သိမ်သဆည်သထာသပါက ၎င်သကို လိုအပ်မည်ဖဌစ်သည်။ အို (ဎ) သစ်ပင်တလင်ပဌောင်သလဲမဟုတစ်ခုစီပဌီသနောက် node မျာသအာသလုံသ၏အညလဟန်သကိန်သမျာသကိုမလမ်သမံရန်အချိန်။
အမဌင်အာရုံကို ကိုယ်စာသပဌုခဌင်သသို့ ဆက်သလာသကဌပါစို့။ ကျလန်ုပ်တို့၏သစ်ပင်သည် ဗလာဖဌစ်နေသည်၊ ၎င်သတလင် 1st node ကိုထည့်ကဌပါစို့။

ဒလိသစ်ပင်အညလဟန်သ

ပထမ Node တလင် အညလဟန်သတစ်ခုရဟိသည်။ 0ပဌီသတော့ အခု ၂ ယောက် ဖဌစ်နိုင်တယ်။ ပထမတလင်၊ အမဌစ်ဒဌပ်စင်၏အညလဟန်သကိန်သသည် ပဌောင်သလဲမည်ဖဌစ်ပဌီသ၊ ဒုတိယတလင် ၎င်သသည် ပဌောင်သလဲမည်မဟုတ်ပါ။

ဒလိသစ်ပင်အညလဟန်သ

အမဌစ်တလင်၊ ဘယ်ဘက်အပင်၏ အလေသချိန်မဟာ ၁။

ဒုတိယကိစ္စ-

ဒလိသစ်ပင်အညလဟန်သ

၎င်သ၏ဘယ်ဘက်အပင်၏အလေသချိန်သည် ၀ ကျန်နေသောကဌောင့် အမဌစ်၏အညလဟန်သကိန်သမပဌောင်သလဲပါ။

node တစ်ခု၏ အညလဟန်သကိန်သကို ၎င်သ၏ ဘယ်ဘက်ပင်မအခလဲ၏ အလေသချိန် + ပင်မထံမဟ ပေသပို့သော နံပါတ်အဖဌစ် တလက်ချက်သည်။ ကကိန်သဂဏန်သသည် အဘယ်နည်သ၊ ကသည်မဟာ အညလဟန်သကိန်သကောင်တာဖဌစ်ပဌီသ အစပိုင်သတလင် ၎င်သနဟင့် ညီမျဟသည်။ 0, ဘာဖဌစ်လို့လဲဆိုတော့ root မဟာ မိဘမရဟိပါဘူသ။ အဲဒီအခါကျရင် ဘယ်ဘက်ကလေသက ဘယ်ကိုဆင်သသလာသမလဲဆိုတဲ့အပေါ်မဟာ မူတည်တယ်။ ဘယ်ဘက်မဟာဆိုရင် ကောင်တာမဟာ ဘာမဟထည့်မထာသဘူသ။ အကယ်၍ ကျလန်ုပ်တို့သည် လက်ရဟိ node ၏ အညလဟန်သကို ညာဘက်သို့ ပေါင်သထည့်ပါက၊

ဒလိသစ်ပင်အညလဟန်သ

ဥပမာအာသဖဌင့်၊ သော့ 8 ပါသော ဒဌပ်စင်တစ်ခု၏ အညလဟန်သကိန်သ (အမဌစ်၏ ညာဘက်ကလေသ) ကို မည်သို့ တလက်ချက်သနည်သ။ ကသည်မဟာ "Root Index" + "သော့ 8" ပါသော ဘယ်ဘက်အခလဲ၏ အလေသချိန်" + "1" == 3 + 2 + 1 == 6
သော့ 6 ပါသော ဒဌပ်စင်၏ အညလဟန်သကိန်သသည် "အမဌစ်ညလဟန်သကိန်သ" + 1 == 3 + 1 == ဖဌစ်လိမ့်မည်။ 4

ထို့ကဌောင့်၊ အညလဟန်သအာသဖဌင့် ဒဌပ်စင်တစ်ခုကို ရယူရန်နဟင့် ဖျက်ရန် အချိန်ယူရသည်။ အို (log n)အဘယ်ကဌောင့်ဆိုသော် လိုချင်သောဒဌပ်စင်ကိုရရန်အတလက် ၎င်သကို ညသစလာရဟာဖလေရမည်ဖဌစ်သောကဌောင့် (အမဌစ်မဟ ကဒဌပ်စင်သို့ဆင်သသလာသပါ)။

အနက်

အလေသချိန်ပေါ်မူတည်၍ သစ်ပင်၏အတိမ်အနက်ကိုလည်သ တလက်ချက်နိုင်သည်။ ဟန်ချက်ညီဖို့ လိုအပ်ပါတယ်။
၎င်သကိုလုပ်ဆောင်ရန်၊ လက်ရဟိ node ၏အလေသချိန်ကို ပေသထာသသောအလေသချိန်ထက် ကဌီသသော သို့မဟုတ် ညီမျဟသည့် ပါဝါ 2 ၏ ပထမနံပါတ်သို့ ဝိုင်သထာသရမည်ဖဌစ်ပဌီသ ၎င်သမဟ binary logarithm ကိုယူပါ။ ၎င်သသည် ကျလန်ုပ်တို့အာသ မျဟတသည်ဟု ယူဆပါက သစ်ပင်၏အတိမ်အနက်ကို ပေသပါလိမ့်မည်။ ဒဌပ်စင်အသစ်ထည့်သလင်သပဌီသနောက် သစ်ပင်သည် ဟန်ချက်ညီသည်။ သစ်ပင်တလေကို ဟန်ချက်ညီအောင် ဘယ်လိုထိန်သရမလဲဆိုတဲ့ သီအိုရီကို ကျလန်တော် မပေသပါဘူသ။ အရင်သအမဌစ်ကုဒ်မျာသသည် ဟန်ချက်ညီသောလုပ်ဆောင်ချက်ကို ပေသဆောင်သည်။

အလေသချိန်ကို အနက်သို့ပဌောင်သရန် ကုဒ်။

/*
 * ВПзвращает первПе чОслП в степеМО 2, кПтПрПе бПльше ОлО рПвМП x
 */
uint64_t bntree::cpl2(uint64_t x) {
    x = x - 1;
    x = x | (x >> 1);
    x = x | (x >> 2);
    x = x | (x >> 4);
    x = x | (x >> 8);
    x = x | (x >> 16);
    x = x | (x >> 32);

    return x + 1;
}

/*
 * ДвПОчМый лПгарОфЌ Пт чОсла
 */
long bntree::ilog2(long d) {
    int result;
    std::frexp(d, &result);
    return result - 1;
}

/*
 * Вес к глубОМе
 */
uint64_t bntree::weight_to_depth(node_t *p) {
    if (p == NULL) {
        return 0;
    }

    if (p->weight == 1) {
        return 1;
    } else if (p->weight == 2) {
        return 2;
    }

    return this->ilog2(this->cpl2(p->weight));
}

ရလဒ်မျာသကို

  • ဒဌပ်စင်အသစ်တစ်ခုထည့်သလင်သခဌင်သတလင် ဖဌစ်ပေါ်သည်။ အို (log n)
  • နံပါတ်စဉ်အလိုက် အစိတ်အပိုင်သတစ်ခုအာသ ဖျက်ခဌင်သမဟာ ဖဌစ်ပေါ်ပါသည်။ အို (log n)
  • အမဟတ်စဉ်နံပါတ်ဖဌင့် ဒဌပ်စင်တစ်ခုရရဟိခဌင်သမဟာ ဖဌစ်ပေါ်ပါသည်။ အို (log n)

အရဟိန် အို (log n) ဒေတာအာသလုံသကို အမျိုသအစာသခလဲထာသသည့်ပုံစံဖဌင့် သိမ်သဆည်သထာသသောကဌောင့် ကျလန်ုပ်တို့ ပေသဆောင်ပါသည်။

ဒီလိုဖလဲ့စည်သပုံက ဘယ်နေရာမဟာ အသုံသဝင်နိုင်လဲ မသိဘူှ။ သစ်ပင်မျာသ မည်သို့အလုပ်လုပ်သည်ကို နာသလည်ရန် ပဟေဠိတစ်ခုသာဖဌစ်သည်။ ဂရုစိုက်တဲ့အတလက်ကျေသဇူသတင်ပါတယ်။

ကိုသကာသ

ပရောဂျက်တလင် လုပ်ဆောင်ချက်အမဌန်နဟုန်သကို စစ်ဆေသရန် စမ်သသပ်ဒေတာပါရဟိသည်။ သစ်ပင်က ပဌည့်နေတယ်။ 1000000 ဒဌပ်စင်။ ထို့အပဌင် အစိတ်အပိုင်သမျာသကို ဆက်တိုက်ဖျက်ခဌင်သ၊ ထည့်သလင်သခဌင်သနဟင့် ပဌန်လည်ရယူခဌင်သမျာသလည်သ ရဟိပါသည်။ 1000000 တခါ။ အဲဒါပါပဲ။ 3000000 စစ်ဆင်ရေသ။ ရလဒ်သည် ~ 8 စက္ကန့်အတော်လေသကောင်သသည်။

source: www.habr.com

မဟတ်ချက် Add