node(정점)와 edge(간선)를 이용하여 데이터의 배치 형태를 추상화한 자료구조
level(수준)
루트에서 얼마나 멀리 떨어져 있는지를 나타낸 것
= 루트 노드 level 0으로 시작하여 거쳐온 edge의 수
height(높이) · depth(깊이)
루트에서 가장 멀리 있는 리프까지의거리
= 노드의 최대 level + 1 
degree(차수)
각 노드가 갖는 자식의 수
= child node로 이어진 edge의 수
subtree(서브트리 · 부분트리)
어떤 노드를 루트로 하고, 그 자손으로 구성된 트리, leaf node의 degree = 0
= 노드의 degree
모든 노드의 차수가 2 이하인 트리
class Node:
	def __init__(self,item):
    		self.data = item
            self.left = None
            self.right = None
class BinaryTree:
	def __init(self,r):
		self.root = r
class Node:
	def size(self):
    	l = self.left.size() if self.left else 0
    	r = self.right.size() if self.right else 0
    	return l + r + 1
class BinaryTree:
	def size(self):
    	if self.root:
        	return self.root.size()
        else:
        	return 0
class Node:
	def depth(self):
    	l = self.left.depth() if self.left else 0
        r = self.right.depth() if self.right  else 0
        return max(l,r) + 1
class BinaryTree:
	def depth(self):
    	if self.root:
        	return self.root.depth()
        else:
        	return 0
class Node:
	def inorder(self):
    	traversal = []
        
        if self.left:
        	traversal += self.left.inorder()
            
        traversal.append(self.data)
        
        if self.right:
        	traversal += self.right.inorder()
            
        return traversal
class BinaryTree:
	def inorder(self):
    	if self.root:
        	return self.root.inorder()
        else:
        	return []
class Node:
	def preorder(self):
    	traversal = []
        
        traversal.append(self.data)
        
        if self.left:
        	traversal += self.left.preorder()
        
        if self.right:
        	traversal += self.right.preorder()
            
        return traversal
        
 class BinaryTree:
 	def preorder(self):
    	if self.root:
        	return self.root.inorder()
        else:
        	return []
class Node:
	def postorder(self):
    	traversal = []
        
        if self.leftr:
        	traversal += self.left.postorder()
            
        if self.right:
        	traversal += self.right.postorder()
            
        traversal.append(self.data)
        
        return traversal
class BinaryTree:
	def postorder(self):
    	if self.root:
       		return self.root.postorder()
        else:
        	return []
class ArrayQueue:
	def __init__(self):
    	self.data = []
        
    def size(self):
    	return len(self.data)
        
    def isEmpty(self):
    	return self.size() == 0
        
   	def enqueue(self):
    	self.data.append(item)
        
    def dequeue(self):
    	return self.data.pop(0)
        
    def peek(self):
    	return self.data[0]
class Node:
	def __init__(self,item):
    	self.data = item
        self.left = None
        self.right = None
        
class BinaryTree:
	def __init__(self,r):
    	self.root = r
       
    def bft(self):
    	visitQueue = ArrayQueue()
        
        traversal = []
        
        if self.root:  # 빈 트리가 아닐 때
        	visitQueue/enqueue(self.root)
        
        while visitQueue.isEmpty() == False:  # 큐가 비어있지 않을 때
        	node = visitQueue.dequeue()
        	traversal.append(node.data)
        
        	if node.left:
        		visitQueue.enqueue(node.left)
        	if node.right:
        		visitQueue.enqueue(node.right)
                
        return traversal
(중복되는 데이터가 없다고 가정했을때)left subtree의 모든 값이 root node의 값보다 작고 right subtree의 모든 값이 root node의 값보다 큰 이진트리
class Node:
	def __init__(self,key,data):
    		self.key = key
            self.data = data
            self.left = None
            self.right = None
            
class BinarySearchTree:
		def __init__(self):
        		self.root = None
class Node:
  def inorder(self):
    traversal = []
    if self.left:
      traversal += self.left.inorder()
    traversal.append(self)
    if self.right:
      traversal += self.right.inorder()
    return traversal
class BinarySearchTrer:
  def inorder(self):
    if self.root:
      return self.root.inorder()
    else:
      return []
class Node:
  def min(self):
    if self.left:
      return self.left.min()
    else:
      return self
    
class BinarySearchTree:
  def min(self):
    if self.root:
      return self.root.min()
    else:
      return None
class Node:
  def max(self):
    if self.right:
      return self.right.max()
    else:
      return self
    
class BinarySearchTree:
  def max(self):
    if self.root:
      return self.root.max()
    else:
      return None
class Node:
  def lookup(self,key,parent=None):
    if key < self.key:
      if self.left:
        return self.left.lookup(key,self)
      else:
        return None, None
    elif key > self.key:
      if self.rignt:
        return self.right.lookup(key,self)
      else:
        return None, None
    else:
      return self, parent
    
class BinarySearchTree:
  def lookup(self,key):
    if self.root:
      return self.root.lookup(key)
    else:
      return None, None
class Node:
  def insert(self,key,data):
    if key < self.key:
      if self.key is key:
        raise KeyError
      
      if key < self.key:
        if self.left:
          self.left.insert(key, data)
        else:
          self.left = Node(key, data)
      else:
        if self.right:
          self.right.insert(key, data)
        else:
          self.right = Node(key, data)
class BinarySearchTree:
  def insert(self,key,data):
    if self.root:
      self.root.insert(key,data)
    else:
      self.root = Node(key,data)