2014-02-15 3 views
1

대학의 선생님은 Stack의 구현에 대해 가르쳐 왔습니다. 그러나이 웹 사이트는 완전히 재귀 적이며 웹상의 어느 곳에서도 이와 같은 것을 보지 못했습니다. 그래서 나는 이것이 얼마나 훌륭하거나 효율적인지 궁금해하고있었습니다. Linked List (가장 효율적인 것)를 사용하고 배열을 사용하여 스택 구현을 많이 보았습니다.스택 재귀 구현 복잡성

public class Stack<T> 
{ 
    private T top; 
    private Stack<T> base; 

    public Stack(){ 
     top = null; 
     base = null; 
    } 

    public Stack(T data, Stack<T> base){ 
     top = data; 
     this.base = base; 
    } 

    public boolean isEmpty(){ 
     return top == null; 
    } 

    public T top(){ 
     return top; 
    } 

    public T push(T data){ 
     if (isEmpty()){ 
      top = data; 
      base = new Stack<T>(); 
     } else { 
      base = new Stack<T>(top, base); 
      top = data; 
     } 
     return data; 
    } 

    public T pop(){ 
     T res = null; 
     if (!isEmpty()){ 
      res = top; 
      top = base.top; 
      base = base.base; 
     } 
     return res; 
    } 
} 

다른 유형의 구현을 본적이 없으므로 의견을 듣고 싶습니다. 언제든지 복잡성을 설명하십시오!

+3

재귀는 어디에 있습니까? – rendon

+1

그래서 배열 대신 링크 된 목록을 기반으로하는 스택입니다. 푸시와 팝을위한 O (1)을 의미합니다. 어레이를 성장시키는 것에 대해 걱정할 필요가 없습니다. 무작위 액세스는 O (n)이지만, 일반적으로 스택이 사용되는 방식이 아닙니다. – Blorgbeard

+0

모든 작업은 O (1)입니다. 이 구현에서 잘못된 점을 보지 마십시오. –

답변

1

다른 사람들이 주석을 달았으므로,이 구현은 단일 연결 목록을 사용하는 반면 일반적인 구현에서는 스택을 보유하는 배열을 사용합니다.

그래서 나는 이것이 얼마나 효율적인지 또는 효율적인지 궁금합니다. 첫째

복잡성 :

  • 최고/평균/최악의 경우 시간 복잡도는 O(1)입니다.

  • 최상의/평균/최악의 경우의 공간 복잡도는 O(N)입니다.

비교 복잡성 :

  • 최상의 경우의 시간 복잡도는 어레이 구현과 동일하다 : O(1).

  • 최상의 구현 공간 복잡도는 어레이 구현시 동일합니다 (O(N)).

  • 평균 및 최악의 경우의 복잡성 비교는 다소 복잡합니다. 배열 기반 측정은 스택이 커지고 축소 될 때 스택의 배열을 다시 할당할지 여부 및 방법에 달려 있기 때문입니다. 그리고 그것은 구현에 따라 다릅니다.

비교 성능 (최상의 경우) : 각 push 호출이 새로운 객체를 생성하기 때문에

  • 이 연결리스트 버전으로 누르면 더 비싸다. (배열 기반 버전의 경우 가장 좋은 경우 배열에 빈 슬롯이 있으므로 재 할당이 필요하지 않습니다.)

  • 팝업은 객체에 도달 할 수 없기 때문에 간접적으로 비용이 많이 듭니다.

  • 최상의 경우 공간 사용은 목록 기반 구현에서 확실히 더 큽니다. 스택 항목은 2 개의 참조가있는 객체로 표현됩니다. 그것은 2 "단어"플러스 객체 헤더와 패딩입니다. 64 비트 JVM에서 ... 아마 24 바이트. 대조적으로, 배열 기반 솔루션은 각 엔트리에 대해 8 바이트 ... 배열에서 1 개의 참조를 사용합니다.

위에서 언급 한 이유로 평균 및 최악의 경우의 성능 및 공간 사용을 비교하기가 어렵습니다.

API 디자인 측면에서 볼 때 API는 누출이없는 추상화를 제공합니다. 내가 가진 유일한 단서는 빈 스택을 터뜨리는 것이다. 이어야한다. null을 호출하는 pop() 메서드는 호출자가 예기치 않은 (또는 예상 한) null 결과를 테스트하지 않으면 문제 (NPE)가 발생할 수 있습니다. 또한 null을 스택에 넣을 수 없습니다.

는 (사실, 거기에 버그가있다! 당신이 null, 그것은 "작품"을 추진하려고하지만 Stack.isEmpty() 스택이 비어있는 것을보고됩니다. 당신이 null를 집어 넣으려고 시도하는 경우 push 메소드가 예외를 throw합니다. ... 또는 적어도


주시기 바랍니다).에게 데이터 구조를 보호 복잡성을 설명!

직접 해결하면 더 배우게됩니다.

하지만이 사람은 완전히 재귀입니다 ...

논쟁의 여지가. 데이터 구조는 어떤 의미에서는 재귀 적이지만 알고리즘은 재귀를 수반하지 않습니다.