Nhảy chuyển đến

Ghép đôi đôi

Dẫn vào

Ghép đôi đôi là một cái duy trì cắm vào, tuần tra / xóa bỏ nhỏ nhất giá trị, xác nhập, sửa chữa nguyên tố chờ thao tác số liệu kết cấu, là một loại nhưng cũng đôi. Có tốc độ mau cùng kết cấu đơn giản ưu thế, nhưng bởi vì này làm cơ sở với thế năng phân tích đều quán phức tạp độ, vô pháp nhưng kéo dài hóa.

Định nghĩa

Ghép đôi đôi là một cây thỏa mãn đôi tính chất mang quyền nhiều xoa thụ ( như sau đồ ), tức mỗi cái tiết điểm quyền giá trị đều nhỏ hơn hoặc tương đương hắn sở hữu nhi tử ( lấy tiểu căn đôi vì lệ, như trên ).

Thông thường chúng ta sử dụng nhi tử - huynh đệ tỏ vẻ pháp chứa đựng một cái ghép đôi đôi ( như sau đồ ), một cái tiết điểm sở hữu nhi tử tiết điểm hình thành một cái đơn hướng liên biểu. Mỗi cái tiết điểm chứa đựng cái thứ nhất nhi tử kim đồng hồ, tức liên biểu đầu tiết điểm; cùng hắn hữu huynh đệ kim đồng hồ.

Phương thức này dễ bề thực hiện ghép đôi đôi, cũng đem phương tiện phức tạp độ phân tích.

1
2
3
4
5
6
structNode{
Tv;// T vì quyền giá trị loại hình
Node*child,*sibling;
// child chỉ hướng nên tiết điểm cái thứ nhất nhi tử, sibling chỉ hướng nên tiết điểm tiếp theo cái huynh đệ.
// nếu nên tiết điểm không có nhi tử / sau huynh đệ tắc kim đồng hồ chỉ hướng nullptr.
};

Từ định nghĩa có thể phát hiện, cùng mặt khác thường thấy đôi kết cấu so sánh với, ghép đôi đôi không giữ gìn bất luận cái gì thêm vào thụ lớn nhỏ, chiều sâu, xếp hạng chờ tin tức ( nhị xoa đôi cũng không giữ gìn thêm vào tin tức, nhưng nó là thông qua duy trì một cái nghiêm khắc hoàn toàn nhị xoa thụ kết cấu tới bảo đảm thao tác phức tạp độ ), thả bất luận cái gì một cái thỏa mãn đôi tính chất thụ đều là một cái hợp pháp ghép đôi đôi, như vậy đơn giản lại độ cao linh hoạt số liệu kết cấu đặt ghép đôi đôi ở thực tiễn trung ưu tú hiệu suất cơ sở; làm đối lập, Fibonacci đôi không xong hằng số chính là bởi vì nó yêu cầu giữ gìn rất nhiều thêm vào tin tức.

Ghép đôi đôi thông qua một bộ tỉ mỉ thiết kế thao tác trình tự tới bảo đảm nó tổng phức tạp độ, nguyên luận văn1Đem này xưng là “Một loại tự điều chỉnh đôi ( Self Adjusting Heap )”. Ở phương diện này cùng Splay thụ ( ở nguyên luận văn trung bị gọi “Self Adjusting Binary Tree” ) rất có tương tự chỗ.

Quá trình

Tuần tra nhỏ nhất giá trị

Từ ghép đôi đôi định nghĩa nhưng nhìn ra, ghép đôi đôi căn tiết điểm quyền giá trị nhất định nhỏ nhất, trực tiếp phản hồi căn tiết điểm là được.

Xác nhập

Xác nhập hai cái ghép đôi đôi thao tác rất đơn giản, đầu tiên lệnh hai cái căn tiết điểm nhỏ lại một cái vì tân căn tiết điểm, sau đó đem trọng đại căn tiết điểm làm nó nhi tử cắm vào đi vào. ( thấy hạ đồ )

Yêu cầu chú ý chính là, một cái tiết điểm nhi tử liên biểu là ấn cắm vào thời gian bài tự, tức nhất bên phải tiết điểm sớm nhất trở thành phụ tiết điểm nhi tử, nhất bên trái tiết điểm gần nhất trở thành phụ tiết điểm nhi tử.

Thực hiện
1
2
3
4
5
6
7
8
9
10
Node*meld(Node*x,Node*y){
// nếu có một cái vì không tắc trực tiếp phản hồi một cái khác
if(x==nullptr)returny;
if(y==nullptr)returnx;
if(x->v>y->v)std::swap(x,y);// swap sau x vì quyền giá trị tiểu nhân đôi, y vì quyền giá trị đại đôi
// đem y thiết vì x nhi tử
y->sibling=x->child;
x->child=y;
returnx;// tân căn tiết điểm vì x
}

Cắm vào

Xác nhập đều có, cắm vào liền trực tiếp đem tân nguyên tố coi là một cái tân ghép đôi đôi cùng nguyên đôi xác nhập là được.

Xóa bỏ nhỏ nhất giá trị

Đầu tiên muốn đề cập một chút là, câu trên mấy cái thao tác đều thập phần lười biếng, hoàn toàn không có đối số liệu kết cấu tiến hành giữ gìn, cho nên chúng ta yêu cầu tiểu tâm thiết kế xóa bỏ nhỏ nhất giá trị thao tác, tới bảo đảm tổng phức tạp độ không ra vấn đề.

Căn tiết điểm tức vì nhỏ nhất giá trị, cho nên muốn xóa bỏ chính là căn tiết điểm. Suy xét lấy xuống căn tiết điểm lúc sau sẽ phát sinh cái gì: Căn tiết điểm nguyên lai sở hữu nhi tử cấu thành một mảnh rừng rậm; mà ghép đôi đôi hẳn là một thân cây, cho nên chúng ta yêu cầu thông qua nào đó trình tự đem này đó nhi tử toàn bộ xác nhập lên.

Một cái thực tự nhiên ý tưởng là sử dụngmeldHàm số đem mấy đứa con trai từ tả đến hữu từng cái cũng ở bên nhau, làm như vậy chính xác tính là hiển nhiên, nhưng là sẽ dẫn tới đơn thứ thao tác phức tạp độ thoái hóa đến.

Vì bảo đảm tổng đều quán phức tạp độ, yêu cầu sử dụng một cái “Hai bước đi” xác nhập phương pháp:

  1. Đem mấy đứa con trai hai hai xứng thành một đôi, dùngmeldThao tác đem bị xứng thành cùng đối hai cái nhi tử xác nhập đến cùng nhau ( thấy hạ đồ 1 ),
  2. Đem tân sinh ra đôiTừ hữu hướng tả( tức lão nhi tử đến tân nhi tử phương hướng ) từng cái xác nhập ở bên nhau ( thấy hạ đồ 2 ).

Trước thực hiện một cái phụ trợ hàm sốmerges,Tác dụng là xác nhập một cái tiết điểm sở hữu huynh đệ.

Thực hiện
1
2
3
4
5
6
7
8
Node*merges(Node*x){
if(x==nullptr||x->sibling==nullptr)
returnx;// nếu nên thụ vì không hoặc hắn không có tiếp theo cái huynh đệ, liền không cần xác nhập, return.
Node*y=x->sibling;// y vì x tiếp theo cái huynh đệ
Node*c=y->sibling;// c là lại tiếp theo cái huynh đệ
x->sibling=y->sibling=nullptr;// chia rẽ
returnmeld(merges(c),meld(x,y));// trung tâm bộ phận
}

Cuối cùng một câu là nên hàm số trung tâm, những lời này phân tam bộ phận:

  1. meld(x,y)“Ghép đôi” x cùng y.
  2. merges(c)Đệ quy xác nhập c cùng hắn các huynh đệ.
  3. Đem mặt trên 2 cái thao tác sinh ra 2 cái tân thụ xác nhập.

Yêu cầu chú ý tới chính là, câu trên nhắc tới bước thứ hai khi xác nhập phương hướng là có yêu cầu ( từ hữu hướng tả xác nhập ), nên đệ quy hàm số thực hiện đã bảo đảm cái này trình tự, nếu người đọc yêu cầu tự hành thực hiện thay đổi phiên bản nói làm ơn tất chú ý bảo đảm nên trình tự, nếu không phức tạp độ đem mất đi bảo đảm.

mergesHàm số,delete-minThao tác liền hiển nhiên.

Thực hiện
1
2
3
4
5
Node*delete_min(Node*x){
Node*t=merges(x->child);
deletex;// nếu yêu cầu nội tồn thu về
returnt;
}

Giảm nhỏ một cái nguyên tố giá trị

Muốn thực hiện cái này thao tác, yêu cầu cấp tiết điểm tăng thêm một cái “Phụ” kim đồng hồ, đương tiết điểm có Tả huynh đệ khi, này chỉ hướng Tả huynh đệ mà phi thực tế phụ tiết điểm; nếu không, chỉ hướng này phụ tiết điểm.

Đầu tiên tiết điểm định nghĩa sửa chữa vì:

Thực hiện
1
2
3
4
5
6
structNode{
LLv;
intid;
Node*child,*sibling;
Node*father;// tân tăng: Phụ kim đồng hồ, nếu nên tiết điểm làm gốc tiết điểm tắc chỉ hướng không tiết điểm nullptr
};

meldThao tác sửa chữa vì:

Thực hiện
1
2
3
4
5
6
7
8
9
10
11
12
Node*meld(Node*x,Node*y){
if(x==nullptr)returny;
if(y==nullptr)returnx;
if(x->v>y->v)std::swap(x,y);
if(x->child!=nullptr){// tân tăng: Giữ gìn phụ kim đồng hồ
x->child->father=y;
}
y->sibling=x->child;
y->father=x;// tân tăng: Giữ gìn phụ kim đồng hồ
x->child=y;
returnx;
}

mergesThao tác sửa chữa vì:

Thực hiện
1
2
3
4
5
6
7
8
9
Node*merges(Node*x){
if(x==nullptr)returnnullptr;
x->father=nullptr;// tân tăng: Giữ gìn phụ kim đồng hồ
if(x->sibling==nullptr)returnx;
Node*y=x->sibling,*c=y->sibling;
y->father=nullptr;// tân tăng: Giữ gìn phụ kim đồng hồ
x->sibling=y->sibling=nullptr;
returnmeld(merges(c),meld(x,y));
}

Hiện tại chúng ta tới suy xét như thế nào thực hiệndecrease-keyThao tác.
Đầu tiên chúng ta phát hiện, khi chúng ta giảm bớt tiết điểmxQuyền giá trị lúc sau, lấyxLàm gốc tử thụ vẫn cứ thỏa mãn ghép đôi đôi tính chất, nhưngxPhụ thân cùngxChi gian khả năng không hề thỏa mãn đôi tính chất.
Bởi vậy chúng ta đem chỉnh cây lấyxLàm gốc tử thụ mổ ra tới, hiện tại hai cây đều phù hợp ghép đôi đôi tính chất, sau đó đem bọn họ xác nhập lên, liền hoàn thành toàn bộ thao tác.

Thực hiện
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// root vì đôi căn, x vì muốn thao tác tiết điểm, v vì tân quyền giá trị, thuyên chuyển khi cần bảo đảm v v
// phản hồi giá trị vì tân căn tiết điểm
Node*decrease_key(Node*root,Node*x,LLv){
x->v=v;// đổi mới quyền giá trị
if(x==root)returnx;// nếu x làm gốc, tắc trực tiếp phản hồi
// đem x từ fa tử tiết điểm trúng mổ đi ra ngoài, nơi này muốn phân x vị trí thảo luận một chút.
if(x->father->child==x){
x->father->child=x->sibling;
}else{
x->father->sibling=x->sibling;
}
if(x->sibling!=nullptr){
x->sibling->father=x->father;
}
x->sibling=nullptr;
x->father=nullptr;
returnmeld(root,x);// một lần nữa xác nhập x cùng căn tiết điểm
}

Phức tạp độ phân tích

Ghép đôi đôi kết cấu cùng thực hiện đơn giản, nhưng thời gian phức tạp độ phân tích cũng không dễ dàng.

Nguyên luận văn1Chỉ đem phức tạp độ phân tích đếnmeldCùngdelete-minThao tác đều vì đều quán,Nhưng đưa ra phỏng đoán cho rằng này các thao tác đều có cùng Fibonacci đôi tương đồng phức tạp độ.

Tiếc nuối chính là, kế tiếp phát hiện, không giữ gìn thêm vào tin tức ghép đôi đôi, ở riêng thao tác danh sách hạ,decrease-keyThao tác đều quán phức tạp độ hạ giới ít nhất vì2.

Trước mắt đối phức tạp độ thượng giới tương đối tốt phỏng chừng có, Iaconomeld,decrease-key3;PettiemeldCùngdecrease-key4.Yêu cầu chú ý chính là, trước thuật phức tạp độ đều vì đều quán phức tạp độ, bởi vậy không thể đối các kết quả phân biệt lấy nhỏ nhất giá trị.

Tham khảo văn hiến