[자료구조,Python] 파이썬으로 만들어보는 스택Stack

Updated:

Stack

Stack의 자료구조에서 핵심은 First in last out 입니다. 즉 제일 먼져 들어온 데이터블록이 제일 마즈막에 나갑니다.

다시한번 실과 빨간색 데이터 블록으로 예를 들어보죠. 이번에는 실 끝에 매듭을 묶어서 매달아 놓을 수 있게 만들어 놓았습니다.

이 그림처럼 말이죠. 이 그림을 보면 빨간색 데이터 블록은 묶여진 매듭에 의해 매듭이 묶여져 있지 않은 한쪽으로밖에 나가지 못합니다. 또 빨간색 데이터 블록을 빼낼 수 있는 출구가 하나밖에 없어서(매듭이 묶여져 있지 않은곳) 처음 들어간 데이터블록은 어쩔 수 없이 제일 마즈막에 나올 수 밖에 없습니다.

우리는 이와같은 현상을 First in Last Out 이라고 이야기합니다.

그리고 이것은 Stack의 모든 것 입니다.

Stack 에는 대표적인 2가지 메소드가 있다. pushpop 이다.

Push는 말 그대로 Push다. 실에 빨간색 데이터 블록을 밀어넣는 행동이라고 생각하면 편하다. 즉 데이터를 삽입하는 메소드 이다.
반면 POP 은 Push와 반대이다. 실에 있는 빨간색 데이터 블록을 뺴내오는 행동이라고 생각하면 편하다. 즉 데이터를 추출하는 메소드 이다.

우리는 singly linked list에서 시작과 끝 데이터 블록 수를 표현하는 Header , tail, size 로 구성했다.
하지만 눈치챌 사람들은 챌 수 있었듯이, 스택은 데이터의 삽입과 삭제가 한곳에서만 일어난다. 그렇기 떄문에 데이터 삽입에 활용한 tail을 스택에서는 필요가 없어진다.

스택에서는 제일 처음 데이터의 삽입과 추출이 이루워지는 TOP 과** 빨간색 데이터 블록 수 즉 데이터의 크기를 표현하는 Size** 이 두가지가 필요하다.

class Node

먼져 노드를 만들어야한다. 노드는 data라는 빨간색 블록과 data의 다음 값이 저장될 next를 필요로한다. 우리는 node 클래스에서 이 객체를 생성한다(push 와 pop을위하여).

class Node:
    def __init__(self,data):
        self.data = data
        self.next = None
    
    def get_data(self):
        return self.data
        #현재 data를 return 
        
    def get_next(self):
        return self.next
        #다음 data를 return
        
    def set_next(self, next):
        self.next = next
        #다음 data를 setting

Class Stack

우리는 위에서 이야기한 push 와 pop의 동작을 수행하는 메소드를 만들어 볼 것이다.

Push Method

def push(self,data):
    new_node = Node(data)
    self.size += 1
    if self.top == None:
        self.top = new_node
    else:
        new_node.set_next(self.top)
        self.top = new_node

저장된 값이없으면 top이 새로운 대이터를 가리키게 했고, 아닌경우는 새로운 데이터 다음값을 현재 top에 저장되어있는 데이터로 바꿔주고, 새로운 데이러를 top으로 지정했다.

Pop Method

def pop(self):
    topData = self.top
    if topData != None:
        self.top = topData.get_next()
        self.size -= 1
    return topData

top에 저장된 데이터가 없을때만 작동한다. top에 저장된 데이터가 없다는 뜻은 텅빈 노드만 있다는 의미와 같은의미이기 때문이다. top에 데이터가 있을경우, top은 다음 블록을 가리키게 한다.

내 코드

class Node:
    def __init__(self,data):
        self.data = data
        self.next = None
        
    def get_data(self):
        return self.data
    
    def get_next(self):
        return self.next
    
    def set_next(self, next):
        self.next = next
        
class Stack:
    def __init__(self):
        self.size = 0
        self.top = None
        
    def push(self,data):
        new_node = Node(data)
        self.size += 1
        if self.top == None:
            self.top = new_node
        else:
            new_node.set_next(self.top)
            self.top = new_node
            
    
    def pop(self):
        topData = self.top
        if topData != None:
            self.top = topData.get_next()
            #topData = topData.get_next()
            self.size -= 1
        return topData

        
    def print_stack(self):
        print(">> current stack")
        node = self.top
        while node != None:
            print(node.get_data())
            node = node.get_next()
        print(">>>>>>>>>>>")

stack = Stack()
stack.push("Apple")
stack.push("Kiwi")
stack.push("Banana")
stack.print_stack()

node = stack.get_at(0)
if node != None:
    print(node.get_data())
else:
    print("index error")
print(">>>>>>>>>>>>")
while True:
    node = stack.pop()
    if node is None:
        break
    else:
        print("Pop : " + node.get_data())
        if node == None:
            break
stack.print_stack()

topData = topData.get_next() 와 self.top = topData.get_next() 로 진행했을때 결과에 차이가 있었다.

나는 topData 라는 참조변수가 self.top을 참조하게끔 했다. 그 후 topData의 다음값을 topData로 저장했고, 그것을 리턴했다.

while문에의해 다시 pop메소드로 돌아왔을 때 우리는 self.top을 변경하지않고 topData만 변경했기 때문에 다시 apple이 topData에 참조되어있었다. 그렇기때문에 계속 Kiwi가 출력되었던 것이다.

출력값

>> current stack
Banana
Kiwi
Apple
>>>>>>>>>>>
Banana
>>>>>>>>>>>>
Pop : Banana
Pop : Kiwi
Pop : Apple
>> current stack
>>>>>>>>>>>

Leave a comment