スタックシミュレーションによるキューの実現(C言語版)

ここに画像の説明を挿入

序文

使用"スタックはキューを実装します「」は Likou の oj 質問で、「スタック」と「キュー」を初めて使用する初心者がスタックとキューの 2 つの構造をよりよく理解するのに役立ちます。

このトピックはLeetcodeからのものです:
トピックリンク: https://leetcode.cn/problems/implement-queue-using-stacks/
難易度: 簡単

1. キューのインターフェイス:

1.1 型宣言 (MyQueue):

//模拟队列类型的声明
typedef struct {
    
    
    ST stackpush;		//用于模拟队列的 入队操作
    ST stackpop;		//用于模拟队列的 出队操作
} MyQueue;

ここでは、シミュレーションキューに 2 つのスタックを使用します
①:stackpushシミュレーションキューに入る
②:stackpopシミュレーションキューから出る

ここに画像の説明を挿入

1.2 初期化 (myQueueCreate):

キューは 2 つのスタックによって実装されているため、2 つのスタックの初期化に注目してください。

ステップ:

  1. 2スタックサイズのスペースを申請し、
    申請が失敗した場合に判定します。
  2. キュー内の 2 つのスタックについては、それらのスタックを呼び出します初期化機能 (これをお見逃しなく、Niu Niu はこれを見逃してから長い間探していました)
//队列的初始化
MyQueue* myQueueCreate() {
    
    
	//给队列开辟空间
    MyQueue* obj=(MyQueue*)malloc(sizeof(MyQueue));
    if(obj==NULL)
    {
    
    
        perror("obj malloc fail");
    }
    //一定要记得这里要初始化(别漏掉了哦)
    InitST(&obj->stackpush);
    InitST(&obj->stackpop);
    return obj;
}

1.3 キューに入る (myQueuePush)

キューに入るシミュレーションの実装は非常に簡単で、データをスタックにプッシュするだけです (キューに入るシミュレーション: stackpush)。

void myQueuePush(MyQueue* obj, int x) {
    
    
    assert(obj);
    STPush(&obj->stackpush,x);
}

1.4 キューアウト (myQueuePop)

機能要件:
チームの最初の要素をデキューし、デキューされたばかりのチームの最初の要素を返します。

デキューのシミュレーションは比較的複雑です。

  1. 初期状態またはstackpop(シミュレートされた)デキューするデータがキューから出て空の場合はデータが無いので、まずstackpopデータがあるかどうかを判断し、データがある場合:直接
    取得しますstackpopスタックトップ要素としてチームリーダー要素。
    データなし: シミュレートされたエンキュー スタックからすべてのデータを反転します (データを反転)
  2. 取得したstackpop_スタックトップ要素としてチームリーダー要素はtop変数を使って記録します(後で実行するため)飛び出る操作します)。
  3. 飛び出る(キューから出てシミュレーション)、top変数を返します。
int myQueuePop(MyQueue* obj) {
    
    
     assert(obj);
     if(STEmpty(&obj->stackpop))//如果栈(stackpop模拟出队列的栈)为空,则向栈(stackpush模拟入队列的栈)要数据
     {
    
    
     		//下面循环结束的条件是不为空
          while(!STEmpty(&obj->stackpush))//将数据从模拟入队列栈全部倒过来
        {
    
    
            //将栈(stackpush模拟入队)的栈顶元素依次压入栈(stackpop模拟出栈)
            STPush(&obj->stackpop,STTop(&obj->stackpush));
            STPop(&obj->stackpush);
        }
     }
    int top=STTop(&obj->stackpop);//记录用来模拟出队列的栈的栈顶元素;
    STPop(&obj->stackpop);
    return top;
}

1.5 キューの空判定(myQueueEmpty)

どちらのスタックにも要素がない場合、キューは空になります。

//書き込み1

bool myQueueEmpty(MyQueue* obj) {
    
    
    if(STEmpty(&obj->stackpush)&&STEmpty(&obj->stackpop))//如果都为空,则为空栈
    {
    
    
        return true;
    }
    else 
    return false;
}

//書き込み2.

bool myQueueEmpty(MyQueue* obj) {
    
    
    return STEmpty(&obj->stackpush)	&&	STEmpty(&obj->stackpop);
}

1.6 キューの最初の要素 (myQueuePeek) に戻ります。

  1. stackpop空でない場合、チームの最初の要素はstackpopスタックになります。エレメント。
  2. stackpop空の場合、チームの最初の要素はstackpushスタックです終わりしたがって、
    ここにもデータを注ぐ必要があります。
int myQueuePeek(MyQueue* obj) {
    
    
    assert(obj);
    if(STEmpty(&obj->stackpop))//如果栈(stackpop模拟出队列)为空,则向栈(stackpush模拟入队列)要数据
     {
    
    
        while(!STEmpty(&obj->stackpush))
        {
    
    
            //将栈(stackpush模拟入队)的栈顶元素依次压入栈(stackpop模拟出队列)
            STPush(&obj->stackpop,STTop(&obj->stackpush));
            STPop(&obj->stackpush);
        }
    }
    int top=STTop(&obj->stackpop);//记录用来模拟出队列的栈的栈顶元素;
    return top;
}

(デキュー) 関数と比較すると、この関数はキューの最初の要素を返すだけであり、デキュー操作myQueuePopを指していないため、関数の実装時に関数を再利用できます。pop
myQueuePopmyQueuePeek

int myQueuePop(MyQueue* obj) {
    
    
    int top=myQueuePeek(obj);
    STPop(&obj->stackpop);
    return top;
}

1.7 キューの破棄 (myQueueFree):

  1. 2 つのスタックの初期化によって空いたスペースを解放します。
  2. キューによって要求されたスペースを解放します。
void myQueueFree(MyQueue* obj) {
    
    
    STDestory(&obj->stackpush);
    STDestory(&obj->stackpop);
    free(obj);
}

次に、コード全体:

C 言語は C++ のようにライブラリを直接呼び出すことができないため、前のコードはスタックの実装です。

typedef  int stacktype;

typedef struct stack//定义栈的类型
{
    
    
	stacktype* data;
	int top;
	int capacaity;
}ST;
void InitST(ST* ps);//初始化栈
void STPush(ST* ps, stacktype x);//压栈
void STPop(ST* ps);//出栈
bool STEmpty(ST* ps);//判断是否为空栈
stacktype STTop(ST* ps);//返回栈顶元素
void STDestory(ST* ps);//栈的销毁

void InitST(ST* ps)//初始化栈
{
    
    
	assert(ps);
	ps->top = -1;
	ps->capacaity = 4;
	ps->data = (stacktype*)malloc(ps->capacaity * sizeof(stacktype));

}

void STPush(ST* ps, stacktype x)//压栈
{
    
    
	assert(ps);
	if (ps->top+1 == ps->capacaity)
	{
    
    
		ps->capacaity *= 2;
		ST* tmp = (stacktype*)realloc(ps->data, ps->capacaity * sizeof(stacktype));
		if(tmp == NULL)
		{
    
    
			printf("增容失败\n");
		}
		ps->data = tmp;
	}
	ps->top++;
	ps->data[ps->top] = x;
	
}


void STPop(ST* ps)//出栈
{
    
    
	assert(ps);
	assert(!STEmpty(ps));
	ps->top--;
}

bool STEmpty(ST* ps)//判断是否为空栈,是空返回真
{
    
    
	assert(ps);
	if (ps->top == -1)
	{
    
    
		return true;
	}
	return false;
}
stacktype STTop(ST* ps)//返回栈顶元素
{
    
    
	assert(ps);
	return ps->data[ps->top];
}
void STDestory(ST* ps)//销毁栈
{
    
    
	assert(ps);
	free(ps->data);
	ps->data = NULL;
	ps->top = -1;
	ps->capacaity = 0;
}


//模拟队列类型的声明
typedef struct {
    
    
    ST stackpush;
    ST stackpop;
} MyQueue;

//队列的初始化
MyQueue* myQueueCreate() {
    
    
    MyQueue* obj=(MyQueue*)malloc(sizeof(MyQueue));
    if(obj==NULL)
    {
    
    
        perror("obj malloc fail");
    }
    //一定要记得这里要初始化
    InitST(&obj->stackpush);
    InitST(&obj->stackpop);
    return obj;
}

void myQueuePush(MyQueue* obj, int x) {
    
    
    assert(obj);
    STPush(&obj->stackpush,x);
}

int myQueuePop(MyQueue* obj) {
    
    
     assert(obj);
     if(STEmpty(&obj->stackpop))//如果栈(stackpop模拟出栈)为空,则向栈(stackpush模拟入栈)要数据
     {
    
    
          while(!STEmpty(&obj->stackpush))
        {
    
    
            //将栈(stackpush模拟入队)的栈顶元素依次压入栈(stackpop模拟出栈)
            STPush(&obj->stackpop,STTop(&obj->stackpush));
            STPop(&obj->stackpush);
        }
     }
    int top=STTop(&obj->stackpop);//记录用来模拟出队列的栈的栈顶元素;
    STPop(&obj->stackpop);
    return top;
}


bool myQueueEmpty(MyQueue* obj) {
    
    
    if(STEmpty(&obj->stackpush)&&STEmpty(&obj->stackpop))//如果都为空,则为空栈
    {
    
    
        return true;
    }
    else 
    return false;
    //return STEmpty(&obj->stackpush)&&STEmpty(&obj->stackpop);
}

int myQueuePeek(MyQueue* obj) {
    
    
    if(STEmpty(&obj->stackpop))//如果栈(stackpop模拟出栈)为空,则向栈(stackpush模拟入栈)要数据
     {
    
    
        while(!STEmpty(&obj->stackpush))
        {
    
    
            //将栈(stackpush模拟入队)的栈顶元素依次压入栈(stackpop模拟出栈)
            STPush(&obj->stackpop,STTop(&obj->stackpush));
            STPop(&obj->stackpush);
        }
    }
    int top=STTop(&obj->stackpop);//记录用来模拟出队列的栈的栈顶元素;
    return top;
    //return STTop(&obj->stackpop);
}


void myQueueFree(MyQueue* obj) {
    
    
    STDestory(&obj->stackpush);
    STDestory(&obj->stackpop);
    free(obj);
}

操作結果:
ここに画像の説明を挿入

おすすめ

転載: blog.csdn.net/qq_67276605/article/details/131138092