【实验一】数据结构:线性表

实验1:顺序表

递增有序顺序表的插入

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

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

 输入样式:

5
1 3 5 7 9
6

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

输出样式:

1,3,5,6,7,9,

#include
#include

#define TRUE        1
#define FALSE       0
#define OK          1
#define ERROR       0
#define INFEASIBLE  -1
#define OVERFOLW    -2
#define MAXSIZE     100

typedef int Status;             //定义Status函数
typedef int SqElemType;

typedef struct List             //顺序表结构体
{
    SqElemType *num;
    int length;  //长度
}SqList;

Status InitSqList(SqList &L){                   //创建空顺序表
    L.num = new SqElemType[MAXSIZE];
    if(!L.num) exit(OVERFOLW);                  //分配失败
    L.length = 0;           //长度初始值为0
    return OK;    
}
int LocateElem(SqList L,SqElemType e){      //查找(要插入的位置i
    int i;
    for (i = 0; i < L.length; i++)
    {
        if (L.num[i] > e)               //从第一个开始比较e的值,找到位置i
        {
            break;
        }
    }
    return i;
}
Status InsertSqList(SqList &L,SqElemType e){    //插入
    int i,j;
    j = LocateElem(L,e);
    for (i = L.length-1; i >= j; --i)           //移动是后面的元素,所以从后面开始找
    {       //下标是从0开始,所以要-1
        L.num[i+1] = L.num[i];          //后移
    }
    L.num[j] = e;       //插入e
    ++L.length;         //增表长
    return OK;
}

int main(){
    SqList S;           //创建顺序表名为S结构体
    SqElemType X;
    int i;
    InitSqList(S);      //初始化
    scanf("%d",&S.length);
    for (i = 0; i < S.length; i++)
    {
        scanf("%d",&S.num[i]);
    }
    scanf("%d",&X);
    InsertSqList(S,X);
    for (i = 0; i < S.length; i++){
        printf("%d,",S.num[i]);
    }
    system("pause");    //防止窗口闪退,+头文件
    return 0;
}



实验2:链表

两个有序链表序列的交集

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

输入格式: 输入分两行,分别在每行给出由若干个正整数构成的非降序序列,用−1表示序列的结尾(−1不属于这个序列)。数字用空格间隔。输出格式: 在一行中输出两个输入序列的交集序列,数字间用空格分开,结尾不能有多余空格;若新链表为空,输出NULL。

输入样式:

1 2 5 -1
2 4 5 8 10 -1

输出样式:

2 5

#include 
#include 
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;
  		}
 	}
 	return head;
}

实验3:栈

简单计算器

本题要求你为初学数据结构的小伙伴设计一款简单的利用堆栈执行的计算器。

计算器由两个堆栈组成,一个堆栈 S1 存放数字,另一个堆栈 S2存放运算符。计算器的最下方有一个等号键,每次按下这个键,计算器就执行以下操作:

1.    从 S1 中弹出两个数字,顺序为 n1 和 n2;

2.    从 S2 中弹出一个运算符 op;

3.    执行计算 n2 op n1;

4.    将得到的结果压回 S1。

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

输入格式: 输入首先在第一行给出正整数 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


#include 
#include          //mallo函数所需头文件

typedef struct SNode1{      //S1结构体
    int num;
    struct SNode1 *top;     //头指针
}*numS1;
typedef struct SNode2{      //S2结构体
    char opr;               //运算符
    struct SNode2 *top;
}*oprS2;

//接口定义:
numS1 CreateS1();
oprS2 CreateS2();
void PushNumS1(int e,numS1 S);
void PushOprS2(char e,oprS2 S);
int PopNumS1(numS1 S);
char PopOprS2(oprS2 S);

//S1数字栈(ALL
numS1 CreateS1(){           //创建栈S1
    numS1 S;
    S = (numS1)malloc(sizeof(numS1));   //动态分配内存空间
    S->top = NULL;          //空栈(栈顶指针)
    return S;
}

void PushNumS1(int e,numS1 S){         //压栈数字--无需返回值,采用void
    numS1 Sql;              //定义存放e的Sql
    Sql = (numS1)malloc(sizeof(numS1));
    Sql->num = e;
    Sql->top = S->top;      //栈顶指针上移
    S->top = Sql;           //新栈顶元素为Sql
}

int PopNumS1(numS1 S){      //出栈(数字,int整型
    int old_num;            //定义保存出栈数据的值
    numS1 top_data;         //栈顶数据
    top_data = S->top;      //把当前栈顶赋值给top_data
    S->top = top_data->top;
    old_num = top_data->num;
    free(top_data);         //释放
    return old_num;         //返回出栈的值
}


//S2运算符栈(ALL
oprS2 CreateS2(){           //创建栈S2
    oprS2 S;
    S = (oprS2)malloc(sizeof(oprS2));
    S->top = NULL;
    return S;
}

void PushOprS2(char e,oprS2 S){         //压栈运算符
    oprS2 Sql;              //定义存放e的Sql
    Sql = (oprS2)malloc(sizeof(oprS2));
    Sql->opr = e;
    Sql->top = S->top;      //栈顶指针上移
    S->top = Sql;           //新栈顶元素为Sql
}

char PopOprS2(oprS2 S){      //出栈(运算符
    char old_opr;            //定义保存出栈数据的值
    oprS2 top_data;         //栈顶数据
    top_data = S->top;      //把当前栈顶赋值给top_data
    S->top = top_data->top;
    old_opr = top_data->opr;
    free(top_data);         //释放
    return old_opr;         //返回出栈的值
}

int main(){
    int N,i,number,n1,n2,sum;
    char operator,op;      
    numS1 S1;
    oprS2 S2;
    scanf("%d",&N);             //数字个数
    S1 = CreateS1();            //栈赋值给S1,S1指向numS1
    for (i = 0; i < N; i++)     //循环,入栈
    {
        scanf("%d",&number);
        PushNumS1(number,S1);   //调用
    }
    getchar();                  //输入缓冲区
    S2 = CreateS2();
    for (i = 0; i < N-1; i++)
    {
        scanf("%c",&operator);
        getchar();
        PushOprS2(operator,S2);
    }
    for (i = 0; i < N-1; i++)  //大循环
    {
        n1 = PopNumS1(S1);      //取出N1
        n2 = PopNumS1(S1);      //取出N2
        op = PopOprS2(S2);      //取出运算符
        if (n1 == 0 && op == '/') //除法,分母为0时
        {
            printf("ERROR: %d/0",n2);
            return 0;
        }
        else{
            switch (op)         //加减乘除运算
            {
                case '+':
                    sum = n2 + n1;
                    break;
                case '-':
                    sum = n2 - n1;
                    break;
                case '*':
                    sum = n2 * n1;
                    break;
                case '/':
                    sum = n2 / n1;
                    break;
            }
            PushNumS1(sum,S1);  //得到的结果压回S1
        }
    }
    printf("%d",sum);     //打印最终值
    return 0;
}

实验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 
#include          //动态存储分配头文件
#include 

//Status函数的返回值类型
#define TRUE        1
#define FALSE       0
#define OK          1
#define ERROR       0
#define INFEASIBLE  -1
#define OVERFLOW    -2

typedef int Status;         //定义Status
typedef int QElemType;
typedef struct QNode        //定义指针结构体
{
    QElemType Data;
    struct QNode *Next;
}QNode,*queuePtr;           //指针queuePtr指向QNode
typedef struct Queue        //顺序队列
{
    queuePtr front;         //头指针
    queuePtr rear;          //尾指针
}SqQueue;

Status InitQueue(SqQueue &Q){                   //创建(初始化
    Q.front = (QNode *)malloc(sizeof(QNode));   //动态分配空间给头结点
    if(!Q.front) exit(OVERFLOW);    //超出,则分配失败
    Q.front->Next = NULL;           //头结点指针指向空
    Q.rear = Q.front;               //空队列
    return OK;
}
Status EnQueue(SqQueue &Q,QElemType e){         //入队(rear队尾
    queuePtr p;                     //新结点p
    p = (QNode *)malloc(sizeof(QNode));
    if(!p) exit(OVERFLOW);
    p->Data = e;                    //e赋值给p指针的数据域
    p->Next =NULL;                  //p指针域指向空
    Q.rear->Next = p;               //p赋值给原队尾指针
    Q.rear = p;                     //p为现在队尾
    return OK;
}
Status DeQueue(SqQueue &Q,QElemType &e){    //出队
    if(Q.front == Q.rear) return ERROR;     //队为空,返回error
    queuePtr temp = Q.front->Next;          //头指针赋值给结点temp
    e = temp->Data;
    Q.front->Next = temp->Next;
    if(Q.rear == temp) Q.rear = Q.front;    //如果删除的是最后一个元素
    free(temp);             //释放
    return OK;
}
Status QueueEmpty(SqQueue Q){       //判断是否为空队列
    if (Q.front == Q.rear)
    {
        return TRUE;
    }
    else return FALSE;
}

int main(){
    SqQueue A;      //创建队列A,B
    SqQueue B;
    int n,m;
    QElemType num,q;
    InitQueue(A);   //创建空队列A,B
    InitQueue(B);
    scanf("%d",&n);   //输入顾客总数
    for (int i = 0; i < n; ++i)     //输入指定数量的顾客编号
    {
        scanf("%d",&num);   //通过for循环以及判断奇偶,依次入队
        if (num%2 == 1)     //取余(奇数
        {
            EnQueue(A,num);
        }
        else{
            EnQueue(B,num); //偶数
        }
    }
    m=0;        //用于是否输出空格
    while (!QueueEmpty(A) && !QueueEmpty(B))    //1、都不为空
    {
        if (m==0)
        {                           //奇数,输出两次
            DeQueue(A,q);
            printf("%d",q);
            m++;
            printf(" ");
            DeQueue(A,q);
            printf("%d",q);
        }
        else{
            printf(" ");
            DeQueue(A,q);
            printf("%d",q);
            m++;
            printf(" ");
            DeQueue(A,q);
            printf("%d",q);
        }
        if (!QueueEmpty(B))         //偶数,输出一次
        {
            printf(" ");
            DeQueue(B,q);
            printf("%d",q);
        }
    }
    while (!QueueEmpty(A) && QueueEmpty(B))     //全奇数,偶数为空
    {
        if (m==0)
        {
            DeQueue(A,q);
            printf("%d",q);
            m++;
        }
        else{
            printf(" ");
            DeQueue(A,q);
            printf("%d",q);
            m++;
        }
        
    }
    while (QueueEmpty(A) && !QueueEmpty(B))     //全偶数,奇数为空
    {
        if (m==0)
        {
            DeQueue(B,q);
            printf("%d",q);
            m++;
        }
        else{
            printf(" ");
            DeQueue(B,q);
            printf("%d",q);
            m++;
        }
        
    }
    printf("\n");
    return 0;
}

实验总结:(模板。。cv)

        通过本次实验,基本掌握线性表的基本知识 ,深入理解、掌握并灵活运用线性表。熟练掌握线性表的存储结构及主要运算的实现。通过实验学习到建立顺序表,并在顺序表上实现基本运算操作,已知顺序表L递增有序,将X插入到线性表的适当位置上,保证线性表有序 , 建立链表,并在链表上实现基本运算操作,已知两个非降序链表序列S1与S2,设计函数构造出S1与S2的交集新链表S3,建立顺序栈,并在栈上实现基本运算操作 ,实现栈在简易计算器的应用 ,建立循环队列,并在队列上实现基本运算操作 ,实现银行业务队列的简单模拟。链表不要求逻辑上相邻的两个数据元素物理上也相邻,它是通过“链”建立起数据元素之间的逻辑关系。因此对线性表的插入、删除不需要移动数据元素,只需要修改“链”。

        通过本次实验,学会了线性表的逻辑结构特点和线性表抽象数据类型的描述方法 ;线性表的两类存储结构设计方法以及各自的优缺点;掌握线性表的基本知识 ;深入理解、掌握并灵活运用线性表;熟练掌握线性表的存储结构及主要运算的实现 ;掌握栈的定义、栈的逻辑结构特性和栈的基本运算;理解栈在表达式求值中的应用;  掌握队列的定义、队列的逻辑结构特性和栈的基本运算; 理解队列的应用。

你可能感兴趣的:(数据结构,c++,c语言)