stack data structure c with illustration
내 인터넷 보안 키는 무엇입니까
C ++의 스택에 대해 알아야 할 모든 것.
스택은 선형 방식으로 요소를 저장하는 데 사용되는 기본 데이터 구조입니다.
스택은 다음과 같습니다 LIFO (후입 선출) 작업이 수행되는 순서 또는 접근 방식. 이는 스택에 마지막으로 추가 된 요소가 스택에서 제거되는 첫 번째 요소가됨을 의미합니다.
=> 모두를위한 전체 C ++ 교육 시리즈를 보려면 여기를 방문하십시오.
학습 내용 :
C ++에서 스택
스택은 실제 스택 또는 우리가 다른 하나 위에 쌓는 물건 더미와 유사합니다.
아래는 Stack의 그림 표현입니다.
위와 같이 서로 쌓인 접시 더미가 있습니다. 다른 항목을 추가하려면 위 그림 (왼쪽)과 같이 스택 맨 위에 추가합니다. 스택에 항목을 추가하는이 작업을 ' 푸시 ”.
오른쪽에는 반대 작업, 즉 스택에서 항목을 제거했습니다. 이것은 또한 동일한 끝, 즉 스택의 상단에서 수행됩니다. 이 작업을“ 팝 ”.
위의 그림에서 볼 수 있듯이 밀기와 팝이 같은 끝에서 수행되는 것을 볼 수 있습니다. 이것은 스택이 LIFO 순서를 따르도록합니다. 항목이 스택으로 밀려 들어가거나 튀어 나오는 위치 또는 끝을 ' 스택 상단 ”.
처음에는 스택에 항목이 없으면 스택의 맨 위가 -1로 설정됩니다. 스택에 항목을 추가하면 스택의 맨 위가 1 씩 증가하여 항목이 추가되었음을 나타냅니다. 이와 반대로 항목이 스택에서 튀어 나오면 스택의 맨 위는 1 씩 감소합니다.
다음으로 스택을 구현하는 동안 필요한 스택 데이터 구조의 몇 가지 기본 작업을 살펴 보겠습니다.
기본 작동
다음은 스택에서 지원하는 기본 작업입니다.
- 푸시 – 스택에 요소를 추가하거나 푸시합니다.
- 팝 - 스택에서 요소를 제거하거나 팝합니다.
- 엿보기 – 스택의 최상위 요소를 가져 오지만 제거하지는 않습니다.
- 가득 - 스택이 가득 찼는 지 테스트합니다.
- 비었다 - 스택이 비어 있는지 테스트합니다.
삽화
위의 그림은 스택에서 수행되는 작업 순서를 보여줍니다. 처음에는 스택이 비어 있습니다. 빈 스택의 경우 스택 맨 위가 -1로 설정됩니다.
다음으로 요소 10을 스택에 넣습니다. 이제 스택의 맨 위가 요소 10을 가리 킵니다.
다음으로 요소 20으로 또 다른 푸시 작업을 수행합니다. 그 결과 스택의 맨 위가 20을 가리 킵니다.이 상태가 세 번째 그림입니다.
이제 마지막 그림에서 팝 () 연산을 수행합니다. 팝 작업의 결과 스택 맨 위에있는 요소가 스택에서 제거됩니다. 따라서 그림에서 요소 20이 스택에서 제거되었음을 알 수 있습니다. 따라서 스택의 맨 위는 이제 10을 가리 킵니다.
이런 식으로 스택에서 사용하는 LIFO 접근 방식을 쉽게 이해할 수 있습니다.
이행
# 1) 어레이 사용
다음은 배열을 사용한 스택의 C ++ 구현입니다.
#include using namespace std; #define MAX 1000 //max size for stack class Stack { int top; public: int myStack(MAX); //stack array Stack() { top = -1; } bool push(int x); int pop(); bool isEmpty(); }; //pushes element on to the stack bool Stack::push(int item) { if (top >= (MAX-1)) { cout << 'Stack Overflow!!!'; return false; } else { myStack(++top) = item; cout< 산출:
스택 푸시
두
4
6
스택 팝 :
6
4
두
출력에서 요소가 한 순서로 스택에 푸시되고 역순으로 스택에서 튀어 나오는 것을 볼 수 있습니다. 이것은 스택에 대한 LIFO (Last in, First out) 접근 방식을 보여줍니다.
스택의 위 배열 구현의 경우 관련된 포인터가 없기 때문에 구현하기가 매우 쉽다는 결론을 내릴 수 있습니다. 그러나 동시에 스택의 크기는 정적이며 스택은 동적으로 늘어나거나 줄어들 수 없습니다.
다음으로 Java 프로그래밍 언어의 배열을 사용하여 스택을 구현합니다.
class Stack { static final int MAX = 1000; // Maximum Stack size int top; int myStack() = new int(MAX); boolean isEmpty() { return (top = (MAX-1)) { System.out.println('Stack Overflow'); return false; } else { myStack(++top) = item; System.out.println(item); return true; } } int pop() { if (top <0) { System.out.println('Stack Underflow'); return 0; } else { int item = myStack(top--); return item; } } } //Main class code class Main { public static void main(String args()) { Stack stack = new Stack(); System.out.println('Stack Push:'); stack.push(1); stack.push(3); stack.push(5); System.out.println('Stack Pop:'); while(!stack.isEmpty()) { System.out.println(stack.pop()); } } }
산출:
스택 푸시 :
1
삼
5
스택 팝 :
5
삼
1
구현 로직은 C ++ 구현과 동일합니다. 출력은 스택으로 /에서 요소를 밀어 넣거나 빼내는 LIFO 기술을 보여줍니다.
이미 언급했듯이 배열을 사용하는 스택 구현은 가장 간단한 구현이지만 스택을 동적으로 늘리거나 줄일 수 없기 때문에 정적 특성입니다.
# 2) 연결 목록 사용
다음으로, 우리는 C ++와 Java 모두에서 연결 목록을 사용하여 스택 작업을 구현합니다. 먼저 C ++ 구현을 시연합니다.
#include using namespace std; // class to represent a stack node class StackNode { public: int data; StackNode* next; }; StackNode* newNode(int data) { StackNode* stackNode = new StackNode(); stackNode->data = data; stackNode->next = NULL; return stackNode; } int isEmpty(StackNode *root) { return !root; } void push(StackNode** root, int new_data){ StackNode* stackNode = newNode(new_data); stackNode->next = *root; *root = stackNode; cout<data; free(temp); return popped; } int peek(StackNode* root) { if (isEmpty(root)) return -1; return root->data; } int main() { StackNode* root = NULL; cout<<'Stack Push:'< 산출:
스택 푸시 :
100
200
300
상단 요소는 300입니다.
스택 팝 :
300
200
100
상단 요소는 -1입니다.
다음으로 연결 목록을 사용하여 스택의 Java 구현을 제시합니다.
class LinkedListStack { StackNode root; static class StackNode { int data; StackNode next; StackNode(int data) { this.data = data; } } public boolean isEmpty() { if (root == null) { return true; } else return false; } public void push(int new_data) { StackNode newNode = new StackNode(new_data); if (root == null) { root = newNode; } else { StackNode temp = root; root = newNode; newNode.next = temp; } System.out.println(new_data); } public int pop() { int popped = Integer.MIN_VALUE; if (root == null) { System.out.println('Stack is Empty'); } else { popped = root.data; root = root.next; } return popped; } public int peek() { if (root == null) { System.out.println('Stack is empty'); return Integer.MIN_VALUE; } else { return root.data; } } } class Main{ public static void main(String() args) { LinkedListStack stack = new LinkedListStack(); System.out.println('Stack Push:'); stack.push(100); stack.push(200); stack.push(300); System.out.println('Top element is ' + stack.peek()); System.out.println('Stack Pop:'); while(!stack.isEmpty()){ System.out.println(stack.pop()); } System.out.println('Top element is ' + stack.peek()); } }
산출:
스택 푸시 :
100
200
300
상단 요소는 300입니다.
스택 팝 :
300
200
100
스택이 비어 있습니다.
상단 요소는 -2147483648입니다.
연결 목록을 사용하여 스택에 대한 C ++ 및 Java 구현을 방금 보았습니다. 우리는 각 스택 항목을 연결 목록의 노드로 나타냅니다. 이 구현의 가장 중요한 장점은 동적이라는 것입니다. 이는 요구 사항에 따라 스택 크기를 늘리거나 줄일 수 있음을 의미합니다.
이는 미리 크기를 선언해야하고 동적으로 변경할 수없는 배열을 사용하는 스택 구현의 경우와는 다릅니다.
이 구현의 단점은 모든 곳에서 포인터를 사용하기 때문에 배열 구현과 비교할 때 너무 많은 공간을 차지한다는 것입니다.
스택의 응용
스택 데이터 구조의 일부 응용 프로그램에 대해 논의 해 보겠습니다. 스택 데이터 구조는 주로 단순성과 구현 용이성으로 인해 소프트웨어 프로그래밍의 다양한 애플리케이션에서 사용됩니다.
아래에서 스택의 일부 응용 프로그램에 대해 간략하게 설명합니다.
# 1) 접미사에서 접미사로 표현
일반적인 산술 표현식은 다음과 같은 형식입니다. operand1 OP 피연산자 2 .
연산자 OP의 위치에 따라 다음과 같은 유형의 표현식이 있습니다.
- 중위 – 중위 표현의 일반적인 형식은“ operand1 OP 피연산자 2 ”. 이것은 표현의 기본 형식이며 우리는 항상 수학에서 사용합니다.
- 접두사 – 연산자가 피연산자 앞에 있으면 접두사 식입니다. 중위 표현의 일반적인 형식은“ OP 피연산자 1 피연산자 2 ”.
- 접미사 – 접미사 표현식에서 피연산자가 먼저 쓰여진 다음 연산자가옵니다. 형식은 'operand1 operand2 OP'입니다.
“a + b * c ' . 컴파일러는 표현식을 왼쪽에서 오른쪽으로 또는 오른쪽에서 왼쪽으로 스캔합니다. 연산자 우선 순위와 연관성을 고려하여 먼저 표현식을 스캔하여 표현식 b * c를 평가합니다. 다음으로, b * c의 결과를 a에 추가하기 위해 표현식을 다시 스캔해야합니다.
표현이 점점 더 복잡 해짐에 따라 표현을 반복해서 스캔하는 이러한 접근 방식은 비효율적입니다.
이러한 비 효율성을 극복하기 위해 스택 데이터 구조를 사용하여 쉽게 평가할 수 있도록 표현식을 접미사 또는 접두사로 변환합니다.
# 2) 식 구문 분석 / 평가
스택을 사용하여 실제 표현식 평가도 수행 할 수 있습니다. 여기서 표현식은 왼쪽에서 오른쪽으로 스캔되고 피연산자는 스택으로 푸시됩니다.
연산자를 만날 때마다 피연산자가 튀어 나와 연산이 수행됩니다. 작업 결과가 다시 스택으로 푸시됩니다. 이런 식으로 스택을 사용하여 표현식을 평가하고 표현식의 최종 결과는 일반적으로 스택의 현재 맨 위입니다.
# 3) 트리 순회
트리 데이터 구조는 우리가 방문한 루트 노드에 따라 다양한 방법으로 각 노드를 방문하기 위해 순회 될 수 있습니다.
- inOrder 순회
- 순회 사전 주문
- postOrder 순회
트리를 효율적으로 순회하기 위해 순회 순서를 유지하기 위해 스택의 중간 노드를 푸시하기 위해 스택 데이터 구조를 사용합니다.
# 4) 정렬 알고리즘
빠른 정렬과 같은 정렬 알고리즘은 스택 데이터 구조를 사용하여보다 효율적으로 만들 수 있습니다.
# 5) 하노이 타워
이것은 n 개의 디스크와 3 개의 타워를 포함하는 고전적인 문제이며, 문제는 중간으로 사용되는 세 번째 타워를 사용하여 디스크를 한 타워에서 다른 타워로 이동하는 것과 관련이 있습니다.
예제 및 구문이 포함 된 유닉스 명령
이 문제는 스택이 기본적으로 디스크를 이동하는 데 사용되는 타워 역할을하므로 스택으로 이동할 디스크를 밀어 넣을 때 스택을 사용하여 효율적으로 해결할 수 있습니다.
결론
스택은 가장 단순한 데이터 구조이며 프로그램으로 구현하기 쉽습니다. 마지막으로 입력 된 요소가 먼저 제거되는 요소임을 의미하는 LIFO (last in, first out) 방식을 사용했습니다. 이는 스택이 요소를 추가 (푸시) 및 제거 (팝)하는 데 한쪽 끝만 사용하기 때문입니다.
스택 데이터 구조는 소프트웨어 프로그래밍에서 많이 사용됩니다. 그중에서 눈에 띄는 것은 표현 평가입니다. 식 평가에는 식을 중위에서 접미 또는 접두사로 변환하는 것도 포함됩니다. 또한 최종 결과를 생성하기 위해 표현식을 평가하는 것도 포함됩니다.
이 튜토리얼에서 우리는 스택의 그림과 구현뿐만 아니라 다양한 작업을 보았습니다.
다가오는 자습서에서는 대기열 데이터 구조에 대해 자세히 알아 봅니다.
=> 전문가의 전체 C ++ 과정을 보려면 여기를 방문하십시오.
추천 도서