Một cây có thể đi qua mà không cần đệ quy, xếp chồng hoặc xếp hàng và chỉ một số ít con trỏ không?


14

Nửa thập kỷ trước, tôi đang ngồi trong một lớp cấu trúc dữ liệu nơi giáo sư cung cấp tín dụng bổ sung nếu bất kỳ ai cũng có thể đi qua một cây mà không sử dụng đệ quy, ngăn xếp, xếp hàng, v.v. (hoặc bất kỳ cấu trúc dữ liệu tương tự nào khác) và chỉ một vài con trỏ. Tôi đã đưa ra những gì tôi nghĩ là một câu trả lời rõ ràng cho câu hỏi đó cuối cùng đã được giáo sư chấp nhận. Tôi đang ngồi trong một lớp toán rời rạc với một giáo sư khác trong cùng khoa - và anh ta khẳng định rằng không thể đi ngang qua một cái cây mà không có đệ quy, xếp chồng, xếp hàng, v.v., và giải pháp của tôi không hợp lệ.

Vì vậy, nó là có thể, hoặc không thể? Tại sao hay tại sao không?

Chỉnh sửa: Để thêm một số làm rõ, tôi đã triển khai điều này trên cây nhị phân có ba phần tử - dữ liệu được lưu trữ ở mỗi nút và con trỏ tới hai con. Giải pháp của tôi có thể được mở rộng cho các cây n-ary chỉ với một vài thay đổi.

Giáo viên cấu trúc dữ liệu của tôi đã không đặt bất kỳ ràng buộc nào đối với việc làm biến đổi cây và thực sự sau đó tôi phát hiện ra rằng giải pháp của riêng anh ta là sử dụng các con trỏ con trỏ để hướng lên cây trên đường đi xuống. Giáo sư toán học rời rạc của tôi cho biết bất kỳ sự đột biến nào của cây có nghĩa là nó không còn là cây theo định nghĩa toán học của cây, định nghĩa của ông cũng sẽ loại trừ bất kỳ con trỏ nào đến cha mẹ - phù hợp với trường hợp tôi đã giải quyết nó ở trên.


3
Bạn cần chỉ định các ràng buộc. Tôi có được phép đột biến cây không? Cây đại diện như thế nào? (Chẳng hạn, mỗi nút có một con trỏ cha mẹ đến cha của nó không?) Câu trả lời sẽ phụ thuộc vào các ràng buộc cụ thể; mà không chỉ định những hạn chế đó, đây không phải là một vấn đề được đặt ra.
DW

2
Tôi đoán sự chống đối mà các giáo sư thực sự muốn bày tỏ là "với không gian bổ sung ". Nhưng giải pháp của bạn là gì? Ôi(1)
Raphael

Câu trả lời:


17

Rất nhiều nghiên cứu trong lĩnh vực này đã được xây dựng mái vòm, được thúc đẩy bởi phương pháp "vượt qua" các cây và cấu trúc danh sách chung trong bối cảnh thu gom rác.

Cây nhị phân luồng là một đại diện thích nghi của cây nhị phân trong đó một số con trỏ nil được sử dụng để liên kết với các nút kế tiếp trong cây. Thông tin bổ sung này có thể được sử dụng để đi qua một cây mà không có ngăn xếp. Tuy nhiên, cần thêm một bit cho mỗi nút để phân biệt các luồng với các con trỏ con. Wikipedia: Tree_traversal

Theo như tôi biết, cây nhị phân được triển khai bằng cách sử dụng các con trỏ theo kiểu thông thường (con trỏ trái và phải trên mỗi nút) có thể được duyệt qua phương thức của các luồng, trong một phương thức được gán cho Morris . Các con trỏ NIL tạm thời được sử dụng lại để luồn một đường dẫn trở lại thư mục gốc. Phần thông minh là trong quá trình truyền tải, người ta có thể phân biệt các cạnh ban đầu với các liên kết luồng tạm thời, bằng cách sử dụng cách chúng tạo thành các chu kỳ trong cây).

Phần tốt: không có cấu trúc dữ liệu bổ sung. Phần xấu: hơi gian lận, ngăn xếp bên trong cây một cách thông minh. Rất thông minh.

Một bằng chứng về ngăn xếp ẩn được hiển thị trong P. Mateti và R. Manghirmalani: Thuật toán chuyển đổi cây của Morris được xem xét lại DOI: 10.1016 / 0167-6423 (88) 90063-9

JM Morris: Đi qua cây nhị phân đơn giản và rẻ tiền. IPL 9 (1979) 197-200 DOI: 10.1016 / 0020-0190 (79) 90068-1

Sau đó, cũng có quét Lindstrom . Phương pháp này "xoay" ba con trỏ liên quan đến mỗi nút (cha và hai con). Nếu bạn muốn thực hiện bất kỳ thuật toán đặt hàng trước hoặc đặt hàng sau phong nha, bạn cần thêm bit cho mỗi nút. Nếu bạn chỉ muốn truy cập tất cả các nút (ba lần, nhưng bạn không bao giờ biết chuyến thăm nào bạn thực hiện) thì có thể được thực hiện mà không cần các bit.

G. Lindstrom: Quét các cấu trúc danh sách mà không có ngăn xếp hoặc bit thẻ. IPL 2 (1973) 47-51. DOI: 10.1016 / 0020-0190 (73) 90012-4

Có lẽ cách đơn giản nhất là một phương pháp của Robson . Ở đây ngăn xếp cần thiết cho thuật toán cổ điển được luồn qua các lá.

JM Robson: Một thuật toán cải tiến để duyệt qua các cây nhị phân không có ngăn xếp phụ IPL 1 (1973) 149-152. 10.1016 / 0020-0190 (73) 90018-5

IPL = Thư xử lý thông tin


Tôi cũng thích giải pháp này, mặc dù không có gì tôi có thể nghĩ ra trong năm đầu tiên tham gia lớp học khoa học máy tính. Vâng, có lẽ gian lận theo quy tắc của giáo sư của tôi.
NL - Xin lỗi đến

2
Bạn có thể cung cấp liên kết / tài liệu tham khảo cho các chiến lược?
Raphael

1
Phần tồi tệ thực sự với phương pháp đó là bạn không thể có nhiều hơn một lần đi qua bất cứ lúc nào.
Gilles 'SO- ngừng trở nên xấu xa'

6

v


Điều này tương tự như giải pháp mà giáo sư cấu trúc dữ liệu đã đề xuất vấn đề được sử dụng để giải quyết nó. Giáo sư toán học rời rạc phản đối rằng "điều này đã trở thành một biểu đồ chứ không phải là một cái cây" nếu có con trỏ quay lại với cha mẹ.
NL - Xin lỗi đến

@NathanLiddle: Điều đó phụ thuộc vào định nghĩa cây được sử dụng (mà bạn không đưa ra). Trong "thế giới thực", đại diện cho cây của Yuval là hợp lý ngay cả khi lý thuyết đồ thị sẽ nói những điều anh ta định nghĩa không phải là cây, tất nhiên.
Raphael

@Raphael Vâng, và nó đáp ứng yêu cầu của giáo sư ban đầu, vì vậy đó là một câu trả lời chấp nhận được với tôi.
NL - Xin lỗi đến

0

Giải pháp của tôi là một giao dịch đầu tiên bằng cách sử dụng các vòng lặp lồng nhau để vũ phu ép cây. Điều này không hiệu quả bằng bất kỳ phương tiện nào, và thực sự là một cấu trúc dữ liệu đệ quy như một cái cây đang cầu xin một giao thức đệ quy, nhưng câu hỏi không phải là liệu một cây có thể đi qua một cách hiệu quả hay không, là liệu nó có khả thi hay không.

Pseudocode:
root = pointer root 
depth = integer 0
finished = bool false
//If we n-ary tree also track how many children have been found 
//on the node with the most children for the purposes of this psuedocode 
//we'll assume a binary tree and insert a magic number of 2 so that we 
//can use bitwise operators instead of integer division 
while(!finished)
    ++depth
    treePosition = pointer root
    finished = true;
    for i := 0..2**depth
        for j := 0..depth
            if (i & j) //bitwise operator explained below
                // if right child doesn't exist break the loop
                treePosition = treePosition.rightChild
            else
                // if left child doesn't exist break the loop
                treePosition = treePosition.leftChild
        if j has any children
            finished = false
            do anything else you want when visiting the node

Đối với một vài cấp độ đầu tiên, nó sẽ trông như thế này, như bạn có thể thấy, toán tử bitwise trong mã giả chỉ đơn giản quyết định rẽ trái hoặc phải trên cây nhị phân:

2**1       0               1
2**2   00      01      10      11
2**3 000 001 010 011 100 101 110 111

Đối với n-ary, bạn sẽ lấy i% (maxChildren ** j) / j để xác định đường dẫn nào sẽ đi giữa 0 và maxChildren.

Tại mỗi nút trên n-ary, bạn cũng cần kiểm tra xem số lượng con có lớn hơn maxChildren hay không và cập nhật nó một cách thích hợp.


Nếu bạn muốn sử dụng nhiều hơn nhị phân, bạn sẽ cần thay thế ma thuật số 2 bằng một biến được tăng lên để phù hợp với số con tối đa mà nó nhìn thấy, và thay vì các toán tử bit, bạn sẽ cần chia cho cùng một biến được tăng lên sức mạnh của độ sâu của cây nơi bạn đã ở.
NL - Xin lỗi đến

Ôi(1)Ôi(lgn)Ôi(1)Ôi(n)Ôi(1)không gian bổ sung "). Chẳng hạn, bạn sẽ làm gì nếu depthvượt quá chiều rộng int?
DW

DW, giáo sư đặt ra vấn đề đã không đặt ra ràng buộc đó cho vấn đề, và điều khiến tôi bận tâm rất nhiều về cuộc thảo luận của tôi với giáo sư toán học rời rạc là ông KHÔNG BAO GIỜ thừa nhận rằng thậm chí có thể đi ngang qua một cái cây mà không cần đệ quy, xếp chồng, hoặc xếp hàng, bất cứ giá nào. Điều duy nhất mà giải pháp của tôi chứng minh là có thể làm bất cứ điều gì lặp đi lặp lại có thể được thực hiện theo cách đệ quy, ngay cả khi bạn xóa các tùy chọn cho ngăn xếp, xếp hàng, v.v.
NL - Xin lỗi đến Monica

Có một điều để nói là không thể giải quyết được nếu không có không gian bổ sung O (1), việc khai báo vấn đề không thể giải quyết được mà không cần đệ quy, xếp chồng hoặc xếp hàng là một điều khác. Và thực tế, sau khi nhìn thấy mã của tôi, giáo sư toán học rời rạc vẫn không thừa nhận điểm vì ông nói "i" trong vòng lặp đầu tiên đã thay thế cho một hàng đợi. Làm thế nào mà khó tính?
NL - Xin lỗi đến

1
@NathanLiddle, kiểm tra lại. Số nguyên của bạn idepthbit rộng. Nếu depthΘ(n) (có thể là, trong những cây không cân bằng), thì bạn cần Θ(n)không gian để lưu trữ số nguyên i, vì vậy giải pháp cần nhiều hơnÔi(1)không gian bổ sung.
DW
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.