C/C++ データ構造 --- 1 つの配列に 2 つのスタックを実装 (PTA)

ホームページ

まだまだ未知の部分が探索を待っている_データ構造、C言語の難しさ、小規模プロジェクト - CSDNブログ

トピック列---データ構造

データ構造_探索を待っている未知のブログがまだあります - CSDN ブログ

目次

I.はじめに        

2. タイトル

必要とする

関数インターフェース定義

審判試験手順サンプル

入力サンプル 

出力サンプル 

3. 分析 

1.スタックの特徴

2. 質問分析 

3. スタックの作成

4. スタックにプッシュします

5. ポップアウト 

4. 合計コード


I.はじめに        

 今日先生から出されたPTAの課題を書いていたら、今までとは違う山積みに出会ったので、みんなが輝けるように、視野を広げて、理解が深まるように書こうと思いました!

2. タイトル

必要とする

この質問では、配列に 2 つのスタックを実装する必要があります。

関数インターフェースの定義:

Stack CreateStack( int MaxSize ); //栈的创建
bool Push( Stack S, ElementType X, int Tag );//入栈 
ElementType Pop( Stack S, int Tag );//出栈

ここでTag、 はスタック番号 (1 または 2)、MaxSizeスタック配列のサイズです。

Stack構造は次のように定義されます。 

typedef int Position;
struct SNode {
    ElementType *Data;
    Position Top1, Top2;
    int MaxSize;
};
typedef struct SNode *Stack;

注: スタックがいっぱいの場合、Push関数は「Stack Full」を出力して false を返す必要があり、スタックが空の場合、関数はPop「Stack Tag Empty」(Tag はスタックの番号) を出力して ERROR を返す必要があります。

審判試験手順サンプル

#include <stdio.h>
#include <stdlib.h>

#define ERROR 1e8
typedef int ElementType;
typedef enum { push, pop, end } Operation;
typedef enum { false, true } bool;
typedef int Position;
struct SNode {
    ElementType *Data;
    Position Top1, Top2;
    int MaxSize;
};
typedef struct SNode *Stack;

Stack CreateStack( int MaxSize );//栈的创建
bool Push( Stack S, ElementType X, int Tag );//入栈
ElementType Pop( Stack S, int Tag );//出栈

Operation GetOp();  /* details omitted *///操作
void PrintStack( Stack S, int Tag ); /* details omitted *///打印

int main()
{
    int N, Tag, X;
    Stack S;
    int done = 0;

    scanf("%d", &N);
    S = CreateStack(N);
    while ( !done ) {
        switch( GetOp() ) {
        case push: 
            scanf("%d %d", &Tag, &X);
            if (!Push(S, X, Tag)) printf("Stack %d is Full!\n", Tag);
            break;
        case pop:
            scanf("%d", &Tag);
            X = Pop(S, Tag);
            if ( X==ERROR ) printf("Stack %d is Empty!\n", Tag);
            break;
        case end:
            PrintStack(S, 1);
            PrintStack(S, 2);
            done = 1;
            break;
        }
    }
    return 0;
}

/* 你的代码将被嵌在这里 */

入力サンプル 

5
Push 1 1
Pop 2
Push 2 11
Push 1 2
Push 2 12
Pop 1
Push 2 13
Push 2 14
Push 1 3
Pop 2
End

出力サンプル 

Stack 2 Empty
Stack 2 is Empty!
Stack Full
Stack 1 is Full!
Pop from Stack 1: 1
Pop from Stack 2: 13 12 11

3. 分析 

記述する前に、配列に 2 つのスタックを実装することが何を意味するのかを理解する必要があります。スタックは理解しやすく、線形テーブルの特殊な形式です。

スタックは、追加、削除、変更、確認の操作を完了できる通常のシーケンス テーブルとは異なり、プッシュとポップの操作のみを実行できます。操作の形式は少ないものの、スタックには独自の利点もあり、スタックのプッシュおよびポップの時間計算量は O(1) で、通常のシーケンス テーブルよりもはるかに高速です。

1.スタックの特徴

1. 後入れ先出し 2. スタックへのプッシュおよびポップの時間計算量は O(1)

スタックの一般的なデータ型は次のとおりです。

#define MaxSize 1000
typedef int elemtype; 
struct LNode
{
    elemtype data[MaxSize];
    int top;栈顶指针,存储的是栈顶上的下标
}

2. 質問分析 

図に示すように、タイトルに記載されている配列に基づいて 2 つのスタックを開きます。

スタックトップポインタ Top1 と Top2 の初期位置は、それぞれ -1 と MaxSize です。質問のTag変数にはスタック番号が格納されており、Tag==1の場合は先頭ポインタTop1のスタックを参照し、Tag==2の場合は先頭ポインタTop2のスタックを参照します。

Top1 を先頭ポインタとするスタックは通常スタック、Top2 を先頭ポインタとするスタックはリバース スタックです。スタックにプッシュするときは、先頭ポインタが左に移動することに注意してください。スタックをポップするときは、上のポインタが左に移動し、右に移動します。

図に示すように、スタックがいっぱいになったときの条件 (Top1+1==Top2) に注意してください。

3. スタックの作成

typedef int Position;
struct SNode {
    ElementType *Data;
    Position Top1, Top2;
    int MaxSize;
};
typedef struct SNode *Stack;

質問で指定されたスタックのタイプに従って、まず、スタック タイプ用のスペースとポインタ データ用のスペースを割り当てる必要があります。

次に、スタックの最上部にある 2 つの異なる変数に初期値を割り当てる必要があります。スタック タイプの MaxSize 変数にも初期値を割り当てる必要があることを忘れないでください。

Stack CreateStack(int MaxSize)
{
    Stack s = (Stack)malloc(sizeof(struct SNode));
    s->Data = (int*)malloc(sizeof(ElementType) * MaxSize);
    s->Top1 = - 1;
    s->Top2 = MaxSize;
    s->MaxSize = MaxSize;
    return s;
}

4. スタックにプッシュします

スタックにプッシュする前に、スタックがいっぱいかどうかを判断する必要があります。上記の説明によれば、S->Top1+1 == S->Top2 であることがわかります。いっぱいでない場合は、タグに従ってスタックの先頭ポインタが Top1 であるか Top2 であるかを判断します。最後に、先頭ポインター Top1++ または Top2-- から開始し、初期値を割り当てます。

bool Push(Stack S, ElementType X, int Tag)
{
    if (S->Top1+1 == S->Top2)
    {
        printf("Stack Full\n");
        return false;
    }
    if (Tag == 1)
    {
         S->Top1++;
         S->Data[S->Top1] = X;
    }
    if(Tag==2)
    {
        S->Top2--;
        S->Data[S->Top2] = X;
    }
    return true;
}

5. ポップアウト 

スタックのポップも同様で、まずスタックが空かどうかを判断し、空でない場合はトップポインタ Top1- または Top2++ を使用します。

ElementType Pop(Stack S, int Tag)
{
    if (Tag == 1)
    {
        if (S->Top1 == -1)       
        {
            printf("Stack %d Empty\n", Tag);
            return ERROR;
        }
        return S->Data[S->Top1--];   
    }

    if (Tag == 2)
    {
        if (S->Top2 == S->MaxSize) 
        {
            printf("Stack %d Empty\n", Tag);
            return ERROR;
        }
        return S->Data[S->Top2++];
    }
}

4. 合計コード

Stack CreateStack(int MaxSize)
{
    Stack s = (Stack)malloc(sizeof(struct SNode));
    s->Data = (int*)malloc(sizeof(ElementType) * MaxSize);
    s->Top1 = - 1;
    s->Top2 = MaxSize;
    s->MaxSize = MaxSize;
    return s;
}
bool Push(Stack S, ElementType X, int Tag)
{
    if (S->Top1+1 == S->Top2)
    {
        printf("Stack Full\n");
        return false;
    }
    if (Tag == 1)
    {
         S->Top1++;
         S->Data[S->Top1-1] = X;
    }
    if(Tag==2)
    {
        S->Top2--;
        S->Data[S->Top2+1] = X;
    }
    return true;
}
ElementType Pop(Stack S, int Tag)
{
    if (Tag == 1)
    {
        if (S->Top1 == -1)       
        {
            printf("Stack %d Empty\n", Tag);
            return ERROR;
        }
        return S->Data[S->Top1--];   
    }

    if (Tag == 2)
    {
        if (S->Top2 == S->MaxSize) 
        {
            printf("Stack %d Empty\n", Tag);
            return ERROR;
        }
        return S->Data[S->Top2++];
    }
}

ご協力ありがとうございました! 

おすすめ

転載: blog.csdn.net/qq_73435980/article/details/133386978