数据结构期末考试~

表达式转换

算术表达式有前缀表示法、中缀表示法和后缀表示法等形式。日常使用的算术表达式是采用中缀表示法,即二元运算符位于两个运算数中间。请设计程序将中缀表达式转换为后缀表达式。

#include<stdio.h>
int main()
{
    char str[201],stack[201];   // 输入字符 + 模拟栈
    int top=0,len=0;            // 栈高,
    gets(str);                  // 获取中缀表达式
 
    /*  开头符号判断  */
    if(str[0]=='+' || str[0]=='-') {
        if(str[0]=='-') putchar('-');
        len++;
    }
 
    /*  逐个字符判断  */
    while (str[len]!='\0'){
        char ch = str[len++];
        switch (ch) {
            case '(':
                // 遇到左括号,注意判断(-1)这种情况
                stack[++top] = '(';
                if(str[len]=='+') len++;
                if(str[len]=='-') printf("%c",str[len++]);
                break;
            case ')':
                // 弹出符号,直到遇见'('为止
                while (stack[top]!='(') printf(" %c",stack[top--]);
                top--;  // '(' 也要弹出
                break;
            case '+': case '-':
                putchar(' '); // 前置空格先输出
                // 弹出符号,直到遇到'('
                while (top!=0 && (stack[top]!='(')) printf("%c ",stack[top--]);
                // 将该符号压入栈
                stack[++top] = ch;
                break;
            case '*': case '/':
                putchar(' '); // 前置空格先输出
                // 只要栈顶是乘号或除号就弹出
                while (top!=0 && (stack[top]=='*' || stack[top]=='/')) printf("%c ",stack[top--]);
                // 将该符号压入栈
                stack[++top] = ch;
                break;
            default: putchar(ch); //数字部分遇见直接输出
        }
    }
 
    while (top>0) printf(" %c",stack[top--]); // 弹出剩余的运算符
    return 0;
}

一元多项式的乘法与加法运算

设计函数分别求两个一元多项式的乘积与和。

< 不考虑指数存在负数情况 >

#include<stdio.h>
void print(int key[]);
int main()
{
    int coefficient[2022],index[2022];      // 第一个多项式的系数与指数
    int key1[2022]={0},key2[2022]={0};      // 乘积结果与和的结果
    int N,M,a,b;

    scanf("%d",&N);
    for(int z=0;z<N;z++) {
        scanf("%d %d",&coefficient[z],&index[z]);
        key2[index[z]] = coefficient[z];
    }

    scanf("%d",&M);
    while (M--){
        scanf("%d %d",&a,&b);
        key2[b] += a;
        for(int z=0;z<N;z++){
            key1[b+index[z]] += a * coefficient[z];
        }
    }

    print(key1);
    print(key2);
    return 0;
}
void print(int key[])
{
    int flag = 0;
    for(int z=2021;z>=0;z--){
        if(key[z]!=0){
            if(flag==1) putchar(' ');
            printf("%d %d",key[z],z);
            flag = 1;
        }
    }
    if(flag==0) puts("0 0");
    else puts("");
}

括号匹配

本题目要求读入n个字符串,每个字符串是一个括号序列,如“{[()]}”,然后判断每个括号序列是否匹配

#include<stdio.h>
#define Size 500
int OP();
int main()
{
    int N;
    scanf("%d\n",&N);
    while (N--) puts(OP()?"Yes":"No");
    return 0;
}
int OP()
{
    char stack[Size],str[Size];
    int top = 0,len=0;
    gets(str);
    while (str[len]!='\0'){
        char ch = str[len++];
        switch (ch) {
            case ')':
                if(top>0&&stack[top]=='(') top--;
                else return 0;
                break;
            case ']':
                if(top>0&&stack[top]=='[') top--;
                else return 0;
                break;
            case '}':
                if(top>0&&stack[top]=='{') top--;
                else return 0;
                break;
            default: stack[++top] = ch;
        }
    }
    return top==0;
}

判断字符串结尾方式

输入2个字符串,判断其中一个字符串是否是以另一个字符串结尾

#include<stdio.h>
#include<string.h>
#define Size 500
char s1[Size],s2[Size];
int OP(int len1,int len2){
    if(len1==-1 && len2==-1) return 666;
    if(len1==-1) return 1;
    if(len2==-1) return 2;
    if(s1[len1]==s2[len2]) return OP(len1-1,len2-1);
    return 0;
}
int main()
{
    gets(s1);
    gets(s2);
    int result = OP(strlen(s1), strlen(s2));
    if(result==0) puts("no");
    else if(result==1) puts(s1);
    else if(result==2) puts(s2);
    else puts("all");
    return 0;
}

出现次数最多的数字和次数

在n个数中,找出出现次数最多那个数字,并且输出出现的次数。如果有多个结果,输出数字最小的那一个。

#include<stdio.h>
int main()
{
    int apr[2022]={0};
    int N,num,result=0;
    scanf("%d",&N);
    while (N--){
        scanf("%d",&num);
        apr[num]++;
        if(apr[num]>apr[result]||(apr[num]==apr[result] && result>num)) result=num;
    }
    printf("%d %d",result,apr[result]);
    return 0;
}

二叉树的遍历-后序

以二叉链表作存储结构,建立一棵二叉树, 输出该二叉树的后序遍历序列。

二叉链表的类型描述:

#include<stdio.h>
#include<stdlib.h>
typedef struct Node *node;
struct Node{
    char data;
    node l,r;
}root;

void createTree(node tree){
    tree->data = getchar();
    if(tree->data=='#') return;
    tree->l = (node)malloc(sizeof(struct Node));
    tree->r = (node)malloc(sizeof(struct Node));
    createTree(tree->l);
    createTree(tree->r);
}

void print(node tree){
    if(tree->data=='#') return;
    print(tree->l);
    print(tree->r);
    putchar(tree->data);
}

int main()
{
    createTree(&root);
    print(&root);
    return 0;
}

数据结构实验五 直接插入排序

用顺序表作存储结构,输入一组数据,用直接插入法对其进行排序。

#include<stdio.h>
#include<stdlib.h>
#define MAXSIZE 50     // MAXSIZE为最大数据元素数目
typedef struct
{
    int  data[MAXSIZE +1];    // r[0]闲置或另作它用
    int  length;
}SqList;
int main()
{
    SqList list;
    scanf("%d",&list.length);
    for(int z=0;z<list.length;z++) scanf("%d",&list.data[z]);
    for(int z=1;z<list.length;z++){
        int key = z;
        while (z>0 && list.data[z]<list.data[z-1]){
            int temp = list.data[z];
            list.data[z] = list.data[z-1];
            list.data[--z] = temp;
        }
        z = key;
    }
    printf("%d",list.data[0]);
    for(int z=1;z<list.length;z++) printf(" %d",list.data[z]);
    return 0;
}

判断回文

回文是指正读反读均相同的字符序列,如“abba”和“abdba”均是回文,但“good”不是回文。试写一个程序判定给定的字符向量是否为回文,用栈实现。(提示:将一半字符入栈)

#include <stdio.h>
#include <string.h>
char str[2022];
int OP(int l,int r){
    if(l>=r) return 1;
    if(str[l]==str[r]) return OP(l+1,r-1);
    return 0;
}
int main()
{
    gets(str);
    printf("%s",str);
    if(OP(0,strlen(str)-1)==1) puts("是回文。");
    else puts("不是回文。");
    return 0;
}

成绩排序

给出班里某门课程的成绩单,请你按成绩从高到低对成绩单排序输出,如果有相同分数则名字字典序小的在前。

#include<stdio.h>
#include<string.h>
#define Size 50
struct Student{
 char name[Size];
 int score,apr;
}s[Size];
int main()
{
    int N;
    scanf("%d",&N);
    for(int z=0;z<N;z++) scanf("%s %d",&s[z].name,&s[z].score);
    for(int z=0;z<N;z++){
        int key = 0;
        while (s[key].apr==1) key++;
        for(int z1=key+1;z1<N;z1++){
            if(s[z1].apr==0){
                if(s[z1].score>s[key].score || (s[z1].score==s[key].score && strcmp(s[z1].name,s[key].name)<0)){
                    key = z1;
                }
            }
        }
        s[key].apr = 1;
        printf("%s %d\n",s[key].name,s[key].score);
    }
    return 0;
}

求阶乘序列前N项和

本题要求编写程序,计算序列 1!+2!+3!+⋯ 的前N项之和。

#include <stdio.h>
int main()
{
    int N,result=1,op=1;
    scanf("%d",&N);
    for(int z=2;z<=N;z++){
        op*=z;
        result+=op;
    }
    printf("%d",result);
    return 0;
}

数组循环左移

本题要求实现一个对数组进行循环左移的简单函数:一个数组a中存有n(>0)个整数,在不允许使用另外数组的前提下,将每个整数循环向左移m(≥0)个位置,即将a中的数据由(a0a1⋯a**n−1)变换为(a**ma**n−1a0a1⋯a**m−1)(最前面的m个数循环移至最后面的m个位置)。如果还需要考虑程序移动数据的次数尽量少,要如何设计移动的方法?

#include <stdio.h>
int main() {
    int N,M,nums[110];
    scanf("%d %d",&N,&M);
    M %= N;
    for (int z = 0; z < N; z++){
        scanf("%d",&nums[(z-M+N)%N]);
    }
    printf("%d",nums[0]);
    for(int z=1;z<N;z++) printf(" %d",nums[z]);
    return 0;
}

两个有序链表序列的合并

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

#include<stdio.h>
int nums[2022120],nums1[1000001],nums2[1000001],len1,len2;
int main()
{
    while (scanf("%d",&nums1[len1])!=EOF && nums1[len1]!=-1) len1++;
    while (scanf("%d",&nums2[len2])!=EOF && nums2[len2]!=-1) len2++;
    int l1=0,l2=0,len=0;
    while (l1!=len1 || l2!=len2){
        if(l1==len1) nums[len++] = nums2[l2++];
        else if(l2==len2) nums[len++] = nums1[l1++];
        else if(nums1[l1]<nums2[l2]) nums[len++] = nums1[l1++];
        else nums[len++] = nums2[l2++];
    }
    if(len==0) puts("NULL");
    else printf("%d",nums[0]);
    for(int z=1;z<len;z++) printf(" %d",nums[z]);
    return 0;
}

数据结构实验四 折半查找

建立一个递增的有序表(用顺序表作存储结构),用折半查找的方法对其实施查找。

#include<stdio.h>
#define MAXSIZE 50
struct SSTable
{
    int data[MAXSIZE+1];
    int length;
}table;

int main()
{
    scanf("%d",&table.length);
    for(int z=1;z<=table.length;z++) scanf("%d",&table.data[z]);
    int left=0,right=table.length,mid,key;
    scanf("%d",&key);
    while (left<=right){
        mid=(left+right)/2;
        if(table.data[mid]==key){
            printf("%d",mid);
            return 0;
        }
        if(table.data[mid]<key) left=mid+1;
        else right=mid-1;
    }
    puts("NOT FOUND");
    return 0;
}

选择排序

本题要求从键盘读入n个整数,对这些数做选择排序。输出选择排序每一步的结果和最终结果。

#include<stdio.h>
int main()
{
    int N,nums[202212];
    scanf("%d",&N);
    for(int z=0;z<N;z++) scanf("%d",&nums[z]);
    for(int z=0;z<N-1;z++){
        printf("step %d: ",z+1);
        int key = z;
        for(int z1=z+1;z1<N;z1++){
            if(nums[key]>nums[z1]){
                key = z1;
            }
        }
        if(key!=z) nums[z]^=nums[key]^=nums[z]^=nums[key];
        for(int z1=0;z1<N;z1++) printf("%d ",nums[z1]);
        puts("");
    }
    printf("sorted array: ");
    for(int z1=0;z1<N;z1++) printf("%d ",nums[z1]);
    return 0;
}

二叉树路径和II

编写程序找出非空二叉树中和最大的路径,二叉树结点为不等于0的整数。本题的“路径”定义为二叉树中的结点序列v**i,…,v**j,序列中前一个结点是后一个结点的父结点,但路径不一定是以根结点为起点,也不一定是以叶结点为终点。路径的和定义为该路径所包含的所有结点的数据值之和。

#include<stdio.h>
#include<stdlib.h>
typedef struct Tree *tree;
struct Tree{
    int data;
    tree l,r;
}root;
void createTree(tree node);
void findRoad(tree node,int deep);
int rSum=-99999999,rLen,rKey[2022];
int main()
{
    createTree(&root);
    findRoad(&root,1);
    printf("%d\n",rSum);
    while (rLen>0) printf("%d ",rKey[--rLen]);
    return 0;
}
void createTree(tree node)
{
    scanf("%d",&node->data);
    if(node->data==0) return;
    node->l = (tree)malloc(sizeof(struct Tree));
    node->r = (tree)malloc(sizeof(struct Tree));
    createTree(node->l);
    createTree(node->r);
}
int sum[2022],last[2022],len[2022];
void findRoad(tree node,int deep)
{
    if(node->data==0) return;
    sum[deep] = last[deep] = node->data;
    len[deep] = 1;
    if(sum[deep-1]>0){
        sum[deep]+=sum[deep-1];
        len[deep]=len[deep-1]+1;
    }
    if(sum[deep]>rSum || (sum[deep]==rSum&&len[deep]<rLen)){
        rSum = sum[deep];
        for(rLen=0;rLen<len[deep];rLen++) rKey[rLen]=last[deep-rLen];
    }
    findRoad(node->l,deep+1);
    findRoad(node->r,deep+1);
}
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

三块不一样的石头

十分满意,一分打赏~

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

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

打赏作者

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

抵扣说明:

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

余额充值