배열과 스택의 차이점은 무엇입니까?


10

Wikipedia에 따르면 스택 :

LIFO (Last In, First Out) 추상 데이터 형식 및 선형 데이터 구조입니다.

배열 동안 :

은 적어도 하나의 배열 인덱스 또는 키로 식별되는 요소 (값 또는 변수) 모음으로 구성된 데이터 구조입니다.

내가 이해하는 한, 그들은 상당히 비슷합니다. 그렇다면 주요 차이점은 무엇입니까? 그것들이 동일하지 않다면, 스택이 할 수없는 것과 반대로 할 수있는 배열은 무엇입니까?


5
Wikipedia에서 찾은 내용으로 질문에 어떻게 대답하지 않습니까? 어떤 순서로든 배열의 요소에 액세스 할 수 있습니다. 스택은 LIFO 순서로 액세스해야합니다.
Caleb

8
@Caleb 무언가를 읽는다고해서 그 개념을 이해한다는 의미는 아닙니다. 내 마음에, 나는 물을 때까지 이것을 완전히 이해하지 못했습니다.
다이내믹

3
-1 당신은 기본적으로 자신의 질문에 답을 게시했습니다. 또 물어보고 싶은 게 뭐야?
Andres F.

1
@AndresF. 그것이 무엇을 의미하는지 알 수 없습니다 ... Wikipedia 기사를보고 그들이 처음 말하는 내용을 이해할 수 있다면 세상은 완벽 할 것입니다.
다이내믹

2
방금 meta.programmers를 읽고 왜 당신 이이 질문을하지 않은지 이해했습니다 : 그것은 경쟁을위한 것입니다. Wikipedia 기사를 이해하지 못했다고 의심합니다. 수치심 : /
Andres F.

답변:


45

글쎄, 당신은 확실히 배열로 스택을 구현할 수 있습니다. 차이점은 액세스입니다. 배열에는 요소 목록이 있으며 언제든지 요소에 액세스 할 수 있습니다. (나무 블록을 모두 한 줄에 배치한다고 생각하십시오.)

그러나 스택에는 임의 액세스 작업이 없습니다. 스택의 맨 위에있는 요소 만 처리하는 Push, Peek및 만 Pop있습니다. (수직으로 쌓인 나무 블록을 생각하십시오. 탑의 탑 아래에있는 어떤 것도 건드리지 않거나 넘어 질 것입니다.)


11
나무 블록-좋은 비유
Jesse Black

1
"스택에서 임의 액세스 작업이 없습니다"라고 말하지만 동의하지 않으며 답변에 더 자세한 내용을 추가합니다.
Scott Whitlock

스택은 확실히 랜덤 액세스로 구현
old_timer

4
젠가를 빨아야합니다.
DisgruntledGoat

1
@Mason, 알아 그것은 농담.
DisgruntledGoat

6

순수 스택에서 허용되는 유일한 작업은 Push, PopPeek하지만 실제적인면에서,이 정확히 사실이 아니에요. 또는 오히려 Peek작업을 통해 스택의 임의의 위치를 ​​볼 수 있지만 스택의 한쪽 끝을 기준으로하는 것이 좋습니다.

따라서 다른 사람들이 말했듯이 배열은 무작위 액세스이며 모든 것은 배열의 시작 부분을 참조합니다 .

스택에서는 스택의 작업 끝에서만 추가 / 제거를 수행 할 수 있지만 여전히 임의 액세스 읽기 권한이 있지만 작업 끝을 참조합니다 . 이것이 근본적인 차이점입니다.

예를 들어, 스택의 매개 변수를 함수에 전달할 때 수신자는 매개 변수를보기 위해 해당 매개 변수를 표시하지 않아도됩니다. 스택의 로컬 변수를 푸시하고 스택 포인터의 오프셋을 기반으로 모든 로컬 변수 및 매개 변수를 참조합니다. 배열 만 사용하는 경우 수신자는 해당 매개 변수를 찾을 위치를 어떻게 알 수 있습니까? 호출 수신자가 완료되면 로컬 변수를 제거하고 리턴 값을 푸시하고 제어를 호출자에게 리턴하며 호출자는 리턴 값 (있는 경우)을 팝한 다음 스택에서 매개 변수를 팝합니다. 장점은 함수 호출에 얼마나 멀리 중첩되어 있더라도 (스택 공간이 부족하지 않다고 가정) 작동한다는 것입니다.

그것은 하나의 특별한 사용 / 구현이지만 차이점을 보여줍니다 : 배열은 항상 처음부터 참조되지만 스택은 항상 일부 작업 끝 위치에서 참조됩니다.

스택의 가능한 구현 중 하나는 배열 작업 끝의 위치를 ​​기억하는 인덱스입니다.


나에게 이것은 답이다. 배열과 스택의 차이점이 무엇인지에 대한 질문은 배열이 덜 제약적이고 다목적 인 것처럼 보일 때 왜 스택이 필요한지에 달려 있습니다. 그리고 이것은 대답합니다 : 스택이 적절한 경우 (예 : 함수 호출)에서 그것을 사용하여 구현을 논리적으로 만드는 것이 더 제한되어 있기 때문입니다. Henco "아름다움"
Todanley

4

여기에서 가장 큰 혼란은 구현과 기본 데이터 구조입니다.

대부분의 (더 기본 언어) 배열은 주어진 시간에 액세스 할 수있는 고정 길이 요소 세트를 나타냅니다. 이와 같은 많은 요소가 있다는 사실은 그것이 어떻게 사용되어야하는지에 대해 아무 것도 알려주지 않습니다 (솔직히 컴퓨터는 사용법을 위반하지 않는 한 어떻게 사용하는지 알지 / 관리하지 않습니다).

스택은 특정 방식으로 처리해야하는 데이터를 나타내는 데 사용되는 추상화입니다. 이것은 상단에 추가하거나 상단에서 제거 할 수있는 일부 서브 루틴 / 메소드 / 기능이 있어야하지만 상단 아래의 데이터는 건드리지 않기 때문에 추상적 개념입니다. 이 방법으로 배열을 사용하기위한 선택입니다.

배열 (최대 크기), 동적 배열 (공간이 부족할 때 커질 수 있음) 또는 연결된 목록 등 다양한 종류의 데이터 구조에서 스택을 만들 수 있습니다. 개인적으로 링크 된 목록은 스택의 제한 사항을 가장 잘 표현한다고 생각합니다. 첫 번째 요소 이상의 것을보고 약간의 노력을 기울여야하며 앞에 추가하고 제거하기가 매우 쉽습니다.

따라서 배열을 사용하여 스택을 만들 수 있지만 동등하지는 않습니다.


3

그들의 책임은 다릅니다 :

  • 스택은 요소를 스택에 넣고 스택에서 요소를 푸시 할 수 있어야하므로 일반적으로 메소드 Pop()Push()

  • 배열의 책임은 지정된 인덱스에서 요소를 가져 오거나 설정하는 것입니다.


3

A \ array의 인덱스에서 항목을 검색 할 수 있습니다.

스택을 사용하면 다른 스택을 사용하여 스택 A의 중간에있는 항목을 검색 할 수 있습니다. B.

A에서 원하는 항목을 얻을 때까지 A에서 최상위 항목을 계속 가져와 B에 넣은 다음 B의 항목을 스택 A 위에 다시 놓습니다.

따라서 임의의 인덱스를 검색 할 수있는 데이터의 경우 스택을 처리하기가 더 어렵습니다.

"last in, first out"동작을 원하는 상황에서 스택은 어레이보다 오버 헤드를 줄입니다.


0

나는 그들이 "매우 비슷하다"고 말하지 않을 것입니다.

배열은 나중에 순차적으로 또는 인덱스를 통해 액세스 할 항목을 보유하는 데 사용됩니다. 데이터 구조는 어떤 종류의 액세스 방법 (FIFO, LIFO, FILO 등)을 의미하지는 않지만 원하는 경우 사용할 수 있습니다.

스택은 생성되는 것들을 추적하는 방법입니다. 생성 된 스택 유형에 따라 액세스 방법이 암시 적 / 필요합니다. 프레임 스택은 LIFO 예입니다. 면책 조항-여기에 내 데이터 구조 분류 체계를 혼합하고 스택은 실제로 LIFO 만 허용 할 수 있습니다. 그렇지 않으면 다른 유형의 대기열이됩니다.

그래서 배열을 스택으로 사용할 수는 있지만 (원하지는 않지만) 스택으로 배열을 사용할 수는 없습니다 (정말 열심히 노력하지 않는 한).


1
'객체 컬렉션을 저장하는 구조'영역에서 나는 그것들이 매우 유사하다고 말하지 않을 것입니다. 프로그래밍 개념의 영역에서 나는 그것들이 상당히 비슷하다고 말합니다. 일반적으로 사물 영역에서는 거의 동일하다고 말합니다.
Kirk Broadhurst

0

배열의 데이터는 키 또는 인덱스로 액세스 할 수 있습니다. 스택의 데이터가 스택 상단에서 튀어 나오면 액세스 할 수 있습니다. 즉, 인덱스를 알고 있으면 배열에서 데이터에 쉽게 액세스 할 수 있습니다. 스택에서 데이터에 액세스한다는 것은 찾고자하는 요소를 찾을 때까지 팝업 요소를 유지해야한다는 것을 의미하므로 데이터 액세스에 시간이 오래 걸릴 수 있습니다.


0

배열은 프로그래머의 관점에서 제자리와 크기에 고정되어 있으며, 위치와 전체 위치를 알고 있습니다. 모든 것에 액세스 할 수 있습니다.

스택을 사용하면 스택의 한쪽 끝에 앉아 있지만 크기 나 안전하게 얼마나 멀리 갈 수 있는지 모릅니다. 그것에 대한 액세스는 할당 된 양으로 제한되며, 힙이나 프로그램 공간에 딱 들어 맞으면 원하는 양을 할당 할 때조차 알지 못하는 경우가 종종 있습니다. 스택에 대한 관점은 자신이 할당 한 작은 배열이며, 원하는 크기이며, 제어하고 볼 수 있습니다. 귀하의 부분은 배열과 다르지 않습니다. 차이점은 배열과 다른 배열의 한쪽 끝에 고정되어 논란의 여지가없고, 크기가 크거나 작다는 것을 알지 못하며, 해를 입히지 않고 만질 수 없습니다. 전역이 아닌 배열은 어쨌든 스택에 구현되는 경우가 많으므로 배열과 스택은 해당 기능 기간 동안 동일한 공간을 공유합니다.

하드웨어 측면으로 들어가고 싶다면 물론 프로세서마다 다르지만 일반적으로 배열은 알려진 시작 지점 / 주소를 기반으로하며 크기는 컴파일러 / 프로그래머가 알고 있으며 주소는 그 주소로 계산됩니다. 때때로 레지스터 오프셋 어드레싱을 사용하여 (이 기본 레지스터 값에 의해 정의 된 주소에서이 오프셋 레지스터 값을 더한 값을로드 할 때와 같이 컴파일 할 때 반드시 레지스터 기반 일 필요는 없습니다. 물론 프로세서에 따라 다름) 높은 수준의 코드로 배열에 액세스하는 것과 유사합니다. 스택과 마찬가지로, 사용 가능한 경우 레지스터 또는 즉시 오프셋 주소 지정을 사용할 수 있습니다. 종종 스택 포인터 자체 또는 스택 프레임에 액세스하기 위해 컴파일러 / 프로그래머가 예약 한 레지스터를 사용하는 특수 레지스터를 사용하지만 함수. 또한 일부 프로세서의 경우 스택에 액세스하기 위해 특수 스택 액세스 기능이 사용됩니다. 푸시 및 팝 명령이 있지만이 질문에 실제로 적용하지 않는 것처럼 자주 사용되지는 않습니다. 일부 프로세서의 경우 push 및 pop은 스택의 스택 포인터뿐만 아니라 모든 레지스터와 함께 사용할 수있는 명령어의 별칭이며이 질문과 관련하여 push 및 pop을 추가로 제거합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.