Viết chương trình ngắn nhất để kiểm tra xem cây nhị phân có cân bằng không


15

Đối với mỗi nút trong cây nhị phân cân bằng, chênh lệch tối đa về độ cao của cây con con trái và cây con con phải nhiều nhất là 1.

Chiều cao của cây nhị phân là khoảng cách từ nút gốc đến nút con xa nhất với gốc.

Dưới đây là một ví dụ:

           2 <-- root: Height 1
          / \
         7   5 <-- Height 2
        / \   \
       2   6   9 <-- Height 3
          / \  /
         5  11 4 <-- Height 4 

Chiều cao của cây nhị phân: 4

Sau đây là các cây nhị phân và một báo cáo về việc chúng có cân bằng hay không:

Trường hợp kiểm tra 1

Cây ở trên không cân đối .

Trường hợp thử nghiệm 2

Cây trên được cân bằng .

Viết chương trình ngắn nhất có thể chấp nhận làm đầu vào gốc của cây nhị phân và trả về giá trị falsey nếu cây không cân bằng và giá trị trung thực nếu cây được cân bằng.

Đầu vào

Rễ của cây nhị phân. Điều này có thể ở dạng tham chiếu đến đối tượng gốc hoặc thậm chí là một danh sách đại diện hợp lệ của cây nhị phân.

Đầu ra

Trả về giá trị trung thực: Nếu cây được cân bằng

Trả về giá trị falsey: Nếu cây không cân bằng.

Định nghĩa cây nhị phân

Cây là một đối tượng chứa một giá trị và hai cây khác hoặc con trỏ tới chúng.

Cấu trúc của cây nhị phân trông giống như sau:

typedef struct T
{
   struct T *l;
   struct T *r;
   int v;
}T;

Nếu sử dụng biểu diễn danh sách cho cây nhị phân, nó có thể trông giống như sau:

[root_value, left_node, right_node]

2
Đầu vào có thể là cây trống?
tsh

1
Trong ví dụ ban đầu của bạn về một cây, nếu bạn loại bỏ lá 4, cây còn lại có cân bằng không?
Neil

Không, không phải ví dụ đó, ý tôi là cái đầu tiên, sử dụng nghệ thuật ASCII.
Neil

Theo triển khai của riêng tôi "C, 117 byte": Không, vì chiều cao của cây con bên phải bắt đầu từ "5" là 2 và chiều cao của cây con bên trái là 0.
T. Salim

Chỉnh sửa có ít nhất 6 ký tự nhưng vui lòng xóa dấu phẩy từ giữa 'cân bằng' và 'nhị phân' - 'cây nhị phân' là cụm danh từ, do đó, viết 'cây nhị phân, cân bằng' là tương đương với 'đỏ, tuyết di động' - dấu phẩy là không bắt buộc.
Geza Kerecsenyi

Câu trả lời:


8

Thạch , 11 byte

ḊµŒḊ€IỊ;߀Ạ

Hãy thử trực tuyến!

Cây trống được đại diện bởi [].


Cảm ơn Erik là một trong những người đầu tiên trả lời câu hỏi này. Jelly chắc chắn là một ngôn ngữ rất phổ biến trên trang web này. Tôi nghĩ rằng tôi nên tự do để thực hiện ngôn ngữ này. Tốt để học từ một ngôn ngữ kịch bản golf mạnh mẽ.
T. Salim

Xin chúc mừng Erik the Outgolfer, bạn là người chiến thắng.
T. Salim

3

Prolog (SWI) , 49 byte

N+_/B/C:-X+B,Y+C,abs(X-Y)<2,N is max(X,Y)+1.
0+e.

Hãy thử trực tuyến!

Đại diện cho cây như Value/Left_Child/Right_Child, với cây trống là nguyên tử e. Xác định +/2, xuất ra thông qua thành công hay thất bại, với một biến không liên kết (hoặc một biến đã bằng chiều cao của cây) ở bên trái và cây ở bên phải - nếu không thể chấp nhận đối số chiều cao, hãy thêm 9 byte để xác định -T:-_+T..

N + _/B/C :-            % If the second argument is a tree of the form _Value/B/C,
    X+B,                % X is the height of its left child which is balanced,
    Y+C,                % Y is the height of its right child which is balanced,
    abs(X-Y) < 2,       % the absolute difference between X and Y is strictly less than 2,
    N is max(X,Y)+1.    % and N is the height of the full tree.
0 + e.                  % If, on the other hand, the second argument is e, the first is 0.

(Nếu giá trị của mỗi nút có thể được bỏ qua từ đầu vào, _/có thể được lấy ra cho 2 byte.)
Chuỗi không liên quan


3

Python 3.8 (tiền phát hành) , 133 125 byte

b=lambda t:((max(l[0],r[0])+1,abs(l[0]-r[0])<2)if(l:=b(t[1]))[1]and(r:=b(t[2]))[1]else(0,0))if t else(0,1)
h=lambda t:b(t)[1]

Hãy thử trực tuyến!

Lấy một cây theo định dạng "danh sách": Một nút [value, left, right]leftright là các nút.

Gọi hàm h .

Trả về 0hoặc Falsecho một cây không cân bằng. Trả về 1hoặcTrue cho một cây cân bằng.

Ung dung:

# Returns tuple (current height, subtrees are balanced (or not))
def balanced(tree):
  if tree: # [] evaluates to False
    left = balanced(tree[1])
    right = balanced(tree[2])
    # If  the subtrees are not both balanced, nothing to do, just pass it up
    if left[1] and right[1]:
      height = max(left[0], right[0]) + 1
      subtrees_balanced = abs(left[0] - right[0]) < 2
    else:
      height = 0 # Value doesn't matter, will be ignored
      subtrees_balanced = False
  else:
    height = 0
    subtrees_balanced = True
  return (height, subtrees_balanced)

def h(tree):
  return balanced(tree)[1]

-10: Đảo ngược logic để thoát khỏi not s

Nếu cho phép lấy các đối số ở giữa một cuộc gọi, điều này có thể được rút ngắn thành (115 byte)

(b:=lambda t:((max(l[0],r[0])+1,abs(l[0]-r[0])<2)if(l:=b(t[1]))[1]and(r:=b(t[2]))[1]else(0,0))if t else(0,1))(_)[1]

với _việc là cây để kiểm tra.



2

JavaScript, 162 byte

f=x=>{for(f=0,s=[[x,1]];s[0];){if(!((d=(t=s.pop())[0]).a&&d.b||f))f=t[1];if(f&&t[1]-f>1)return 0;if(d.a)s.push([d.a,t[1]+1]);if(d.b)s.push([d.b,t[1]+1])}return 1}

Hãy thử trực tuyến!

Định dạng của đầu vào là một đối tượng

root={a:{node},b:{node},c:value}

Giải trình

for(f=0,s=[[x,1]];s[0];){if(!((d=(t=s.pop())[0]).a&&d.b||f))f=t[1]

Thực hiện tìm kiếm đầu tiên tìm thấy độ sâu của nút đầu tiên bị thiếu một hoặc nhiều nhánh.

if(f&&t[1]-f>1)return 0;if(d.a)s.push([d.a,t[1]+1]);if(d.b)s.push([d.b,t[1]+1])}

Tiếp tục tìm kiếm đầu tiên theo chiều rộng, trả về 0 nếu bất kỳ phần tử nào sâu hơn hai độ sâu của nút đầu tiên thiếu các nhánh.

return 1}

Nếu không tìm thấy nút nào như vậy, trả về 1


1
Có lẽ có một số cách để làm cho tìm kiếm đầu tiên tốt hơn nhưng tôi không thể nghĩ về nó.
fnɛtɪk

1
Tôi nghĩ rằng điều này không thành công đối với một số trường hợp hợp lệ, chẳng hạn như ví dụ đầu tiên sẽ trở nên cân bằng khi bạn loại bỏ chiếc lá 4.
Neil

1

Julia, 56 byte

f(t)=t!=()&&(-(f.(t.c)...)^2<2 ? maximum(f,t.c)+1 : NaN)

Với cấu trúc sau đại diện cho cây nhị phân:

struct Tree
    c::NTuple{2,Union{Tree,Tuple{}}}
    v::Int
end

c là một tuple đại diện cho các nút trái và phải và tuple trống () được sử dụng để báo hiệu sự vắng mặt của một nút.

Giá trị Falsey là NaN, bất kỳ số nguyên là sự thật.


1
Giả sử mã hóa là UTF-8, đây thực sự là 57 byte vì , theo bộ đếm byte tích hợp của TIO . Dù sao, chào mừng bạn đến với CG & CC!
Chuỗi không liên quan

1
Vâng bạn đã đúng. Tôi đã sửa nó, để bây giờ thực sự là 56 byte
user3263164


0

C, 117 byte

h(T*r){r=r?1+h(h(r->l)>h(r->r)?r->l:r->r):0;}b(T*r){return r->l&&!b(r->l)||r->r&&!b(r->r)?0:abs(h(r->l)-h(r->r))<=1;}

Cấu trúc thực hiện như sau:

 typedef struct T
    {
        struct T * l;

        struct T * r;

        int v;

    } T;

Hãy thử điều này trên JDoodle


Điều này dường như là 117 byte, mặc dù bạn có thể thực hiện <2cho lần kiểm tra cuối cùng đó
Jo King

Ngoài ra, tôi không chắc nó có giá trị như thế nào, vì nó dựa trên cấu trúc dữ liệu được xác định bên ngoài nội dung gửi
Jo King

0

Python 2 , 99 96 94 byte

lambda A:A==[]or(abs(D(A[1])-D(A[2]))<2)*f(A[1])*f(A[2])
D=lambda A:A>[]and-~max(map(D,A[1:]))

Hãy thử trực tuyến!

3 byte từ Jo King .

Đưa đầu vào là: nút trống []và các nút khác là [<value>, <leftNode>, <rightNode>]. Đầu ra 0/1cho Sai / Đúng.

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.