рдореИрдВрдиреЗ O (1) рдХреЗ рд▓рд┐рдП рджреЛрдЧреБрдиреА рд▓рд┐рдВрдХ рдХреА рдЧрдИ рд╕реВрдЪреА рдкрд░ рдмрд╣рд╕ рдХреИрд╕реЗ рдХреА


рдПрдХ рдмрд╛рд░ рдЬрдм рдореИрдВрдиреЗ рдЧрд▓рддреА рд╕реЗ рдЕрдкрдиреЗ рд╕рд╣рдХрд░реНрдореА рдХреЛ C ++ рдореЗрдВ рджреЛрдЧреБрдиреА рд▓рд┐рдВрдХреНрдб рд╕реВрдЪреА рдХреЗ рд╡рд┐рд╕реНрддрд╛рд░ рдХреЗ рдХрдирд┐рд╖реНрда рдХрд╛рд░реНрдп рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рджреЗрдЦрд╛ред рдФрд░ рдЙрд╕ рдкрд▓ рдореБрдЭреЗ рдпрд╣ рдЕрдЬреАрдм рдирд╣реАрдВ рд▓рдЧрд╛ рдХрд┐ рд╡рд╣ рдПрдХ рд╕реАрд╕рд╛ рдерд╛ рдФрд░ рд▓рдВрдмреЗ рд╕рдордп рд╕реЗ рдЗрд╕ рдмрд╛рдд рдХреЛ рдкрдЫрд╛рдбрд╝рддрд╛ рд░рд╣рд╛, рд▓реЗрдХрд┐рди рдлреИрд╕рд▓рд╛ рдЦреБрдж рд╣реА рд╣реБрдЖред

рдЕрдзрд┐рдХ рд╕рд╣реА рдорд╛рдпрдиреЗ рдореЗрдВ, рдРрд╕рд╛ рдирд╣реАрдВ рд╣реИред

рд╕рдорд╛рдзрд╛рди рдорд╛рдирдХ рдерд╛: рдкреНрд░рддреНрдпреЗрдХ рдиреЛрдб рдореЗрдВ рд╕рдВрдХреЗрдд рдХреЗ рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрди рдХреЗ рд╕рд╛рде рдПрдХ рд╣реА рд░реИрдЦрд┐рдХ рдорд╛рд░реНрдЧ, рдЬреИрд╕рд╛ рдХрд┐ рд╕реИрдХрдбрд╝реЛрдВ рд╣рдЬрд╛рд░реЛрдВ рд▓реЛрдЧреЛрдВ рдиреЗ рдкрд╣рд▓реЗ рд▓рд┐рдЦрд╛ рдерд╛ред рдХреБрдЫ рднреА рдЕрд╕рд╛рдорд╛рдиреНрдп рдпрд╛ рдЬрдЯрд┐рд▓ рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдЬрдм рдореИрдВрдиреЗ рдЙрд╕рдХреА рдУрд░ рджреЗрдЦрд╛, рддреЛ рдореЗрд░реЗ рджреЛ рд╕рд╡рд╛рд▓ рдереЗ:

  • рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рд╣рд░ рдХреЛрдИ рдЗрд╕ рддрд░рд╣ рд╕реЗ рд╕рдорд╕реНрдпрд╛ рдХрд╛ рд╕рдорд╛рдзрд╛рди рдХреНрдпреЛрдВ рдХрд░рддрд╛ рд╣реИ?
  • рдХреНрдпрд╛ рдмреЗрд╣рддрд░ рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реИ?

рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ рдореИрдЯрд░рд┐рдпрд▓ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВред рдпрджрд┐ рдЖрдк рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рджреЛрд╣рд░реА рд▓рд┐рдВрдХ рдХреА рдЧрдИ рд╕реВрдЪреА рдХреНрдпрд╛ рд╣реИ, рддреЛ рдЖрдк рдЕрдЧрд▓реЗ рдкреИрд░рд╛рдЧреНрд░рд╛рдл рдХреЛ рдЫреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВред

рдПрдХ рдбрдмрд▓ рд▓рд┐рдВрдХ рдХреА рдЧрдИ рд╕реВрдЪреА рдмреБрдирд┐рдпрд╛рджреА рдбреЗрдЯрд╛ рд╕рдВрд░рдЪрдирд╛рдУрдВ рдореЗрдВ рд╕реЗ рдПрдХ рд╣реИ, рдЗрд╕рдХреЗ рд╕рд╛рде рдкрд░рд┐рдЪрд┐рдд рдЖрдорддреМрд░ рдкрд░ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдкреНрд░рд╢рд┐рдХреНрд╖рдг рдХреЗ рд╢реБрд░реБрдЖрддреА рдЪрд░рдгреЛрдВ рдореЗрдВ рд╣реЛрддрд╛ рд╣реИред рдпрд╣ рдиреЛрдбреНрд╕ рдХреЗ рдЕрдиреБрдХреНрд░рдо рд╕реЗ рдмрдирд╛ рдПрдХ рд╕рдВрдЧреНрд░рд╣ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдХреБрдЫ рдбреЗрдЯрд╛ рд╣реЛрддреЗ рд╣реИрдВ рдФрд░ рдПрдХ рджреВрд╕рд░реЗ рдХреЗ рд╕рд╛рде рдЬреЛрдбрд╝реЗ рдЬрд╛рддреЗ рд╣реИрдВ - рдЕрд░реНрдерд╛рдд, рдпрджрд┐ рдиреЛрдб A рдХреЛ рдЕрдЧрд▓реЗ рдХреЗ рд░реВрдк рдореЗрдВ рд╕рдВрджрд░реНрднрд┐рдд рдХрд░рддрд╛ рд╣реИ, рддреЛ рдиреЛрдб B рдкрд┐рдЫрд▓реЗ рдХреЗ рд░реВрдк рдореЗрдВ A рдХреЛ рд╕рдВрджрд░реНрднрд┐рдд рдХрд░рддрд╛ рд╣реИред рд╡реНрдпрд╡рд╣рд╛рд░ рдореЗрдВ, рдЖрдкрдХреЛ рдпрд╣ рд╕рдВрд░рдЪрдирд╛ рдХрдВрдЯреЗрдирд░реЛрдВ рдореЗрдВ рдорд┐рд▓ рд╕рдХрддреА рд╣реИ рдЬреИрд╕реЗ рдХрд┐ std :: C ++ рдореЗрдВ рд╕реВрдЪреА, C # рдореЗрдВ рд▓рд┐рдВрдХреНрдбрд▓рд┐рд╕реНрдЯ, рдФрд░ рдЬрд╛рд╡рд╛ред рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рд╕рдВрднрд╛рд╡рдирд╛ рд╣реИ, рдЖрдкрдХреЛ рдЗрд╕рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХрд┐рд╕реА рдЕрдиреНрдп рднрд╛рд╖рд╛ рдХреЗ рдорд╛рдирдХ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдореЗрдВ рдорд┐рд▓реЗрдЧрд╛ред

рдкрд╛рда рдореЗрдВ рдЖрдЧреЗ, рдХрдореНрдкреНрдпреВрдЯреЗрд╢рдирд▓ рдЬрдЯрд┐рд▓рддрд╛ рдХреЗ рд╕рдВрдХреЗрдд рдХреЗ рд╕рд╛рде рдРрд╕реА рд╕реВрдЪреА рдкрд░ рдореВрд▓ рдЧреБрдгреЛрдВ рдФрд░ рд╕рдВрдЪрд╛рд▓рди рдХрд╛ рд╡рд░реНрдгрди рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред

рдЕрдм рдкрд╣рд▓реЗ рджрд┐рдП рдЧрдП рдкреНрд░рд╢реНрдиреЛрдВ рдкрд░ рд╡рд╛рдкрд╕ рдЬрд╛рдПрдВред

рдореИрдВрдиреЗ рд╕рдорд╕реНрдпрд╛ рдХреА рд╕реНрдерд┐рддрд┐ рдкрд░ рдзреНрдпрд╛рди рджрд┐рдпрд╛ рдФрд░ рдкрд╣рд▓реЗ рдХрд╛ рдЬрд╡рд╛рдм рджреЗрдЦрд╛ред рдпрд╣рд╛рдБ рдпрд╣ рд╣реИ:

struct node
{
    int data;
    node* next;
    node* prev;
};

. ? :



. тАХ , . , , .

EBDCA. тАХ , . .

, , , , O(1), . , . , .

. , , :

  • , .
  • . , .
  • . , .
  • .
  • (/ //) .
  • / , .
  • тАУ . , .

тАХ . тАХ / . , - . , . , - , , , - .

┬л? -?┬╗ тАХ : ┬л !┬╗

, , - - . , : , . Data-Oriented Design: , , , . DOD. . , , .

, , . . .

, -, . , ┬л┬╗ . :

  • / , .
  • - , . -.



, . , . , - O(1), .

тАХ (SoA) (AoS), . :



? :

тАХ . data, prev/next.
/ -.

, тАХ , prev next . - . .

, ?

ACDBE. EBDCA, :



! , , , , .

, prev next , first last , , :

prev <-> next
last <-> first

, . . . - , - .

, , :

template <class T, size_t Cap>
struct doubly_linked_list
{
    struct node { size_t index; };

    // API      

    T& get(node n) { return data_[n.index]; }
    const T& get(node n) const { return data_[n.index]; }

    node first() const { return { first_ }; }
    node last() const { return { last_ }; }

    node next(node n) const { return { next_[n.index] }; }
    node prev(node n) const { return { prev_[n.index] }; }

    bool is_valid(node n) const { return n.index < length_; }

    //          

    node add(T v)
    {
        auto index = length_;
        if (length_ == 0) first_ = 0;
        data_[index] = v;
        next_[index] = INVALID_INDEX;
        prev_[index] = last_;
        next_[last_] = index;
        last_ = index;
        length_++;
        return { index };
    }

    node insert_before(T v, node n)
    {
        auto index = length_;
        data_[index] = v;
        next_[index] = n.index;
        auto prev = prev_[index] = prev_[n.index];
        prev_[n.index] = index;
        next_[prev] = index;
        length_++;
        if (n.index == first_) first_ = index;
        return { index };
    }

    // тАж    ,          ,
    //      ┬л┬╗   .     add/insert_before -
    //   length_     ┬л┬╗.

    //    тАУ ,      :

    void reverse()
    {
            std::swap(first_, last_);
            std::swap(next_, prev_);
    }

private:
    static constexpr size_t INVALID_INDEX = SIZE_T_MAX;

    T data_[Cap];
    size_t indirection_[Cap * 2];
    size_t *next_ = indirection_;
    size_t *prev_ = indirection_ + Cap;
    size_t first_ = INVALID_INDEX;
    size_t last_ = INVALID_INDEX;
    size_t length_ = 0;
};

:

auto list = doubly_linked_list<int, 10>();
auto pos = list.add(0);
for (int i = 0; i < 5; ++i) pos = list.insert_before(i + 1, pos);

std::cout << "list";
for (auto n = list.first(); list.is_valid(n); n = list.next(n))
    std::cout << list.get(n) << " ";

// > list 5 4 3 2 1 0

list.reverse();
std::cout << std::endl << "reversed";
for (auto n = list.first(); list.is_valid(n); n = list.next(n))
    std::cout << list.get(n) << " ";

// > reversed 0 1 2 3 4 5

, , AoS . , : - , .

, . , - - тАХ , cache-friendly DCEL, . , .

:

. . . тАХ , . , , , тАУ , .

Data-Oriented Design: , . . тАУ , . , .

. - .

Source: https://habr.com/ru/post/hi480462/


All Articles