ํธ๋ฆฌ ADT
ํธ๋ฆฌ ADT๋ ๊ณ์ธต์ ์ผ๋ก ์ ์ฅ๋ ๋ฐ์ดํฐ ์์๋ค์ ๋ชจ๋ธ๋ง ํ ๊ฒ์ด๋ค. ์์ ๋ฐ์ดํฐ ๊ตฌ์กฐ๋ค๊ณผ ์ฐจ์ด์ ์ด๋ผ๋ฉด ๊ณ์ธต์ ์ด๋ผ๋ ์ ์ด๋ค.
๋งจ ์์ ์์๋ฅผ ์ ์ธํ๊ณ , ๊ฐ ํธ๋ฆฌ ์์๋ ๋ถ๋ชจ(parent) ์์์ 0๊ฐ ์ด์์ ์์(children) ์์๋ค์ ๊ฐ์ง๋ค.
์ ์ : ํธ๋ฆฌ๋ ๋น์ด์์ง ์๋ค -> ์๊ณ ๋ฆฌ์ฆ ๋จ์ํ
ํธ๋ฆฌ ์ฉ์ด
๋ฃจํธ(root): ๋ถ๋ชจ๊ฐ ์๋ ๋
ธ๋(A)
๋ด๋ถ๋
ธ๋(internal node): ์ ์ด๋ ํ ๊ฐ์ ์์์ ๊ฐ์ง ๋
ธ๋(A, B, C, F)
์ธ๋ถ๋
ธ๋(external node), ๋๋ ๋ฆฌํ (leaf): ์์์ด ์๋ ๋
ธ๋(E, I, J, K, G, H, D)
ํ์ (siblings): ๊ฐ์ ๋ถ๋ชจ๋ฅผ ๊ฐ์ง ๋
ธ๋๋ค(G, H)
๋
ธ๋์ ์กฐ์(ancestor): ๋ถ๋ชจ(parent), ์กฐ๋ถ๋ชจ(grandparent), ์ฆ์กฐ๋ถ๋ชจ(grand-grandparent), ๋ฑ
๋
ธ๋์ ์์(descendant): ์์(child), ์์ฃผ(grandchild), ์ฆ์์ฃผ(grandgrandchild), ๋ฑ
๋ถํธ๋ฆฌ(subtree): ๋
ธ๋์ ๊ทธ ๋
ธ๋์ ์์๋ค๋ก ๊ตฌ์ฑ๋ ํธ๋ฆฌ
๊ฒฝ๋ก(path): ์กฐ์ ๋๋ ์์์๋ฐ๋ผ ์ด์ด์ง ๋
ธ๋ ์ํ์ค(์:ABF)
๊ฒฝ๋ก๊ธธ์ด(path length): ๊ฒฝ๋ก๋ด ๊ฐ์ (edge)์ ์
๋
ธ๋์ ๊น์ด(depth): ๋ฃจํธ๋ก๋ถํฐ ๋
ธ๋์ ์ด๋ฅด๋์ ์ผํ ๊ฒฝ๋ก์ ๊ธธ์ด
๋
ธ๋์ ๋์ด(height): ๋
ธ๋๋ก๋ถํฐ ์ธ๋ถ๋
ธ๋์์ด๋ฅด๋ ๊ฐ์ฅ ๊ธด ๊ฒฝ๋ก์ ๊ธธ์ด
ํธ๋ฆฌ์ ๋์ด(height of a tree): ๋ฃจํธ์ ๋์ด
ํธ๋ฆฌ ADT ๋ฉ์๋
ํธ๋ฆฌ ADT์ ๋ฉ์๋๋ ๋ค์๊ณผ ๊ฐ๋ค.
- ์ผ๋ฐ ๋ฉ์๋
boolean isEmpty()*
integer size()
- ์ ๊ทผ ๋ฉ์๋
node root()
node parent(v)
node children(v)
element element(v)
- ์ง์ ๋ฉ์๋
boolean isInternal(v)
boolean isExternal(v)
boolean isRoot(v)
- ๊ฐฑ์ ๋ฉ์๋
swapElements(v, w) #๋ ธ๋์ ๋ ธ๋์ ๋ฐ์ดํฐ๋ฅผ ์๋ก swap
element setElement(v, e) #๋ ธ๋์ ๋ฐ์ดํฐ๋ฅผ e๋ก set
- ์์ธ
invalidNodeException(): ๋ถ๋ฒ ๋ ธ๋ ์ ๊ทผ ์ ๋ฐ๋ น
ํธ๋ฆฌADT๋ฅผ ๊ตฌํํ๋ ๋ฐ์ดํฐ ๊ตฌ์กฐ์ ๋ฐ๋ผ ์ถ๊ฐ์ ์ธ ๊ฐฑ์ ๋ฉ์๋ (์ฝ์ , ์ญ์ ๋ฑ) ์ ์๊ฐ ๊ฐ๋ฅํ๋ค!!
๊น์ด
๋ ธ๋ v์ ๊น์ด(depth)์ ์ฌ๊ท์ ์ ์
- ๋ง์ฝ v๊ฐ ๋ฃจํธ๋ฉด, v์ ๊น์ด๋ 0
- ๊ทธ๋ ์ง ์์ผ๋ฉด, v์ ๊น์ด๋ v์ ๋ถ๋ชจ์ ๊น์ด ๋ํ๊ธฐ 1
์คํ์๊ฐ์ O(n) ์ด๋ฉฐ ๋จ, n์ ํธ๋ฆฌ ๋ด ์ด ๋ ธ๋ ์์ด๋ค.
๋์ด
๋ ธ๋ v์ ๋์ด(heigth)์ ์ฌ๊ท์ ์ ์
- ๋ง์ฝ v๊ฐ ์ธ๋ถ๋ ธ๋๋ฉด, v์ ๋์ด๋ 0
- ๊ทธ๋ ์ง ์์ผ๋ฉด, v์ ๋์ด๋ v์ ์์๋ค ์ค ์ต๋ ๋์ด ๋ํ๊ธฐ 1
์คํ์๊ฐ์ O(n) ์ด๋ฉฐ ๋จ, n์ ํธ๋ฆฌ ๋ด ์ด ๋ ธ๋ ์์ด๋ค.
์ํ
์ํ(traversal)๋ ํธ๋ฆฌ์ ๋ ธ๋๋ค์ ์ฒด๊ณ์ ์ธ ๋ฐฉ์์ผ๋ก ๋ฐฉ๋ฌธํ๋ ๊ฒ์ ๋งํ๋ค.
์ ์์ํ (preorder traversal) : ๋ ธ๋๋ฅผ ๊ทธ์ ์์๋ค๋ณด๋ค ์์ ๋ฐฉ๋ฌธ
๋ ๋ฒจ์ํ (levelorder traversal): ํ๋ฅผ ์ด์ฉํ์ฌ ๊น์ด d์ ๋ชจ๋ ๋ ธ๋๋ค์ ๊น์ด d + 1์ ๋ ธ๋๋ค์ ์์ ๋ฐฉ๋ฌธ
๋ ๋ฒจ์ด๋ ํธ๋ฆฌ์ ๊ฐ์ ๊น์ด d์ ์กด์ฌํ๋ ๋ชจ๋ ๋ ธ๋๋ค์ ์งํฉ์ ๋ํ๋ธ๋ค.
ํ์์ํ( postorder traversal) : ๋ ธ๋๋ฅผ ๊ทธ์ ์์๋ค๋ณด๋ค ๋์ค์ ๋ฐฉ๋ฌธ
์ด์งํธ๋ฆฌ ADT
์ด์งํธ๋ฆฌ๋ ํธ๋ฆฌ์ ๊ฐ ๋ด๋ถ๋ ธ๋๊ฐ ๋ ๊ฐ์ ์์์ ๊ฐ์ง – ์ผ์ชฝ(left) ๋ฐ ์ค๋ฅธ์ชฝ(right) ์์
์ข์ฐ ์์๋ ธ๋ ๊ฐ์ด๋ฐ ํ๋๊ฐ ๋น์ด ์๋ ๊ฒฝ์ฐ๋ผ๋ ์ ์ ์ด์งํธ๋ฆฌ๋ก ๊ตฌํ ๊ฐ๋ฅํ๋ค.
์ด์งํธ๋ฆฌ ADT ๋ฉ์๋
์ด์งํธ๋ฆฌ ADT๋ ํธ๋ฆฌ ADT์ ํ์ฅ์ด๋ค – ์ฆ, ํธ๋ฆฌ ADT์ ๋ชจ๋ ๋ฉ์๋๋ฅผ ์์ํ๋ค.
-์ถ๊ฐ์ ์ธ ๋ฉ์๋
node leftChild(v)
node rightChild(v)
node sibling(v)
์ด์งํธ๋ฆฌADT๋ฅผ ์ญ์ ๊ตฌํํ๋ ๋ฐ์ดํฐ ๊ตฌ์กฐ์ ๋ฐ๋ผ ์ถ๊ฐ์ ์ธ ๊ฐฑ์ ๋ฉ์๋ (์ฝ์ , ์ญ์ ๋ฑ) ์ ์๊ฐ ๊ฐ๋ฅํ๋ค!!
์ด์งํธ๋ฆฌ์ ๊น์ด์ ๋์ด
๋ ธ๋ v์ ๊น์ด(depth)์ ์ฌ๊ท์ ์ ์
- ๋ง์ฝ v๊ฐ ๋ฃจํธ๋ฉด, v์ ๊น์ด๋ 0
- ๊ทธ๋ ์ง ์์ผ๋ฉด, v์ ๊น์ด๋ v์ ๋ถ๋ชจ์ ๊น์ด ๋ํ๊ธฐ 1
๋ ธ๋v์ ๋์ด(height)์ ์ฌ๊ท์ ์ ์
- ๋ง์ฝ v๊ฐ ์ธ๋ถ๋ ธ๋๋ฉด, v์ ๋์ด๋ 0
- ๊ทธ๋ ์ง ์์ผ๋ฉด, v์ ๋์ด๋ v์ ์ผ์ชฝ๊ณผ ์ค๋ฅธ์ชฝ ์์ ์ค ์ต๋ ๋์ด ๋ํ๊ธฐ 1
์ด์งํธ๋ฆฌ ์ํ
์ด์งํธ๋ฆฌ์ ์ํ๋ ํธ๋ฆฌ์ํ์ ํนํ๋ค.
์ ์์ํ(preorder traversal): ๋
ธ๋๋ฅผ ๊ทธ์ ์ผ์ชฝ ๋ฐ ์ค๋ฅธ์ชฝ ๋ถํธ๋ฆฌ๋ณด๋ค ์์ ๋ฐฉ๋ฌธ
ํ์์ํ(postorder traversal): ๋
ธ๋๋ฅผ ๊ทธ์ ์ผ์ชฝ ๋ฐ ์ค๋ฅธ์ชฝ ๋ถํธ๋ฆฌ๋ณด๋ค ๋์ค์ ๋ฐฉ๋ฌธ
๋ ๊ฐ์ง ๋ฐฉ๋ฒ์ '๋ฐฉ๋ฌธ์ ์ธ์ ํ๋๋?' ์ ๋ฌ๋ ค์๋ค.
์ค์์ํ(inorder traversal): ๋ ธ๋๋ฅผ ๊ทธ์ ์ผ์ชฝ ๋ถํธ๋ฆฌ๋ณด๋ค๋ ๋์ค์, ์ค๋ฅธ์ชฝ ๋ถํธ๋ฆฌ๋ณด๋ค๋ ์์ ๋ฐฉ๋ฌธํ๋ค.
์ค์์ํ๋ ์ ๋๊ฐ์ง ๋ฐฉ๋ฒ๊ณผ ๋น์ทํ๊ฒ ๋ฐฉ๋ฌธ ์์๋ง ์ฐจ์ด๊ฐ ์๋ค.
ํ์ด์ฌ์ผ๋ก ํธ๋ฆฌ ๊ตฌํ
class Node:
def __init__(self,data,L=None,R=None,parent=None):
self.data = data
self.L = L
self.R = R
self.parent = parent
class tree:
def __init__(self):
self.root = None
self.n=0
def isEmpty(self):
return self.root==None
def treesize(self):
print(self.n)
return self.n
def rootnode(self):
#print(self.root)
return self.root.data
def parent(self,v):
if v == self.root:
print("Root Node")
else:
#print(v.parent.data)
return v.parent.data
def children(self,v):
return v.L.data,v.R.data
def element(self,v):
return v.data
def isInternal(self,v):
if v.L != None or v.R != None:
return True
else:
return False
def isExternal(self,v):
if v.L == None and v.R == None:
return True
else:
return False
def isRoot(self,v):
if self.root == v:
return True
else:
return False
def swapElements(self,v,w):
tmp = v.data
v.data = w.data
w.data = tmp
print(f"v.data : {tmp} => {v.data} / w.data : {v.data} => {w.data} ")
def setElements(self,v,e):
tmp = v.data
v.data = e
print(f"Succesly set element v.data : {tmp}=> {e}")
def addNode(self,v,data,location):
if location =='L':
v.L = Node(data,None,None,v)
self.n+=1
elif location == 'root':
self.root = Node('Root')
self.n+=1
else:
v.R = Node(data,None,None,v)
self.n+=1
>>> a = tree()
>>> a.addNode(None,None,'root')
>>> a.addNode(a.root,"root_left",'L')
>>> a.addNode(a.root,"root_right",'R')
>>> a.swapElements(a.root.L,a.root.R)
v.data : root_left => root_right / w.data : root_right => root_left
>>> print(a.isEmpty())
False
>>> a.treesize()
3
>>> print(a.rootnode())
Root
>>> print(a.children(a.root))
('root_right', 'root_left')
>>> a.swapElements(a.root.L,a.root.R)
v.data : root_right => root_left / w.data : root_left => root_right
>>> print(a.isInternal(a.root))
True
>>> print(a.isExternal(a.root))
False
>>> print(a.isInternal(a.root.L))
False
>>> print(a.isExternal(a.root.L))
True
>>> print(a.isRoot(a.root))
True
>>> print(a.isRoot(a.root.L))
False
>>> a.setElements(a.root.L,"LEFT")
Succesly set element v.data : root_left=> LEFT
>>> print(a.element(a.root.L))
LEFT
๋ฉ์๋๊ฐ ์ ์คํ๋๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.