0
点赞
收藏
分享

微信扫一扫

【数据结构-栈 二】【单调栈】每日温度、接雨水

辰鑫chenxin 2023-10-14 阅读 15
数据结构

目录

队列的定义与结构

  队列的实现

队列的结构

初始化空队列

销毁队列

队尾入队列

队头出队列

获取队列头部元素

获取队列尾部元素

判断队列是否为空

获取队列长度

栈与队列经典试题

队列实现栈

栈实现队列


队列的定义与结构

  队列的实现

  • 空队列示意图

  •  空队列插入第一个元素示意图

  • 入队(单链表尾插)

  • 出队 (单链表头删)

队列的结构

typedef int QDataType;
typedef struct QueueNode
{
	QDataType data;//数据域
	struct QueueNode* next;//指针域-指向下一个队列结点
}QueueNode;

//当进行出队列操作(头删),需要修改队头指针,但是对于形参的修改不影响实参,只能传递二级指针;
//采取如下方案:将对头指针,队尾指针封装成结构体,只需要修改结构体指针即可修改结构体变量;
typedef struct Queue
{
	QueueNode* head;//队头指针
	QueueNode* tail;//队尾指针
	int size;//获取队列的长度
}Queue;

初始化空队列

void InitQueue(Queue* ps)
{
	assert(ps != NULL);

	ps->tail = ps->head = NULL;
	ps->size = 0;
}

销毁队列

void DestroyQueue(Queue* ps)
{
	assert(ps != NULL);
	QueueNode* cur = ps->head;
	while (cur != NULL)
	{
		QueueNode* next = cur->next;
		free(cur);
		cur= next;
	}
	ps->head = NULL;
	ps->tail = NULL;
	ps->size = 0;
}

队尾入队列

//队尾入队列(尾插)
void QueuePush(Queue* ps, QDataType x)
{
	assert(ps != NULL);
	//创建新队列结点
	QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));
	if (newnode == NULL)
	{
		perror("malloc failed:");
		exit(-1);
	}
	newnode->data = x;
	newnode->next = NULL;
	//入队列(尾插)
	//空队列时通过赋值完成尾插,队列中存在队列结点,按照逻辑关系完成连接;
	if (ps->tail == NULL)
	{
		ps->head = ps->tail = newnode;
	}
	else
	{
		ps->tail->next = newnode;
		ps->tail = newnode;
	}
	ps->size++;
}

队头出队列

//队头出队列(头删)
void QueuePop(Queue* ps)
{
	assert(ps != NULL);

	//空队列不可删
	assert(ps->tail != NULL);

	//出队列
	//队列中只有一个队列结点
	if (ps->head->next == NULL)
	{
		free(ps->head);
		ps->head = ps->tail = NULL;
	}
	//队列中有两个以上队列结点
	else
	{
		QueueNode* next = ps->head->next;
		free(ps->head);
		ps->head = next;
	}
	ps->size--;
}

获取队列头部元素

//获取队列头部元素
QDataType QueueFront(Queue* ps)
{
	assert(ps != NULL);
	//队列不为空
	assert(ps->head != NULL);

	return ps->head->data;
}

获取队列尾部元素

//获取队列尾部元素
QDataType QueueBack(Queue* ps)
{
	assert(ps != NULL);
	//队列不为空
	assert(ps->tail != NULL);

	return ps->tail->data;
}

判断队列是否为空

//判断队列是否为空
bool QueueEmpty(Queue* ps)
{
	assert(ps);
	if (ps->tail == NULL)
	{
		return true;
	}
	return false;
}

获取队列长度

//获取队列长度
int QueueLength(Queue* ps)
{
	assert(ps);

	return ps->size;
}

栈与队列经典试题

  • 队列实现栈

 

typedef struct 
{
  Queue q1;
  Queue q2;
} MyStack;

MyStack* myStackCreate() 
{
   MyStack* p=(MyStack*)malloc(sizeof(MyStack));

   InitQueue(&(p->q1));
   InitQueue(&(p->q2));
   return p;
}

//那个队列不为空,数据尾插到那个队列
void myStackPush(MyStack* obj, int x) 
{
if(!QueueEmpty(&(obj->q1)))
{
   QueuePush(&(obj->q1),x);
}
//队列q1为空,无论队列q2为不为空,数据尾插到q2;
else
{
    QueuePush(&(obj->q2),x);
}
}

int myStackPop(MyStack* obj) 
{
   //首先判断那个是空队列,假设法;
   Queue* Empty=&(obj->q1);
   Queue* NonEmpty=&(obj->q2);
   if(!QueueEmpty(&(obj->q1)))
   {
       Empty=&(obj->q2);
       NonEmpty=&(obj->q1);
   }
  //空队列为Empty,非空队列为NonEmpty;
  //由于队列中包含队列的长度,需要将非空队列的前size-1个数据插入到空队列;
  //队列每出一个数据,长度自动减一,当非空队列大于1个元素,不断将非空队列的数据插入到空队列;
  while(QueueLength(NonEmpty)>1)
  {
      QueuePush(Empty,QueueFront(NonEmpty));
      QueuePop(NonEmpty);
  }
  //非空队列只剩一个元素
  int top=QueueBack(NonEmpty);
  QueuePop(NonEmpty);
  return top;
}

int myStackTop(MyStack* obj) 
{
    //由于队列始终保持一个为空,取非空队列的对头元素即为栈顶元素
   if(!QueueEmpty(&(obj->q1)))
   {
       return QueueBack(&(obj->q1));
   }
   else
   {
       return QueueBack(&(obj->q2));
   }
}

bool myStackEmpty(MyStack* obj) 
{
    //栈为空当且仅当两个队列皆为空
   return QueueEmpty(&(obj->q1))&&QueueEmpty(&(obj->q2));
}

void myStackFree(MyStack* obj) 
{
   DestroyQueue(&(obj->q1));
   DestroyQueue(&(obj->q2));

   free(obj);
}
  • 栈实现队列

typedef struct 
{
    Stack pushstack;//入数据
    Stack popstack;//出数据
} MyQueue;

//初始化队列
MyQueue* myQueueCreate() 
{
    MyQueue* pst=(MyQueue*)malloc(sizeof(MyQueue));
    InitStack(&(pst->popstack));
    InitStack(&(pst->pushstack));
    return pst;
}

//数据入栈时全部存放于pushstack;
void myQueuePush(MyQueue* obj, int x) 
{
    StackPush(&(obj->pushstack),x);
}

//首先判断popstack栈是否为空,若popstack栈为空
//需要将pushstack栈中的数据全部送入popstack栈中;
//若popstack栈不为空,直接出数据,直到popstack为空;
int myQueuePop(MyQueue* obj) 
{
  if(StackEmpty(&(obj->popstack)))
  {
    //捯数据,将pushstack栈中的数据全部放入popstack栈中;
   while(!StackEmpty(&(obj->pushstack)))
   {
       StackPush(&(obj->popstack),StackTop(&(obj->pushstack)));
       StackPop(&(obj->pushstack));//干掉pushstack栈中栈顶元素
   }
  }
  //popstack栈不为空
   int top=StackTop(&(obj->popstack));
   StackPop(&(obj->popstack));
   return top;
}

//获取队头数据即popstack栈中即将出栈的第一个数据;
int myQueuePeek(MyQueue* obj)
{
  if(StackEmpty(&(obj->popstack)))
  {
    //捯数据,将pushstack栈中的数据全部放入popstack栈中;
   while(!StackEmpty(&(obj->pushstack)))
   {
       StackPush(&(obj->popstack),StackTop(&(obj->pushstack)));
       StackPop(&(obj->pushstack));//干掉pushstack栈中栈顶元素
   }
  }
  //popstack栈不为空
   return StackTop(&(obj->popstack));
}

//若队列为空当且仅当popstack与pushstack都为空;
bool myQueueEmpty(MyQueue* obj) 
{
   return StackEmpty(&(obj->pushstack))&&StackEmpty(&(obj->popstack));
}
//销毁队列
void myQueueFree(MyQueue* obj) 
{
    DestroyStack(&(obj->pushstack));
    DestroyStack(&(obj->popstack));
    free(obj);
}

                                                     

举报

相关推荐

0 条评论