2011-12-29 40 views
5

Tôi có cấu trúc cây có nút có ID cha (các nút con không giới hạn). Vì mục đích hiển thị, tôi cần cấu trúc cây này như một cây nhị phân. Làm thế nào tôi làm điều này là ở mỗi nút cấp được nhóm lại thành một nút duy nhất dựa trên một điều kiện. Khi một nút được chọn, con của nó sẽ được hiển thị. Ví dụ:Cây nhị phân từ cây chung

N-Ary tree

Các màu xanh lá cây là khi điều kiện là true và màu đỏ là false

BTree

B, C đã được nhóm lại thành nút trái và D, E ở bên phải dựa trên điều kiện của họ.

CÂU HỎI: Tôi đang sử dụng KnockoutJS để hiển thị cây và tôi cần có thể thực hiện các hoạt động bình thường của cây như nhận nút dựa trên ID của nó, chèn (các) nút xóa (các) nút. Đây là cấu trúc tôi có. Có cấu trúc/cách làm tốt hơn không?

var tree = [ 
    { groupNodeId: "A", childNodes: [ 
     { nodeId: "A", childGroupNodes: [ 
      { groupNodeId: "B", condition: true, childNodes: [ 
       { nodeId: "B", childGroupNodes: []}, 
       { nodeId: "C", childGroupNodes: []} 
      ]}, 
      { groupNodeId: "D", condition: false, childNodes: [ 
       { nodeId: "D", childGroupNodes: []}, 
       { nodeId: "E", childGroupNodes: []} 
      ]} 
     ]} 
    ]} 
]; 
+0

Tại sao bạn sử dụng 'childGroupNodes' và' groupNodeId' cho các nút được chèn thay vì tiếp tục sử dụng 'childNodes' và' nodeId'? Ngoài ra, nếu, ví dụ, B và C mỗi có một đứa trẻ có 'điều kiện' là đúng, bạn có muốn hai nút đó được nhóm lại với nhau không? –

+1

Ngoài ra, tôi giả sử 'điều kiện: true' trong groupNode' D' là một lỗi đánh máy? –

+0

Vâng, đã được sửa chữa – Ryan

Trả lời

3

Tôi không chắc chắn chính xác những gì bạn muốn, nhưng giả định rằng:

  1. Bạn muốn chèn "groupNodes", các nút không thường xuyên, và rằng groupNodes có thể có con không giới hạn.
  2. Cây gốc chỉ chứa các nút thông thường, không chỉ các nút nhóm.
  3. Tất cả các nút thông thường đều có nodeId, điều kiện được đặt thành true hoặc false và một childNodes mảng.
  4. Bạn không muốn tạo nhómNó không có con.

thì đây là câu trả lời của bạn.

function binize(tree) { 
    var left,right,t,u, 
    stack=[tree]; 
    while(t=stack.pop()) { 
    left=[]; 
    right=[]; 
    while(u=t.childNodes.pop()) { 
     (u.condition?left:right).push(u); 
     stack.push(u); 
    } 
    left.length&&t.childNodes.push({ 
     groupNodeId:left[0].nodeId, 
     condition:true, 
     childNodes:left 
    }); 
    right.length&&t.childNodes.push({ 
     groupNodeId:right[0].nodeId, 
     condition:false, 
     childNodes:right 
    }); 
    } 
} 

Tôi đã thử nghiệm nó bằng cấu trúc dữ liệu này (lưu ý rằng cây là đối tượng cấp cao nhất, không phải mảng có chứa nó).

var tree={nodeId:'A',childNodes:[ 
    {nodeId:'B',condition:true,childNodes:[]}, 
    {nodeId:'C',condition:true,childNodes:[]}, 
    {nodeId:'D',condition:false,childNodes:[ 
    {nodeId:'F',condition:false,childNodes:[]}, 
    {nodeIf:'G',condition:false,childNodes:[]} 
    ]}, 
    {nodeId:'E',condition:false,childNodes:[]} 
]}; 

Nếu tôi biết nhiều hơn về cây của bạn thì tôi có thể đã thực hiện một cách tiếp cận khác. Ví dụ, nếu cây không phải là rất sâu thì nó có thể hiệu quả hơn (và dĩ nhiên là sạch hơn) để đào sâu nó một cách đệ quy.

Ngoài ra, tôi chưa bao giờ sử dụng KnockoutJS trước đây và không biết cấu trúc nó thích. Tôi vừa tạo ra các cấu trúc bạn đã chỉ ra; hy vọng rằng sẽ làm việc.

+0

Hmmm, tôi sẽ thử nghiệm điều này tối nay, nhưng từ sự hiểu biết của tôi bây giờ điều này có thể là một bộ lồng nhau? hoặc một cây nhị phân mà mỗi nút chứa một cây nhị phân khác – Ryan

+1

Vâng, nó thay thế các chế độ, như ví dụ của bạn. Vì vậy, cấp 1 có nút cấp cao nhất, và cấp độ tiếp theo là hai nhómNode. Cấp độ tiếp theo (trẻ em nhómNodes) chứa tất cả các con ban đầu của nút trên cùng, và cấp độ tiếp theo chứa 2 groupNodes cho mỗi Node gốc (nếu nhóm sẽ không trống), v.v. Đó là những gì bạn muốn, phải không? –

+0

Có, một phần ...Điều này cho thấy làm thế nào để tạo cây của tôi từ một cây chung nhưng tôi muốn biết làm thế nào để đi qua cấu trúc của tôi một cách hiệu quả – Ryan

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