เขียนโปรแกรมที่สั้นที่สุดเพื่อตรวจสอบว่าต้นไม้ไบนารีมีความสมดุลหรือไม่


15

สำหรับแต่ละโหนดในต้นไม้ไบนารีที่สมดุลความแตกต่างสูงสุดในความสูงของทรีย่อยของเด็กซ้ายและทรีย่อยของเด็กที่ถูกต้องคือมากที่สุด 1

ความสูงของต้นไม้ไบนารีคือระยะทางจากรูตโหนดไปยังโหนดชายด์ที่อยู่ห่างจากรูทมากที่สุด

ด้านล่างเป็นตัวอย่าง:

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

ความสูงของต้นไม้ไบนารี: 4

ต่อไปนี้เป็นต้นไม้ไบนารีและรายงานว่ามีความสมดุลหรือไม่:

กรณีทดสอบ 1

ต้นไม้ข้างต้นเป็นความไม่สมดุล

กรณีทดสอบ 2

ต้นไม้ด้านบนมีความสมดุลมีความสมดุล

เขียนโปรแกรมที่สั้นที่สุดที่ยอมรับได้ว่าป้อนรากของต้นไม้ไบนารีและคืนค่าเท็จถ้าต้นไม้ไม่สมดุลและค่าจริงถ้าต้นไม้มีความสมดุล

อินพุต

รากของต้นไม้ไบนารี นี่อาจเป็นในรูปแบบของการอ้างอิงไปยังวัตถุรากหรือแม้แต่รายการที่เป็นตัวแทนที่ถูกต้องของต้นไม้ไบนารี

เอาท์พุต

ส่งกลับค่าความจริง:ถ้าต้นไม้มีความสมดุล

ส่งคืนค่า falsey:หากต้นไม้ไม่สมดุล

ความหมายของต้นไม้ไบนารี

ต้นไม้เป็นวัตถุที่มีค่าและต้นไม้หรือพอยน์เตอร์อีกสองตัว

โครงสร้างของต้นไม้ไบนารีมีลักษณะดังนี้:

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

หากใช้การแสดงรายการสำหรับต้นไม้ไบนารีมันอาจมีลักษณะดังต่อไปนี้:

[root_value, left_node, right_node]

2
อินพุตอาจเป็นต้นไม้ว่างเปล่า?
TSH

1
ในตัวอย่างเริ่มต้นของต้นไม้ถ้าคุณนำใบไม้4ออกต้นไม้ที่เหลืออยู่นั้นมีความสมดุลหรือไม่?
Neil

ไม่ไม่ใช่ตัวอย่างนั้นฉันหมายถึงชิ้นแรกโดยใช้ ASCII art
Neil

ตามการใช้งานของฉันเอง "C, 117 bytes": ไม่เนื่องจากความสูงของทรี subarm ด้านขวาเริ่มต้นจาก "5" คือ 2 และความสูงของทรี subarm ทางซ้ายคือ 0
T. Salim

การแก้ไขอย่างน้อย 6 ตัวอักษร แต่โปรดลบเครื่องหมายจุลภาคออกจากระหว่าง 'สมดุล' และ 'ไบนารี' - 'ต้นไม้ไบนารี' เป็นวลีคำนามดังนั้นการเขียน 'สมดุลต้นไม้ไบนารี' จึงเท่ากับ 'แดงมือถือหิมะ' - ไม่จำเป็นต้องใช้เครื่องหมายจุลภาค
Geza Kerecsenyi

คำตอบ:


8

เยลลี่ 11 ไบต์

ḊµŒḊ€IỊ;߀Ạ

ลองออนไลน์!

[]ต้นไม้ที่ว่างเปล่าเป็นตัวแทนจาก


ขอบคุณ Erik ที่ได้เป็นคนแรกที่ตอบคำถามนี้ เยลลี่เป็นภาษาที่ได้รับความนิยมอย่างมากในเว็บไซต์นี้ ฉันคิดว่าฉันควรมีเสรีภาพในการใช้ภาษานี้ ดีที่จะเรียนรู้จากภาษาสคริปต์กอล์ฟที่แข็งแกร่ง
T. Salim

ขอแสดงความยินดีกับ Erik the Outgolfer คุณเป็นผู้ชนะ
T. Salim

3

Prolog (SWI) , 49 ไบต์

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

ลองออนไลน์!

หมายถึงต้นไม้กับต้นไม้ที่ว่างเปล่าเป็นอะตอมValue/Left_Child/Right_Child eกำหนด+/2ซึ่งเอาท์พุทผ่านสำเร็จหรือล้มเหลวกับตัวแปรผูกไว้ (หรือหนึ่งแล้วเท่ากับความสูงของต้นไม้) ทางด้านซ้ายและต้นไม้ด้านขวา - ถ้าอาร์กิวเมนต์สูงเป็นที่ยอมรับเพิ่ม 9 -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.

(หากค่าของแต่ละโหนดสามารถตัดออกจากอินพุต_/สามารถนำออกมาเป็น -2 ไบต์)
สตริงที่ไม่เกี่ยวข้อง

3

ภาษา Wolfram (Mathematica)ขนาด 50 ไบต์

f@_[x_,y_]:=f@x&&f@y&&-2<Depth@x-Depth@y<2;f@_=1>0

ใช้Nullเป็นโมฆะvalue[left, right]สำหรับโหนด 2[7[2[Null, Null], 6[5[Null, Null], 11[Null, Null]]], 5[Null, 9[4[Null, Null], Null]]]ยกตัวอย่างเช่นต้นไม้ต่อไปนี้จะเขียนเป็น

    2
   / \
  7   5
 / \   \
2   6   9
   / \  /
  5  11 4

ลองออนไลน์!


มันสวยจริงๆ!
เกร็กมาร์ติน

3

Python 3.8 (เผยแพร่ล่วงหน้า) , 133 125 ไบต์

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]

ลองออนไลน์!

ใช้ต้นไม้ในรูปแบบ "รายการ": โหนดอยู่[value, left, right]กับleftและrightเป็นโหนด

hเรียกใช้ฟังก์ชั่น

ส่งคืน0หรือFalseสำหรับทรีที่ไม่สมดุล ส่งคืน1หรือTrueสำหรับต้นไม้ที่สมดุล

Ungolfed:

# 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: ตรรกะกลับด้านเพื่อกำจัด not s

หากมีข้อโต้แย้งระหว่างการโทรที่ได้รับอนุญาตอาจทำให้สั้นลงได้ (115 ไบต์)

(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]

ด้วย_การเป็นต้นไม้ที่จะตรวจสอบ



2

จาวาสคริปต์, 162 ไบต์

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}

ลองออนไลน์!

รูปแบบของอินพุตเป็นวัตถุ

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

คำอธิบาย

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}

หากไม่พบโหนดดังกล่าวให้ส่งคืน 1


1
อาจมีวิธีที่จะทำการค้นหาที่กว้างกว่านี้ก่อนดีกว่า แต่ฉันไม่สามารถคิดได้
fəˈnɛtɪk

1
4ผมคิดว่านี้ล้มเหลวสำหรับกรณีที่ถูกต้องบางอย่างเช่นตัวอย่างแรกมากซึ่งจะกลายเป็นความสมดุลเมื่อคุณเอาใบ
Neil

1

Julia, 56 ไบต์

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

ด้วยโครงสร้างต่อไปนี้แสดงต้นไม้ไบนารี:

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

c คือ tuple ที่แสดงถึงโหนดด้านซ้ายและขวาและ tuple ที่ว่างเปล่า ()ถูกใช้เพื่อส่งสัญญาณว่าไม่มีโหนด

ค่า Falsey คือNaNจำนวนเต็มใด ๆ ที่เป็นจริง


1
สมมติว่าการเข้ารหัสเป็น UTF-8 นี้เป็นจริง 57 ไบต์เพราะตามTIO ของในตัวเคาน์เตอร์ไบต์ ยินดีต้อนรับสู่ CG&CC!
สตริงที่ไม่เกี่ยวข้อง

1
ใช่คุณพูดถูก. ฉันแก้ไขให้ถูกต้องแล้วตอนนี้มันเป็นจริง 56 ไบต์
user3263164


0

C, 117 ไบต์

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;}

การใช้งานโครงสร้างมีดังต่อไปนี้:

 typedef struct T
    {
        struct T * l;

        struct T * r;

        int v;

    } T;

ลองใช้สิ่งนี้กับ JDoodle


ดูเหมือนว่าจะเป็น 117 ไบต์ แต่คุณสามารถทำการ<2ตรวจสอบครั้งสุดท้ายแทนได้
Jo King

นอกจากนี้ฉันไม่แน่ใจว่ามันถูกต้องเพราะอาศัยโครงสร้างข้อมูลที่กำหนดนอกการส่ง
Jo King

0

Python 2 , 99 96 94 ไบต์

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:]))

ลองออนไลน์!

3 ไบต์จาก โจกษัตริย์

จะเข้าเป็น: โหนดที่ว่างเปล่าและโหนดอื่น[][<value>, <leftNode>, <rightNode>]เอาต์พุต0/1สำหรับ False / True

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.