C语言博客作业02--栈和队列

| 这个作业属于哪个班级 | 数据结构--网络2011,2012(集美大学) |
| ---- | ---- | ---- | ---- |
| 这个作业的地址 | C博客作业02--栈和队列
| 这个作业的目标 | 学习如何设计函数、C语言基本数据类型 |
| 姓名 | 张官德 |

0.PTA得分截图

1.本周学习总结(0-5分)

1.1栈

  • 栈是一种线性数据结构,栈的特征是数据的插入和删除只能通过一端来实现,这一端称为“栈顶”,相应的另一端称为“栈底”;另外其还有先进后出,后进先出的特征。

  • 顺序栈

    结构体

typedef struct 
{  ElemType data[MaxSize]; //栈中数据元素
   int top;		//top为栈顶指针
} Stack;
typedef Stack *SqStack;

顺序栈的基本操作

初始化操作

void InitStack(SqStack s)
{
    s = new SqStack;//分配一个顺序栈的空间,首地址存放s处
    s->top = -1;    //栈顶指针置为-1
}

判断栈是否为空

bool StackEmpty(SqStack s)
{
    if(s->top == -1) //栈为空返回true
    {
        return true;
    }
    return false;
}

出栈与入栈操作

//出栈
bool Pop(SqStack &s,ElemType e)
{
    if(StackEmpty(s))    //判断是否为空栈
    {
        return false;
    }
    e = s->data[s->top--];    //退栈
    return true;
}
* 出栈并没有将原来站内的数据删除,只是指针下移

//入栈
bool Push(SqStack &s,ElemType e)
{
    if(s->top == MAXSIZE - 1)    //判断是否栈满
    {
        return false;
    }
    s->data[s->top++] = e;    //入栈
    return true;
}

取栈顶

bool GetTop(SqStack s, ElemType e) {
	if (s->top == -1) {
		cout << "栈空";
		return false;
	}
	e = s->data[s->top];
	return true;
}

毁栈

void DestroyStack(SqStack s)
{
   delete s;
}
  • 链栈

    结构体
typedef struct StackNode
{
    ElemType data;
    struct StackNode *next;
}Node,*Stack;

顺序栈的基本操作

初始化操作

void CreatStack(LiStack &s)
{  
   s=new LiNode;
   s->next=NULL;
}

判断栈是否为空

bool StackEmpty(LiStack S)
{
	return (S->next == NULL);
}

入栈与出栈

//头插入栈
void Push(Stack& s, ElemType e)
{
	Stack p;
	p = new Node;
	p->data = e;		
	p->next = s->next;	
	s->next = p;
}

//出栈
bool Pop(LiStack& S, ElemType e)
{
	LiStack p;
	if (S->next == NULL)return false;//判断栈是否为空
	p = S->next;
	e = p->data;
	S->next = p->next;
	delete p;
	return true;
}

毁栈

void DestroyStack(Stack &s)
{ 
   Stack p;
   while (s!=NULL)
   {   p=s; 	
       s=s->next;
       delete p; 
   }
 }

1.2 栈的应用

栈是一个重要的数据结构,其特性简而言之就是“后进先出”,这种特性在计算机中有着广泛的运用。其实程序员无时无刻不在使用者栈,函数的调用是我们间接使用栈的最好的例子,但是栈在实际中的运用远不止这些,比较经典的应用还包括括号匹配、逆波兰表达式的求值等
例如符号配对

从第一个字符开始扫描
 当遇见普通字符时忽略,当遇见左符号时压入栈中
 当遇见右符号时从栈中弹出栈顶符号
 进行匹配
  匹配成功:继续读入下一个字符
  匹配失败:立即停止,并报错
 结束:
  成功:所有字符扫描完毕,且栈为空
  失败:匹配失败或所有字符扫描完毕但栈非空

1.3 队列

  • 1)队列(Queue)队列是一种先进先出的线性表。它只允许在表的一端进行插入,而在另一端进行删除。向队列中插入元素称为入队,从队列中删除元素称为出队。
    2)队首(front)允许进行删除的一端称为队首。

    3)队尾(rear)允许进行插入的一端称为队尾。

顺序队列


结构体

typedef struct 
{     ElemType data[MaxSize]; 
      int front,rear;      //队首和队尾指针
}Queue;
typedef Queue *SqQueue;

初始化

void InitQueue(SqQueue &q)
{	q=new Queue;
	q->front=q->rear=-1;
} 

入队

bool enQueue(SqQueue &q,ElemType e)
{  
    if (q->rear+1==MaxSize )
        return false;
                                       
	q->rear=q->rear+1;//队尾指针增加
	q->data[q->rear]=e;//数据纳入
	return true;
}

出队

bool deQueue(SqQueue &q,ElemType &e)
{	
    if (q->front==q->rear)  
	 return false;
	q->front=q->front+1;
	e=q->data[q->front];
	return true;
        //队首指针
}

毁队列

void DestroyQueue(SqQueue &q)
{
  delete q;
}

环队列###


环队列与顺序队列的结构体一样,只是初始化不同
初始化

void InitQueue(SqQueue &q)
{   q=new Queue;
    q->front=q->rear=0;
}

入队

bool enQueue(SqQueue &q,ElemType e)
{	if ((q->rear+1)%MaxSize==q->front)	
		return false;
	q->rear=(q->rear+1)%MaxSize;//与顺序队列不同之处
	q->data[q->rear]=e;
	return true;
}

出队

bool deQueue(SqQueue &q,ElemType &e)
{	if (q->front==q->rear)
		return false;
	q->front=(q->front+1)%MaxSize;
	e=q->data[q->front];
	return true;
}

链队列


结构体

    typedef struct node {
    ElemType data;
    struct node* next;
}QueueNode;
//定义头节点
typedef struct {
    QueueNode* front;
    QueueNode* rear;
}LinkQueue;

初始化

void InitQueue(LinkQueue* Q)
{
    Q->front = Q->rear = NULL;
}

是否为空

int QueueEmpty(LinkQueue* Q)
{
    return(Q->front == NULL && Q->rear == NULL);
}

入队

void EnLinkQueue(LinkQueue* Q, ElemType v)
{
    QueueNode* p;
    p = new QueueNode;//创立节点
    p->data = v;
    p->next = NULL;
    if (QueueEmpty(Q)) {
      Q->front = Q->rear = p;
     }
    else{
        Q->rear->next = p;  //尾插入列
        Q->rear = p;             //指向队列尾
    
}

出队

bool DeLinkQueue(LinkQueue* Q, ElemType &e)
{
    QueueNode* s;
    if (QueueEmpty(Q))
    return false;     //判断队列是否为空
    s = Q->front;
    e = s->data;
    if (Q->front == Q->rear)   
        Q->front = Q->rear = NULL;
    else
        Q->front = s->next;
    delete s;
    return true;
}

毁队列

Status DestroyQueue(LinkQueue& Q)
{
	while (Q.front)
	{
		Q.rear = Q.front->next;
		free(Q.front);
		Q.front = Q.rear;
	}
	return OK;
}

队列应用

int QueueLen(SqQueue Q) {
    return Q->rear - Q->front;
}
int EnQueue(SqQueue& Q, Person e) {
   
    Q->data[Q->rear] = e;
    Q->rear++;
    return 1;
}
int QueueEmpty(SqQueue& Q) {
    if (Q->front == Q->rear) {
        return 1;
    }
    else {
        return 0;
    }
}

int DeQueue(SqQueue& Q, Person& e) {
    e = Q->data[Q->front++];
    return 1;
}

void DancePartner(Person dancer[], int num) {
    int i = 0;
    Person e;
    for (i = 0; i < num; i++) {
        e = dancer[i];
        if (e.sex == 'F') {
            EnQueue(Fdancers, e);
        }
        else {
            EnQueue(Mdancers, e);
        }
    }
    while (!QueueEmpty(Fdancers) && !QueueEmpty(Mdancers)) {
        DeQueue(Fdancers,e);
        cout << e.name;
        DeQueue(Mdancers, e);
        cout << "  " << e.name << endl;
    }

}

#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <string>
#include <stack>
#include <queue>
using namespace std;

int main()
{
	queue<int>q;
	int n;
	int m;
	int i;
	int count = 0;
	int e;
	int flag = 0;

	cin >> n;//人数
	cin >> m;//出列的数
	if (m > n)
	{
		cout << "error!";
		return 0;
	}
	//入队
	for (i = 1;i <= n;i++)
	{
		q.push(i);
	}
	//报数
	while (!q.empty())
	{
		count++;
		if (count == m)//出队
		{
			if (flag == 0)
			{
				cout << q.front();
				flag = 1;
			}
			else
			{
				cout << " " << q.front();
			}
			q.pop();
			count = 0;
		}
		else if (count != m && !q.empty())//继续入队
		{
			e = q.front();
			q.push(e);
			q.pop();
		}
	}
	return 0;
}

2.PTA实验作业

符号配对

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

using namespace std;
struct SNode {
	char data[1000];
	int top;
};
typedef struct SNode* stack;

int main() {
	stack s;
	int i;
	s = new SNode;
	int flag = 0;
	s->top = -1;
	string str;
	
	while (1) {
		
		getline(cin, str);
		if (str[0] == '.') {
			break;
		}
		
		for (i = 0; str[i]; i++) {
			if (str[i] == '[' || str[i] == '{' || str[i] == '(') {
				
				s->top++;
				s->data[s->top] = str[i];
				
			}
			else if (str[i] == '/' && str[i + 1] == '*') {
				s->top++;
				s->data[s->top] = str[i];
				s->top++;
				s->data[s->top] = str[i + 1];
			}
			if (str[i] == ']' || str[i] == '}' || str[i] == ')'||(str[i]=='*'&&str[i+1]=='/')) {
				if (str[i] == ']' && s->data[s->top] == '['&&s->top!=-1) {
					s->top--;
				}
				else if (str[i] == '}' && s->data[s->top] == '{' && s->top != -1) {
					s->top--;
				}
				else if (str[i] == ')' && s->data[s->top] == '(' && s->top != -1) {
					s->top--;
				}
				else if (str[i] == '*' && str[i + 1] == '/' && s->data[s->top] == '*' && s->data[s->top - 1] == '/' && s->top != -1) {
					s->top--;
					s->top--;
				}
				else if (s->top == -1 && str[i] == ']') {
					
					flag = 1;
					break;
				}
				else if (s->top == -1 && str[i] == '}') {
					
					flag = 2;
					break;
				}
				else if (s->top == -1 && str[i] == ')') {
					
					flag = 3;
					break;
				}
				else if (s->top == -1 && str[i] == '/' && str[i - 1] == '*') {
					flag = 4;
					break;
				}
			}
		}
		
	}

	if (flag) {
		cout << "NO" << endl;
		cout << "?-]";
	}
	else if (flag == 2) {
		cout << "NO" << endl;
		cout << "?-}";
	}
	else if (flag == 3) {
		cout << "NO" << endl;
		cout << "?-)";
	}
	else if (flag == 4) {
		cout << "NO" << endl;
		cout << "?-*/";
	}


	if (s->top == -1 && flag == 0) {
		cout << "YES";
	}
	else if (s->top != -1 && s->data[s->top] == '[') {
		cout << "NO" << endl;
		cout << "[-?";
	}
	else if (s->top != -1 && s->data[s->top] == '{') {
		cout << "NO" << endl;
		cout << "{-?";
	}
	else if (s->top != -1 && s->data[s->top] == '(') {
		cout << "NO" << endl;
		cout << "(-?";
	}
	else if(s->top != -1 && s->data[s->top] == '*'&& s->data[s->top-1] == '/') {
		cout << "NO" << endl;
		cout << "/*-?";
	}
}

解题思路
遇到左符号就入栈,遇到右符号就出一个栈,如果到最后栈空可以判断匹配成功或者左边符号没有入栈过,若是第二种且有右符号则缺左符号,
若到最后栈不空则缺右符号。

知识点
栈的基本运用
include < string > 的运用

银行业务队列简单模拟

#include <stdio.h>
#include <stdlib.h>
#include<iostream>
using namespace std;
typedef int Position;
typedef struct SNode *PtrToSNode;
typedef struct {
    int *data;
    int front; 
    int rear; 
} Team;
typedef Team *SqTeam;
SqTeam Creat()
{
    SqTeam T = new Team;
    T->front = 0;
    T->rear = 0;
    T->data= (int*)malloc(1000 * sizeof(int));
    return T;
}
void push(SqTeam T,int a)
{
    T->data[T->rear++] = a;
    return;
}
int empty(SqTeam T)
{
    if (T->rear == T->front)return 0;
    return 1;
}
void pop(SqTeam T,int *flag)
{
    if (empty(T) && *flag == 1)
    {
        printf("%d", T->data[T->front++]); *flag = 0;
    }
    else if (empty(T) && *flag == 0)
        printf(" %d", T->data[T->front++]);

}

int main()
{
    SqTeam A, B;
    A = Creat();
    B = Creat();
    int n,i,a,*flag,f=1;
    flag = &f;
    cin >> n;
    for (i = 0; i < n; i++)
    {
        cin >> a;
        if (a % 2 != 0)push(A, a);
        else push(B, a);
    }
    while (empty(A) && empty(B))
    {
        pop(A,flag);
        pop(A,flag);
        pop(B,flag);
    }
    if (!empty(A))
    {
        while (empty(B))
        {
            pop(B, flag);
        }
    }
    if (!empty(B))
    {
        while (empty(A))
        {
            pop(A, flag);
        }
    }
    return 0;
}

1)将a,b客户入队到俩个不同队列
2)输出a两个,b一个
3)输出剩余队列的元素

知识点
队列的运用
出入关系明确

3.代码阅读


解题思路

解题代码

#include<iostream>
#include<queue>
using namespace std;
class Mystack
{
public:
    Mystack()
    {
        
    }
    void push(int x)
    {
        std::queue<int> temp_queue;
        temp_queue.push(x);
        while(!_data.empty())
        {
            temp_queue.push(_data.front());
            _data.pop();
        }
        while(!temp_queue.empty())
        {
            
            _data.push(temp_queue.front());
            temp_queue.pop();
        }
        
    }
    int pop()
    {
        int x=_data.front(); //取栈顶元素,即为队列头部元素
        _data.pop();
        return x;
    }
    int top()
    {
        return _data.front();//返回栈顶元素,即为直接范围队列头部元素
    }
    bool empty()
    {
        return _data.empty();
    }
private:
    std::queue<int> _data; //_data数据队列存储元素的顺序就是栈存储元素的顺序。
};
int main()
{
	Mystack S;
	S.push(1);
	S.push(2);
	S.push(3);
	S.push(4);
	printf("%d\n",S.top());
	S.pop();
	printf("%d\n",S.top());
	S.push(5);
	printf("%d\n",S.top());
	return 0;
	
} 

posted @ 2021-04-05 23:00  此处应该有名字  阅读(102)  评论(0编辑  收藏  举报