【数据结构】特殊线性表练习

特殊线性表练习。 时间:2020-4-29

程序填空题

5-1 循环队列入队出队操作

循环队列入队出队操作。

#include<iostream>
using namespace std;

#define MAXQSIZE 100
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef char QElemType;
typedef char SElemType;
typedef int Status;

typedef struct {
    QElemType *base;
    int front;
    int rear;
} SqQueue;


Status InitQueue(SqQueue &Q) {
	Q.base=new QElemType[MAXQSIZE];
    if (!Q.base)
        exit(OVERFLOW); 
    
		Q.front=Q.rear=0; 
  
    return OK;
}


Status EnQueue(SqQueue &Q, QElemType e) {
    if ((Q.rear+1)%MAXQSIZE==Q.front) 
        return ERROR;
    Q.base[Q.rear] = e; 
    Q.rear=(Q.rear+1)%MAXQSIZE; 
    return OK;
}


Status DeQueue(SqQueue &Q, QElemType &e) {
    if (Q.front==Q.rear)
        return ERROR; 
    e = Q.base[Q.front]; 
    Q.front=(Q.front+1)%MAXQSIZE; 
    return OK;
}


int main() {
    SqQueue Q;
    int n, i; 
    char c;
    InitQueue(Q);
    cin >> n;
    for(i=0;i<n;i++){
        cin >> c;
        EnQueue(Q,c);        
    }
    for(i=0;i<n;i++){
        DeQueue(Q,c);
        cout << c << " ";
    }
    return 0;
}

5-2 链队入队出队操作

链队基本操作。

#include<iostream>
using namespace std;

#define OK 1
#define ERROR 0
typedef int Status;
typedef char QElemType;
typedef struct QNode {
    QElemType data;
    struct QNode *next;
} QNode, *QueuePtr;

typedef struct {
    QueuePtr front; 
    QueuePtr rear; 
} LinkQueue;

Status InitQueue(LinkQueue &Q) {
    Q.front = Q.rear = new QNode; 
    Q.front->next = NULL;
    return OK;
}

Status EnQueue(LinkQueue &Q, QElemType e) {
    QueuePtr p;
    p = new QNode; 
    p->data = e; 
    p->next = NULL;
    Q.rear->next=p; 
    Q.rear=p; 
    return OK;
}

Status DeQueue(LinkQueue &Q, QElemType &e) {
    QueuePtr p;
    if (Q.front == Q.rear)
        return ERROR; 
    p = Q.front->next; 
    e = p->data; 
    
	Q.front->next=p->next; 
    if (Q.rear == p)
    	Q.rear=Q.front; 
    delete p;
    return OK;
}

int main() {
    LinkQueue Q;
    int n,m,i; 
    char c;
    InitQueue(Q);
    cin >> n;
    for(i=0;i<n;i++){
        cin >> c;
        EnQueue(Q,c);        
    }
    for(i=0;i<n;i++){
        DeQueue(Q,c);
    }
    cin >> m;
    for(i=0;i<m;i++){
        cin >> c;
        EnQueue(Q,c);        
    }
    for(i=0;i<m;i++){
        DeQueue(Q,c);
        cout << c << " ";
    }
    return 0;
}

输入格式:
输入第一行为1个整数n,第二行输入n个字符,将n个字符依次入队,再执行n次出队操作(不输出)。
输入第三行为1个整数m,第四行输入m个字符,将m个字符依次入队,再执行m次出队操作并输出。

4
ABCD
5
12345

输出格式:

1 2 3 4 5 

函数题

6-1 另类堆栈

在栈的顺序存储实现中,另有一种方法是将Top定义为栈顶的上一个位置。请编写程序实现这种定义下堆栈的入栈、出栈操作。如何判断堆栈为空或者满?

函数接口定义:

bool Push( Stack S, ElementType X );
ElementType Pop( Stack S );

其中Stack结构定义如下:

typedef int Position;
typedef struct SNode *PtrToSNode;
struct SNode {
    ElementType *Data;  /* 存储元素的数组 */
    Position Top;       /* 栈顶指针       */
    int MaxSize;        /* 堆栈最大容量   */
};
typedef PtrToSNode Stack;

注意:如果堆栈已满,Push函数必须输出“Stack Full”并且返回false;如果队列是空的,则Pop函数必须输出“Stack Empty”,并且返回ERROR。

裁判测试程序样例:

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

#define ERROR -1
typedef int ElementType;
typedef enum { push, pop, end } Operation;
typedef enum { false, true } bool;
typedef int Position;
typedef struct SNode *PtrToSNode;
struct SNode {
    ElementType *Data;  /* 存储元素的数组 */
    Position Top;       /* 栈顶指针       */
    int MaxSize;        /* 堆栈最大容量   */
};
typedef PtrToSNode Stack;

Stack CreateStack( int MaxSize )
{
    Stack S = (Stack)malloc(sizeof(struct SNode));
    S->Data = (ElementType *)malloc(MaxSize * sizeof(ElementType));
    S->Top = 0;
    S->MaxSize = MaxSize;
    return S;
}

bool Push( Stack S, ElementType X );
ElementType Pop( Stack S );

Operation GetOp();          /* 裁判实现,细节不表 */
void PrintStack( Stack S ); /* 裁判实现,细节不表 */

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

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

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

输入样例:

4
Pop
Push 5
Push 4
Push 3
Pop
Pop
Push 2
Push 1
Push 0
Push 10
End

输出样例:

Stack Empty
3 is out
4 is out
Stack Full
0 1 2 5 

代码:

bool Push( Stack S, ElementType X )
{
	if(S->Top==S->MaxSize)
	{printf("Stack Full\n");return false;}
	else
	{
		S->Data[S->Top]=X;
		S->Top++;
		return true;
	}

}
ElementType Pop( Stack S )
{
	if(S->Top==0)
	{printf("Stack Empty\n");return ERROR;}
	else
	{
	ElementType e;
	e=S->Data[S->Top-1];
	S->Top--;
	return e;
	}
}

6-2 十进制转二进制(顺序栈设计和应用)

设计一个顺序栈,并利用该顺序栈将给定的十进制整整数转换为二进制并输出。

函数接口定义:

#define MaxSize 100    /* 栈最大容量 */
int top;        /* 栈顶指针 */
int mystack[MaxSize];    /* 顺序栈 */

/*判栈是否为空,空返回true,非空返回false */
bool isEmpty();

/* 元素x入栈 */
void Push(int x);

/* 取栈顶元素 */
int getTop();

/* 删除栈顶元素 */


void Pop();

其中 MaxSize 和 top 分别为栈的最大容量和栈顶指针。数组mystack 用来模拟顺序栈。请实现给出的isEmpty、Push、getTop和Pop这四个函数。

裁判测试程序样例:

#include <bits/stdc++.h>
using namespace std;

#define MaxSize 100        /* 栈最大容量 */
int top;                /* 栈顶指针 */
int mystack[MaxSize];    /* 顺序栈 */

/*判栈是否为空,空返回true,非空返回false */
bool isEmpty();

/* 元素x入栈 */
void Push(int x);

/* 取栈顶元素 */
int getTop();

/* 删除栈顶元素 */
void Pop();

/* 十进制正整数转换为二进制 */
void dec2bin(int x) {
    top = -1;            /* 初始化栈顶指针 */
    while (x) {
        Push(x % 2);
        x >>= 1;
    }
    while (!isEmpty()) {
        int t = getTop();
        Pop();
        printf("%d", t);
    }
    printf("\n");
}

int main(int argc, char const *argv[])
{
    int n;
    while (scanf("%d", &n) != EOF) {
        dec2bin(n);
    }
    return 0;
}

/* 请在这里填写答案 */

输入样例:

10

输出样例:

1010

代码:

bool isEmpty()
{
if(top==-1)
	return true;
else
	return false;
}

/* 元素x入栈 */
void Push(int x)
{   
   if(top<MaxSize)
	{mystack[++top]=x;}
}

/* 取栈顶元素 */
int getTop()
{int e;
e=mystack[top];
return e;
}

/* 删除栈顶元素 */
void Pop()
{
if(top!=-1)
top--;
}

编程题

7-1 堆栈操作合法性

假设以S和X分别表示入栈和出栈操作。如果根据一个仅由S和X构成的序列,对一个空堆栈进行操作,相应操作均可行(如没有出现删除时栈空)且最后状态也是栈空,则称该序列是合法的堆栈操作序列。请编写程序,输入S和X序列,判断该序列是否合法。

输入格式:
输入第一行给出两个正整数N和M,其中N是待测序列的个数,M(≤50)是堆栈的最大容量。随后N行,每行中给出一个仅由S和X构成的序列。序列保证不为空,且长度不超过100。

输出格式:
对每个序列,在一行中输出YES如果该序列是合法的堆栈操作序列,或NO如果不是。

输入样例:

4 10
SSSXXSXXSX
SSSXXSXXS
SSSSSSSSSSXSSXXXXXXXXXXX
SSSXXSXXX

输出样例:

YES
NO
NO
NO

代码:

#include <stdio.h>

int main()
{
	int n,m,i=0,j=0,cnt=0;
	char c[101];
	scanf("%d %d",&n,&m);
	getchar();

	for(;i<n;i++)
	{   scanf("%s",c);
	    cnt=0;j=0;

		while(c[j]!='\0')
		{
			if(c[j]=='S')
			{   cnt++;
				if(cnt==m+1)
				{break;}
				
			}
			else
			{
                 cnt--;
				if(cnt==-1)
				{break;}
				
			}
           j++;
         
		}
		if(cnt==0)
			printf("YES\n");
		else
			printf("NO\n");

		
	}
return 0;
}

7-2 括号匹配(难点)

给定一串字符,不超过100个字符,可能包括括号、数字、字母、标点符号、空格,编程检查这一串字符中的( ) ,[ ],{ }是否匹配。

输入格式:
输入在一行中给出一行字符串,不超过100个字符,可能包括括号、数字、字母、标点符号、空格。

输出格式:
如果括号配对,输出yes,否则输出no。

输入样例1:

sin(10+20)

输出样例1:

yes

输入样例2:

{[}]

输出样例2:

no

代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include<iostream>
using namespace std;
int main()
{
	char str[105],check[105];
	int i,top=-1,flag=1,flag2=0;
	char temp;
    cin.get(str,105);
	//scanf("%s",str);
	for(i=0;i<=strlen(str);i++){
		if(str[i]=='('||str[i]=='['||str[i]=='{')
		{   flag2++;
			top++;
			check[top]=str[i];
		}

		else if(str[i]==']'||str[i]==')'||str[i]=='}')
		{   flag2++;  
            if(top==-1)
              {flag=0;break;}
			  temp=check[top];top--;
             if ((str[i] == ')'&& temp !='(' )|| (str[i] == ']'&& temp != '[') || (str[i] == '}'&& temp!= '{'))
			 {flag=0;break;}
				
		}
       
	}		
	//if(i==101)
    //{printf("yes\n");return 0;}
	if(flag==0||top!=-1)
		printf("no\n");
    else 
        printf("yes\n");
    return 0;
}

7-3 表达式求值_1

在一个表达式中,只有“(”,“)”,“0-9”,“+”,“-”,“*”,“/”,“^”,请求出表达式的值。(“/”用整数除法)。

输入格式:
共1 行,为一个算式。 (算式长度<=30 其中所有数据在 0~2^31-1的范围内)。

输出格式:
共一行,为表达式的值。

输入样例:
在这里给出一组输入。例如:

1+(3+2)*(7^2+6*9)/(2)

输出样例:
在这里给出相应的输出。例如:

258

代码:

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

int CompareOpe(char a,char b)
{
	int n1=0,n2=0; 
	if(a=='*'||a=='/')
	{n1=1;}
	else if(a=='^')
	{n1=2;}
	else if(a=='(')
	{n1=3;}


	if(b=='*'||b=='/')
	{n2=1;}
	else if(b=='^')
	{n2=2;}
	else if(b=='(')
	{n2=3;}

	if(n1>n2)
		return 1;
	return 0;
}

int cal(int a,char c,int b)
{
	if(c=='-')
	return a-b;
	else if(c=='+')
	return a+b;
	else if(c=='*')
	return a*b;
	else if(c=='/')
	return a/b;
	else
	return (int)pow(a*1.0,b);
}

int main()
{

	char s[310],ope[310]={'0'}; 
	int num[310]={0};
	int top1=0,top2=0,i=0,flag=0;
	//cin.getline(s,310);
    //cin>>s;
	//char s[31]={'1','+','(','3','+','2',')','*','(','7','^','2','+','6','*','9',')','/','(','2',')'};
    //scanf("%s",s);
    gets(s);
    for(i=0;i<310;i++)
	{
		num[i]=0;ope[i]='0';
	}
    
	for(i=0;i<strlen(s);)
	{
		while(s[i]>='0'&& s[i]<='9')//入数
		{if(flag==0)
			{num[top1]=s[i++]-'0';flag=1;}
			else
			{num[top1]=num[top1]*10+s[i++]-'0';}
			continue;
		}
		if(flag==1)
			{top1++;}
			flag=0;
		if(s[i]=='(')
		{
			ope[top2++]=s[i];
		}
		else if(s[i]==')')
		{
			while(ope[top2-1]!='(') 
			{		
				num[top1-2]=cal(num[top1-2],ope[top2-1],num[top1-1]);
				num[top1-1]=0; 
				top2--;
				top1--; 
			}
			top2--;
		} 
		else
		{
			if(top2==0||CompareOpe(s[i],ope[top2-1])) 
			{
				ope[top2++]=s[i];
			}			
			else
			{
				while(!CompareOpe(s[i],ope[top2-1]))
				{
					if(ope[top2-1]=='(')
					{break;}
					num[top1-2]=cal(num[top1-2],ope[top2-1],num[top1-1]);
					num[top1-1]=0;
					top2--; 
					top1--; 
					if(top2==0)
						break; 
				}
				ope[top2++]=s[i]; 
			}
		} 
i++;
	}
	while(top1!=1&&top2>0)
	{
		num[top1-2]=cal(num[top1-2],ope[top2-1],num[top1-1]);
		top1--;
		top2--;	
	}
	printf("%d",num[0]);
	return 0;
}

7-4 银行业务队列简单模拟

设某银行有A、B两个业务窗口,且处理业务的速度不一样,其中A窗口处理速度是B窗口的2倍 —— 即当A窗口每处理完2个顾客时,B窗口处理完1个顾客。给定到达银行的顾客序列,请按业务完成的顺序输出顾客序列。假定不考虑顾客先后到达的时间间隔,并且当不同窗口同时处理完2个顾客时,A窗口顾客优先输出。

输入格式:
输入为一行正整数,其中第1个数字N(≤1000)为顾客总数,后面跟着N位顾客的编号。编号为奇数的顾客需要到A窗口办理业务,为偶数的顾客则去B窗口。数字间以空格分隔。

输出格式:
按业务处理完成的顺序输出顾客的编号。数字间以空格分隔,但最后一个编号后不能有多余的空格。

输入样例:

8 2 1 3 9 4 11 13 15

输出样例:

1 3 2 9 11 4 13 15

代码:

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

int main()
{
	int i=0,j=0,k=0;
	int flag=0;
	int A[1000],B[1000];
	int temp;
	scanf("%d",&k);

	while(k--)
	{scanf("%d",&temp);
	if(temp%2==0)
	{B[j]=temp;j++;}
	else
	{A[i]=temp;i++;}
	}
	B[j]=A[i]='\0';

	i=j=0;

	for(;B[j]!='\0';j++)
	{
		
			for(k=0;A[i]!='\0'&& k<2;i++,k++)
		    {
			if(flag==0)
			{printf("%d",A[i]);flag++;}
			else
				printf(" %d",A[i]);
		    }
		
		if(flag==0)
		{printf("%d",B[j]);flag++;}
		else
			printf(" %d",B[j]);
	}

	if(A[i]!='\0')
	{
	for(;A[i]!='\0';i++)
		    {
			if(flag==0)
			{printf("%d",A[i]);flag++;}
			else
				printf(" %d",A[i]);
		    }
	}
	return 0;

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值