线性表实验

实验目的与要求

实验目的:

  1. 线性表的逻辑结构特点和线性表抽象数据类型的描述方法
  2. 线性表的两类存储结构设计方法以及各自的优缺点
  3. 掌握线性表的基本知识
  4. 深入理解、掌握并灵活运用线性表。
  5. 熟练掌握线性表的存储结构及主要运算的实现
  6. 掌握栈的定义、栈的逻辑结构特性和栈的基本运算。
  7. 理解栈在表达式求值中的应用。
  8. 掌握队列的定义、队列的逻辑结构特性和栈的基本运算。
  9. 理解队列的应用。

实验要求:

编程实现如下功能:

递增有序顺序表的插入

1、已知顺序表L递增有序,将X插入到线性表的适当位置上,保证线性表有序。

输入格式:

第1行输入顺序表长度,第2行输入递增有序的顺序表,第3行输入要插入的数据元素X。

输出格式

对每一组输入,在一行中输出插入X后的递增的顺序表。

  两个有序链表序列的交集

2、已知两个非降序链表序列S1与S2,设计函数构造出S1与S2的交集新链表S3。

输入格式:

输入分两行,分别在每行给出由若干个正整数构成的非降序序列,用−1表示序列的结尾(−1不属于这个序列)。数字用空格间隔。

输出格式:

在一行中输出两个输入序列的交集序列,数字间用空格分开,结尾不能有多余空格;若新链表为空,输出NULL

简单计算器

3、本题要求你为初学数据结构的小伙伴设计一款简单的利用堆栈执行的计算器。如上图所示,计算器由两个堆栈组成,一个堆栈 S1 存放数字,另一个堆栈 S2存放运算符。计算器的最下方有一个等号键,每次按下这个键,计算器就执行以下操作:

  1. 从 S​1​​ 中弹出两个数字,顺序为 n​1​​ 和 n​2​​;
  2. 从 S​2​​ 中弹出一个运算符 op;
  3. 执行计算 n​2​​ op n​1​​;
  4. 将得到的结果压回 S​1​​。

直到两个堆栈都为空时,计算结束,最后的结果将显示在屏幕上。

输入格式:

输入首先在第一行给出正整数 N1<N≤103),为 S1 中数字的个数。

第二行给出 N 个绝对值不超过 100 的整数;第三行给出 N−1 个运算符 —— 这里仅考虑 +-*/ 这四种运算。一行中的数字和符号都以空格分隔。

输出格式:

将输入的数字和运算符按给定顺序分别压入堆栈 S1  S2,将执行计算的最后结果输出。注意所有的计算都只取结果的整数部分。题目保证计算的中间和最后结果的绝对值都不超过 109

如果执行除法时出现分母为零的非法操作,则在一行中输出:ERROR: X/0,其中 X 是当时的分子。然后结束程序。

输入样例 1

5

40 5 8 3 2

/ * - +

输出样例 1

2

输入样例 2

5

2 5 8 4 4

* / - +

输出样例 2

ERROR: 5/0

银行业务队列简单模拟

4、设某银行有AB两个业务窗口,且处理业务的速度不一样,其中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

实验原理与内容

实验原理:

顺序表的插入操作在于找准位置,循环移动元素,注意移动下标的边界问题

以下是给定位置插入,本题中思考参数还需要指定位置吗?

bool Insert( List L, ElementType X, int i )
{    Position j;
     if ( L->Last == MAXSIZE-1) {
	/* 表空间已满,不能插入 */
	printf("表满"); 
	return false; 
     }  
     if ( i<1 || i>L->Last+2 ) { 
 /* 检查插入位序的合法性:是否在1~n+1。n为当前元素个数,即Last+1 */
	printf("位序不合法");
	return false; 
     } 
     for( j=L->Last; j>=i-1; j-- ) /*Last指向序列最后元素 */
	L->Data[j+1] = L->Data[j]; /* 将位序i及以后的元素顺序向后移动 */
     L->Data[i-1] = X;  /* 新元素插入第i位序,其数组下标为i-1 */
     L->Last++;       /* Last仍指向最后元素 */
     return true; 
}

链表不要求逻辑上相邻的两个数据元素物理上也相邻,它是通过“链”建立起数据元素之间的逻辑关系。因此对线性表的插入、删除不需要移动数据元素,只需要修改“链”。

堆栈

“堆栈(Stack)”可以认为是具有一定操作约束的线性表,插入和删除操作都作用在一个称为栈顶(Top)的端点位置。主要特点是“后进先出”(Last In First Out)。

队列

队列是一种限制在两端进行插入和删除的线性表。

【分析提示】

首先需要针对A和B业务设计两个循环队列,分别处理两类业务请求;然后根据输入序列整数的奇偶性将各个整数分配到这两个队列中。另外,需要设计针对两个队列处理过程的流程,这是一个循环。在循环中,先从A队列中输出两个元素,然后再从B队列输出一个元素。当发现某一队列为空时,输出另一个队列的所有元素。

【实现要点】

采用统一的循环队列函数处理两个队列的操作,注意对队列满、空情况的判断。

实验内容:

  1. 建立顺序表,并在顺序表上实现基本运算操作
  2. 已知顺序表L递增有序,将X插入到线性表的适当位置上,保证线性表有序

3.  建立链表,并在链表上实现基本运算操作

4.  已知两个非降序链表序列S1与S2,设计函数构造出S1与S2的交集新链表S3

5.  建立顺序栈,并在栈上实现基本运算操作

6.  实现栈在简易计算器的应用

7.建立循环队列,并在队列上实现基本运算操作

8.实现银行业务队列的简单模拟

实验过程与结果

每道题目都要写出以下三个步骤:

递增有序顺序表的插入

#include <stdio.h>
int main()
{
	int dz[200];
	int a,b,i,j;
	scanf("%d",&a);
	for(i=0;i<a;i++)
		scanf("%d",&dz[i]);
	scanf("%d",&b);
	dz[a]=b;
	for(i=a;i>0;i--)		
		if(dz[i]<dz[i-1])
		{
			j=dz[i];
			dz[i]=dz[i-1];
			dz[i-1]=j;			
				}		
	for(i=0;i<a+1;i++)
		printf("%d,",dz[i]);	
	return 0;
}

两个有序链表序列的交集

#include <stdio.h>
#include <stdlib.h>
struct Node 
{
 	int data;
 	struct Node *next;
};
struct Node *build();
struct Node *operate(struct Node *a,struct Node *b);
int main() 
{
 	struct Node *a,*b,*c;
 	a=build();
 	b=build();
 	c=operate(a,b);
 	if(!c)
  		printf("NULL\n");
 	while(c)
 	{
  		if(c->next==NULL)
   			printf("%d",c->data);
  		else
   			printf("%d ",c->data);
  		c=c->next;
 	} 
}
struct Node *build()
{
 	int a;
 	struct Node *head=NULL,*str=NULL;
 	scanf("%d",&a);
 	while(a!=-1)
 	{
  		struct Node *p=(struct Node*)malloc(sizeof(struct Node));
  		p->data=a;
  		p->next=NULL;
  		if(head==NULL)
   			head=p;
  		else
   			str->next=p;
  		str=p; 
  		scanf("%d",&a);
 	}
 	return head;
}
struct Node *operate(struct Node *a,struct Node *b)
{
 	struct Node *head=NULL,*str=NULL;
 	while(a&&b)
    	{
        	if((a->data)<(b->data))
           		a=a->next;
        	else if((a->data)>(b->data))
            		b=b->next;
        	else if((a->data)==(b->data))
        	{
         		if(head==NULL)
          			head=a;
         		else
          			str->next=a;
         		str=a;        
         		a=a->next;
         		b=b->next;
         		str->next=NULL;//放在这里很重要,要先将a进至下一节点,防止直接将链表a中断
  		}
 	}
 	return head;
}

简单计算器

#include<stdio.h>
int digit(int a,int b,char c)//计算操作
{
	if(c=='+')return  a+b;
	if(c=='-')return a-b;
	if(c=='*')return a*b;
	if(c=='/'&&b==0)
		return -199;//如果出错就返回199;继续后续的ERROR打印
	if(c=='/')return a/b;
	else return 0;
}
int main()
{
	int n;
	scanf("%d",&n);
	int a[n];
	char b[n-1];
	for(int i=0;i<n;i++)
		scanf("%d",&a[i]);
	getchar();//要用getchar吸收空格和回车,一开始搞错了,找了很久的错误。
	for(int i=0;i<n-1;i++)
	{
		scanf("%c",&b[i]);
		getchar(); 
	}
	int sum=0;
	int p = n-2;//p是字符数组的下标,因为有n-1个元素,所以末尾元素是n-2
	
	for(int i=n-1;i>0;i--)
	{	
		int tem = a[i-1];
		a[i-1] = digit(a[i-1],a[i],b[p]);//计算后两位,然后结果给到倒数第二位
		p--;
		if(a[i-1]==-199)//哎,等于-199说明错误啦,所以输出然后直接返回。tem是为了存i-1的数值
													//不然i-1就是-199啦,就会错的一塌糊涂。
		{
			printf("ERROR: %d/%d",tem,a[i]);
			return 0;
		}
	}
	printf("%d",a[0]);//全部计算完之后就只剩下a[0]啦
}

银行业务队列简单模拟

#include<iostream>
#include<queue>
using namespace std;
int N;
queue<int>A;
queue<int>B;
void Input() {
	cin >> N;
	int M;
	for (int i = 1; i <= N; i++) {
		cin >> M;
		if (M % 2 == 0) {
			B.push(M);
		}
		else {
			A.push(M);
		}
	}
}
void Printf() {
	int flag = 0;
	while (A.empty() != 1 && B.empty() != 1) {//当他们都不为空
		if (flag == 0) {
			cout <<A.front();
			flag++;
		}
		else {
			cout << " "<<A.front();
		}
		A.pop();
		if (A.empty() != 1) {
			cout << " "<<A.front();
			A.pop();
		}
		cout << " " << B.front();
		B.pop();
	}
	while (A.empty() == 1 && B.empty() != 1) {
		if (flag == 0) {
			cout <<B.front();
			flag++;
		}
		else {
			cout << " " << B.front();
		}
		B.pop();
	}
	while (A.empty() != 1 && B.empty() == 1) {
		if (flag == 0) {
			cout <<A.front();
			flag++;
		}
		else {
			cout << " " << A.front();
		}
		A.pop();
	}
}

	int main() {
		Input();
		Printf();
	}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

榴某

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值