2010-10-14 26 views
6

Tôi đã đọc một số bài viết khác ở đây trông tương tự, nhưng không hoàn toàn trả lời được sự cố của tôi. Tôi đã được đưa ra một câu hỏi cho một nhiệm vụ gán tất cả các nút trong một cây nhị phân độ sâu tương ứng của nó. Tôi không thể hiểu được.Chỉ định độ sâu cho mỗi nút

Để tham khảo này là mã của tôi:

struct treeNode { 
    int item; 
    int depth; 
    treeNode *left; 
    treeNode *right; 
}; 
typedef treeNode *Tree; 

int assignDepth(Tree &T, int depth) 
{ 
    if(T!=NULL) 
    { 
     depth = assignDepth(T->left, depth++); 
     T->depth = depth; 
     depth = assignDepth(T->right, depth++); 
    } 
    else //leaf 
     return depth--; 
} 

Tôi đã cố gắng chạy nó thông qua với bút và giấy và nó trông OK, nhưng bàn của tôi kỹ năng kiểm tra đang thiếu rõ ràng.

Bất kỳ ai cũng có thể chỉ cho tôi đúng hướng không? Đây là lần đầu tiên tôi sử dụng cây, và đệ quy không phải là điểm mạnh của tôi.

Trả lời:

void treecoords(Tree &T, int depth) 
{ 
    static int count = -1; //set to -1 so the precrement before assignment doesn't give the wrong values 
    if(T!=NULL) 
    { 
     treecoords(T->left, depth+1); //depth decrements automatically once this function call is removed from the stack 
     count++; 
     T->x = count; 
      T->y = depth; 
     treecoords(T->right, depth+1); 
    } 
} 
+1

Cảm ơn mọi người đã trả lời bài đăng của tôi. Tôi hiểu bây giờ tôi đã nghĩ về nó. Tôi sẽ đi và cố gắng sửa mã cho những gì bạn đã nói với tôi và đăng kết quả cuối cùng của tôi. Tôi không muốn chỉ sử dụng mã someones mà không hoàn toàn hiểu nó (mặc dù tôi đánh giá cao rằng bạn đã đăng nó cho tôi, cảm ơn). – xyzjace

+0

Nó hoạt động! Tôi đã thực hiện một thuật toán đệ quy mà kết thúc lên phù hợp với ông Cooper. Nó thực sự là một phần của một thuật toán lớn hơn gán tọa độ x và y cho các nút cây. Thuật toán là trong câu hỏi ban đầu ngay bây giờ. – xyzjace

Trả lời

3

Bạn don' t cần

else //leaf 
    return depth--; 

Bạn cũng không muốn để tăng biến sâu, chỉ cần vượt qua độ sâu + 1 với interation tới.

Cũng không cần trả lại giá trị.

Hãy thử điều này:

void assignDepth(Tree T, int depth) 
{ 
    if(T!=NULL) 
    { 
     assignDepth(T->left, depth+1); 
     T->depth = depth; 
     assignDepth(T->right, depth+1); 
    } 
} 
+0

Tôi không hiểu tại sao không, nhưng tất cả mọi người đã nói để loại bỏ nó, vì vậy tôi đã làm. Đệ quy phá vỡ tâm trí của tôi. Cảm ơn :) – xyzjace

+0

Nó giúp để suy nghĩ thông qua những gì đang xảy ra. Trong độ sâu cuộc gọi đầu tiên = 0 (hoặc bất cứ điều gì) và T là gốc của cây. Giả sử T không phải là NULL, hàm này gọi chính nó trên cây con bên trái với độ sâu + 1, gán chiều sâu cho nút (root) hiện tại, sau đó tự gọi chính nó trên cây con bên phải, một lần nữa với độ sâu + 1. Đó là bước trung gian gán giá trị của tham số chiều sâu cho nút, vì vậy không cần phải trả về giá trị cho bất kỳ đâu. –

+0

Điều đó có ý nghĩa. Tôi nhận được một chút bối rối với giá trị trở lại trong đệ quy. Nhưng tôi nghĩ tôi đã hiểu rồi. Nhiều đánh giá cao :) – xyzjace

2

Vâng, đối với người mới bắt đầu, bạn đang sử dụng sau tăng/giảm, bạn có thể có nghĩa là ++depth/--depth cho việc chuyển nhượng quyền và nghĩa khác trở lại;

Ngoài ra, tại sao truyền con trỏ làm biến tham chiếu?

+0

Tôi đã thử tiền tố như bạn đã đề xuất và nó đến đó, nhưng không hoàn toàn đúng. Tại sao tôi sử dụng tiền tố thay vì đăng bài? Tôi nghĩ rằng chỉ quan trọng theo thứ tự các hoạt động? Tôi đang sử dụng tham chiếu đến con trỏ vì đó là cách nó hoạt động.Chúng tôi đã được giới thiệu rất ngắn gọn cho con trỏ, sau đó thả xuống trong một đại dương của cây. Nó đã được rất nhiều đoán và kiểm tra xem khi trình biên dịch ngừng ném lỗi tại tôi. – xyzjace

1
int assignDepth(Tree &T, int depth) 

Bạn đã xác định Tree như một con trỏ đến một treeNode. Bạn không cần phải vượt qua nó bằng cách tham khảo. Bạn có thể sửa đổi nút được trỏ đến.

{ 
    if(T!=NULL) 
    { 
     depth = assignDepth(T->left, depth++); 

Các postfix ++ đảm bảo rằng bạn đang đi qua gốc depth xuống. Đó không phải là những gì bạn muốn. Tăng thêm depth trước đó, và quên trả về nó như là một kết quả hàm.

T->depth = depth; 

Điều này là ổn.

 depth = assignDepth(T->right, depth++); 

Tương tự như cuộc gọi đệ quy trước đây, ngoại trừ việc bạn không nên sửa đổi depth vì tất cả đã được tăng lên.

} 
    else //leaf 
     return depth--; 

Bạn không cần phải trả lại bất kỳ thông tin chi tiết nào (hoặc đó là yêu cầu không được nêu ra?).

} 

Cheers & h.,

+0

Tôi đọc tất cả các ý kiến ​​để chắc chắn rằng tôi không bỏ lỡ bất cứ điều gì. Cảm ơn :) – xyzjace

1
  1. Khi bạn đã đạt đến một nút lá, bạn không quan tâm đến chiều sâu của nó nữa, vì vậy giá trị trả về xuất hiện để thực hiện gì cả.

  2. Trong hai báo cáo:

    depth = assignDepth(T->left, depth++); 
    // and 
    depth = assignDepth(T->right, depth++); 
    

Bạn có hành vi không xác định từ điều chỉnh depth hai lần mà không có một điểm tự can thiệp (mặc dù nó có vẻ như không nên có, có không một điểm chuỗi giữa bên phải và bên trái của bài tập).

+0

Tôi chỉ nhận ra lý do tại sao giá trị trả lại là thừa khi tôi đã gõ này. Người đàn ông làm tôi cảm thấy ngu ngốc. Cảm ơn :)! Không chắc chắn về điểm chuỗi là gì, xin lỗi. – xyzjace

+0

@ user475234: Tôi đã tranh luận thậm chí còn nhắc đến nó, vì việc sửa mã cũng sẽ loại bỏ vấn đề này. Với một vài ngoại lệ, C về cơ bản nói rằng bạn chỉ có thể sửa đổi một biến cụ thể một lần trong một tuyên bố đã cho, và trong trường hợp này bạn đang làm nó hai lần (một lần trong gia số, một lần trong nhiệm vụ). –

1
  1. Tại sao bạn quay lại khi nút là NULL. Theo đặc điểm kỹ thuật của bạn, bạn không cần phải trả lại bất kỳ độ sâu nào
  2. Trong trường hợp khác, bạn chỉ cần tăng độ sâu và gửi đến cuộc gọi hàm. Sau đây là phiên bản của tôi về mã

    trống assignDepth (Tree & T, int chiều sâu) { if (T == NULL) trở lại; else { T-> depth = depth; nếu (T-> left! = NULL) gánDepth (T-> left, depth + 1); nếu (T-> right! = NULL) gánDepth (T-> phải, depth + 1); }}

+0

Nó bắt đầu có ý nghĩa hơn một chút. Bây giờ tôi nhận ra rằng khi đệ quy kết thúc, nó không cần phải trả về độ sâu, bởi vì khi nó kéo chức năng gọi ra khỏi ngăn xếp, chiều sâu là cùng giá trị trước khi bạn gọi hàm. Cảm ơn: D! – xyzjace

1

Tôi có một thiết kế hơi phức tạp hơn với thay đổi loại Node và đã làm điều này, vì vậy tôi nghĩ rằng id cổ phiếu.

Nếu bạn có cây thay đổi theo loại Nút thành Nút (Nhị phân, Unary, v.v.), bạn nên đơn giản hóa phương pháp truyền thống để tránh các IF được nhúng khó kiểm tra loại Nút.

Hai Chức năng:

  • 1: Từ root, chạy qua từng nút và kiểm tra khoảng cách của nó đến gốc bởi recursivly tự xưng và thêm 1 cho mỗi phụ huynh. Đặt mỗi nút một biến sâu để lưu trữ điều này.
  • 2: Từ bộ hoàn chỉnh các Nút trên cây chạy kiểm tra MAX đối với mỗi độ sâu nút, số cao nhất sẽ bằng độ sâu của cây.

Xử lý theo cách này loại bỏ kiểm tra loại rõ ràng và chỉ cần đếm nút cho dù nó có một, hai hoặc một trăm trẻ em.

Hy vọng điều này sẽ giúp ai đó!

Các vấn đề liên quan