栈与对列 练习题

本文介绍如何通过双栈实现带有最小值查询的栈、队列与栈之间的相互转换,并探讨了入栈与出栈序列合法性的判断方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

###1.实现一个栈,要求实现Push(出栈)、Pop(入栈)、Min(返回最小值)的时间 复杂度为O(1)
#####创建2个栈 s 和 min ,入栈时,先入栈s,在判断是否<=栈min的top元素,如果是,则同时也入min栈,否则不入。
#####出栈时,如果s栈的top元素与min栈的top元素相等,则两个都出栈,否则只出s栈的top取min值时直接返回min栈top元素即可
function.h

#pragma once
#include"stack.h"

void minstack_push(Stack *s, Stack *min, DataType x)
{
	assert(s);
	assert(min);
	StackPush(s, x);
	if (min->_top == 0 || StackTop(min) >= x)
	{
		StackPush(min,x);
	}

}
void minstack_pop(Stack *s, Stack *min)
{
	assert(s);
	assert(min);
	if (StackTop(s) == StackTop(min))
	{
		StackPop(min);
	}
	StackPop(s);
}

int minstack_min(Stack *min)
{
	assert(min);
	
	return StackTop(min);

}

###2.使用两个栈实现一个队列
#####思路:创建两个栈s1和s2,
#####当要入数据时,只往s1当中入数据,
#####需要出数据时,先看s2里是否有元素,如果有,则先出s2内的数据,如果s2为空,则先将s1的数据依次导到s2中,再出数据。
function.h

#pragma once
#include"stack.h"

void double_stack_to_queue_push(Stack *s1,DataType x)
{
	assert(s1);
	StackPush(s1,x);
}
void double_stack_to_queue_pop(Stack *s1, Stack *s2)
{
	assert(s1);
	assert(s2);
	if (StackEmpty(s2) == 0)
	{
		printf("%d\t", StackTop(s2));
		StackPop(s2);
		return;
	}
	else
	{
		if (StackEmpty(s1) == 1)
		{
			printf("两个栈均无数据,无法出栈!");
			return;
		}
		while (StackEmpty(s1) == 0)
		{
			StackPush(s2, StackTop(s1));
			StackPop(s1);
		}
		printf("%d\t", StackTop(s2));
		StackPop(s2);
	}
}

###3使用两个队列实现一个栈
#####思路:创建2个队列 q1和q2,
#####入数据时,如果两个队列都为空,则往q1入数据,如果q1和q2中有一个为空,一个不为空,则往不为空的那个队列入数据(即一直保持一个队列为空
#####当要出数据时,将不为空的队列中的n-1个数据挪至为空的队列,这时候原本不为空的队列中只剩一个数据且是最后入的数据,pop掉即可。(仍然保持一个队列为空)
functions.h

#pragma once
#include"queue.h"

void double_queue_to_stack_push(Queue *q1, Queue *q2, DataType x)
{
	if (QueueEmpty(q1) == 0 && QueueEmpty(q2) == 0)//两个队列都空
	{
		QueuePush(q1, x);
	}
	else if (QueueEmpty(q1) == 0)//往不为空的那个队列入数据
	{
		QueuePush(q2, x);
	}
	else
	{
		QueuePush(q1, x);
	}
}

void double_queue_to_stack_pop(Queue *q1, Queue *q2)
{
	assert(q1);
	assert(q2);
	if (QueueEmpty(q1) == 0 && QueueEmpty(q2) == 0)
	{
		printf("两个队列均无数据!");
		return;
	}
	else if (QueueEmpty(q1) == 0)
	{
		size_t size2 = QueueSize(q2);

		while (size2 != 1)
		{
			QueuePush(q1, QueueFront(q2));
			QueuePop(q2);
			size2--;
		}
		printf("%d", QueueFront(q2));
		QueuePop(q2);
		q2->_tail = q2->_head;
	}
	else
	{
		size_t size1 = QueueSize(q1);
		while (size1 != 1)
		{
			QueuePush(q2, QueueFront(q1));
			QueuePop(q1);
			size1--;
		}
		printf("%d", QueueFront(q1));
		QueuePop(q1);
		q1->_tail = q1->_head;
	}

}

###4.元素出栈、入栈顺序的合法性。如入栈的序列(1,2,3,4,5),出栈序列为 (4,5,3,2,1)

#####思路:给定入栈序列与出栈序列,用2个指针分别指向他们。
#####如果指针所指内容相等,说明入栈后立刻出栈,两个指针都后移.
#####当指针所指内容不相等时,说明入栈序列的值可能暂时存在栈中,稍后会出栈,故对入栈指针进行后移操作,出栈指针不变。
#####等到入栈序列指针指向NULL后,说明此时要么出栈指针也为空,要么剩余出栈序列与栈内元素一 一匹配才合法。否则不合法。

#include <stdio.h>  
#include <stdlib.h>  
#define MaxSize 60   
#define OK      1        
#define ERROR   0        
#define TRUE    1        
#define FALSE   0      
typedef int ElemType;    
typedef int Status;    
typedef struct {    
    ElemType    data[MaxSize];    
    int         top1;                      
    int         top2;                     
}Stack,  *pStack;    
  
Status init_Stack(pStack S)  
{  
    S->top1 = -1;  
    S->top2 = MaxSize;  
    return OK;   
}  
  
Status push_Stack(pStack S, ElemType e, int stackNumber)  
{  
    if (S->top1+1 == S->top2)  
        return ERROR;  
    switch(stackNumber)  
    {  
        case 1:       
                S->data[++S->top1] = e;         
                break;  
        case 2:       
                S->data[--S->top2] = e;         
                break;  
    }  
    return OK;  
}  
  
  
Status pop_Stack(pStack S, ElemType *e, int stackNumber)  
{  
    if (1 == stackNumber)  
    {     
        if (-1 == S->top1)         
            return ERROR;  
        *e = S->data[S->top1--];  
    }  
    else if (2 == stackNumber)  
    {  
        if (MaxSize == S->top2)  
            return ERROR;  
        *e = S->data[S->top2++];  
    }  
    return OK;  
}  
  
  
Status dis_pStack(pStack S, int stackNumber)  
{  
    int i;  
    if (1 == stackNumber)  
    {  
        if (-1 == S->top1)  
            return ERROR;  
  
        printf("栈1中的元素为:\n");  
        for (i=0; i<=S->top1; ++i)  
            printf("%d ", S->data[i]);  
        printf("\n==================================\n");  
    }  
    else if (2 == stackNumber)  
    {  
        if (MaxSize == S->top2)  
            return ERROR;  
        printf("栈2中的元素为:\n");  
        for (i=MaxSize-1; i>=S->top2; --i)      
            printf("%d ", S->data[i]);  
        printf("\n==================================\n");  
    }  
}  
  
int main()  
{  
    printf("======共享栈===========\n\n");  
    Stack S;  
    ElemType e;  
    init_Stack(&S);  
    push_Stack(&S, 1, 1);  
    push_Stack(&S, 2, 1);  
    push_Stack(&S, 3, 1);  
    push_Stack(&S, 4, 1);  
    push_Stack(&S, 5, 1);  
    push_Stack(&S, 6, 1);  
    pop_Stack(&S, &e, 1);  
    push_Stack(&S, 10, 2);  
    push_Stack(&S, 9, 2);  
    push_Stack(&S, 8, 2);  
    push_Stack(&S, 7, 2);  
    dis_pStack(&S, 1);  
    dis_pStack(&S, 2);  
    return 0;  
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值