数据结构课程设计

题目:

从以下六个题目中选择四个题目,每个题目25分,共100分。请在选作的题目前面打上√并按照示例对每个题目做出解答。

No Copying

一、表达式求值问题

二、看病排队候诊问题

三、计算哈夫曼树的WPL值

四、图的应用

五、哈希表的应用

六、汽车牌照的快速查询


一、表达式求值问题

给定一个四则运算的中缀表达式、前缀表达式和后缀表达式,编程计算表达式的值。 基本要求:  

  (1)在给定的表达式中要包含括号;    

(2)栈的操作要求自己完成,不允许调用类库中的方法;  

  (3)对不同的操作编写相应的函数。 测试数据要求:        

给定测表达式(字符串)中的数字字符要有包含两位以上的数字字符。

前缀

///前缀 author : revolIA 
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
struct Stack{
    double *base;
    int Top,len;
    void init(){
        base = (double*)malloc(sizeof(double));
        len = 1,Top = 0;
    }
    void push(double x){
        if(Top == len){
            len <<= 1;
            base = (double*)realloc(base,len*sizeof(double));
        }
        base[Top++] = x;
    }
    void pop(){
        if(Top)
            Top--;
    }
    double Gettop(){
        return base[Top-1];
    }
    bool empty(){
        return Top==0?1:0;
    }
}st;
char s[10000];
double calculator(char s[]){
    st.init();
    int len = strlen(s);
    int i = len-1;
    while(~i){
        if(s[i] == ' ')
            i--;
        else if(isdigit(s[i])){
            ll ans = 0;
            int Stack[10],x = 0;
            while(i+1&&isdigit(s[i]))
                Stack[x++] =  s[i--]-'0';
            while(x--)
                ans = ans*10 + Stack[x];
            st.push(1.0*ans);
        }else{
            double ans;
            double a = st.Gettop();
            st.pop();
            double b = st.Gettop();
            st.pop();
            switch (s[i]){
                case '+' : ans = a+b ;break;
                case '-' : ans = a-b ;break;
                case '*' : ans = a*b ;break;
                case '/' : ans = a/b ;
            }
            st.push(ans);
            i--;
        }
    }
    return st.Gettop();
}
void Getline(char s[]){
    int i = 0;
    while((s[i]=getchar())!='\n')i++;
    s[i]='\0';
}
int main(){
    Getline(s);
    //puts(s);
    printf("%f\n",calculator(s));
    return 0;
}

中缀

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
union type{double a;char b;};
type make_type(char c){
    type x;x.b = c;
    return x;
}
type make_type(double c){
    type x;x.a = c;
    return x;
}
struct Stack{
    type *base;
    int Top,len;
    void init(){
        base = (type*)malloc(sizeof(type));
        len = 1,Top = 0;
    }
    void push(type x){
        if(Top == len){
            len <<= 1;
            base = (type*)realloc(base,len*sizeof(type));
        }
        base[Top++] = x;
    }
    void pop(){
        if(Top)
            Top--;
    }
    type Gettop(){
        return base[Top-1];
    }
    bool empty(){
        return Top==0?1:0;
    }
}stn,stc;
int Getpriority(char s){
    if(s == '(')return 1;
    if(s == '+' || s == '-')return 2;
    if(s == '*' || s == '/')return 3;
    return 4;
}
void cal(Stack &stn,type x){
    type ans;
    double b = stn.Gettop().a;stn.pop();
    double a = stn.Gettop().a;stn.pop();
    switch (x.b){
        case '+' : ans.a = a+b ;break;
        case '-' : ans.a = a-b ;break;
        case '*' : ans.a = a*b ;break;
        case '/' : ans.a = a/b ;
    }
    stn.push(ans);
}
char s[10000];
double calculator(char s[]){
    stn.init(),stc.init();
    int len = strlen(s);
    int i = 0;
    while(len-i){
        if(isdigit(s[i])){
            ll ans = 0;
            while(len-i && isdigit(s[i]))
                ans = ans*10 + s[i++] - '0';
            stn.push(make_type(1.0*ans));
            i--;
        }else if(Getpriority(s[i])==2 || Getpriority(s[i])==3){
            if(stc.empty())
                stc.push(make_type(s[i]));
            else{
                while(!stc.empty() && Getpriority(stc.Gettop().b) >= Getpriority(s[i])){
                    cal(stn,stc.Gettop());
                    stc.pop();
                }
                stc.push(make_type(s[i]));
            }
        }else{
            if(s[i] == '(')
                stc.push(make_type(s[i]));
            else{
                while(stc.Gettop().b != '('){
                    cal(stn,stc.Gettop());
                    stc.pop();
                }
                stc.pop();
            }
        }
        i++;
    }
    while(!stc.empty()){
        cal(stn,stc.Gettop());
        stc.pop();
    }
    return stn.Gettop().a;
}
void Getline(char s[]){
    int i = 0;
    while((s[i]=getchar())!='\n')i++;
    s[i]='\0';
}
int main(){
    Getline(s);
    //puts(s);
    printf("%f\n",calculator(s));
    return 0;
}

后缀

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
struct Stack{
    double *base;
    int Top,len;
    void init(){
        base = (double*)malloc(sizeof(double));
        len = 1,Top = 0;
    }
    void push(double x){
        if(Top == len){
            len <<= 1;
            base = (double*)realloc(base,len*sizeof(double));
        }
        base[Top++] = x;
    }
    void pop(){
        if(Top)
            Top--;
    }
    double Gettop(){
        return base[Top-1];
    }
    bool empty(){
        return Top==0?1:0;
    }
}st;
char s[10000];
double calculator(char s[]){
    st.init();
    int len = strlen(s);
    int i = 0;
    while(len-i){
        if(s[i] == ' ')
            i++;
        else if(isdigit(s[i])){
            ll ans = 0;
            while(len-i&&isdigit(s[i]))
                ans = ans*10 + s[i++]-'0';
            st.push(1.0*ans);
        }else{
            double ans;
            double b = st.Gettop();
            st.pop();
            double a = st.Gettop();
            st.pop();
            switch (s[i]){
                case '+' : ans = a+b ;break;
                case '-' : ans = a-b ;break;
                case '*' : ans = a*b ;break;
                case '/' : ans = a/b ;
            }
            st.push(ans);
            i++;
        }
    }
    return st.Gettop();
}
void Getline(char s[]){
    int i = 0;
    while((s[i]=getchar())!='\n')i++;
    s[i]='\0';
}
int main(){
    Getline(s);
    //puts(s);
    printf("%f\n",calculator(s));
    return 0;
}

 

 

二、看病排队候诊问题        

医院各科室的医生有限,病人到医院看病时必须排队就诊,而病人病情有轻重之分,不能简单地根据先来先服务的原则进行诊断治疗,所以医院根据病人的病情规定了不同的优先级别。医生在诊断治疗时,总是选择优先级别高的病人进行诊治,如果遇到两个优先级别相同的病人,则选择优先来排队的病人进行诊治。 基本要求:    

(1)用队列模拟上述病人看病排队候诊问题;      

(2)两个队列分别对应不同的优先级别,优先级高的队列中的病人优先就诊;      

(3)按照从终端读入数的方式进行模拟管理。

    测试数据要求:

         病人信息包括:挂号编号、病历号、看病的优先级、姓名和性别。

 

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
struct node{
    ll regis_num,case_num;///挂号,病历
    char name[40];
    char sex[20];
    int priority;
};
struct qnode{
    node x;
    qnode *nex;
};
struct Queue{
    qnode *head,*tail;
    void init(){
        tail = head = (qnode*)malloc(sizeof(qnode));
        head->nex = NULL;
    }
    void push(node a){
        qnode *p = (qnode*)malloc(sizeof(qnode));
        p->x = a;
        p->nex = NULL;
        tail->nex = p;
        tail = tail->nex;
    }
    void pop(){
        qnode *s = head->nex;
        if(s == NULL)
            return;
        head->nex = s->nex;
        free(s);
    }
    node front(){
        return head->nex->x;
    }
    bool empty(){
        return head->nex==NULL;
    }
}Q[2];
void init(){
    for(int i=0;i<2;i++)Q[i].init();
}
void input(){
    node t;
    int n;
    printf("input the number of the patient\n");
    scanf("%d",&n);
    printf("regis_num case_num priority name sex\n");
    while(n--){
        scanf("%lld%lld%d%s%s",&t.regis_num,&t.case_num,&t.priority,t.name,t.sex);
        Q[t.priority].push(t);
    }
}
void output(){
    printf("regis_num case_num priority name sex\n");
    int k = 2;
    while(k--){
        while(!Q[k].empty()){
            printf("%06lld %06lld %d %s %s\n",
            Q[k].front().regis_num,Q[k].front().case_num,
            Q[k].front().priority,Q[k].front().name,Q[k].front().sex),Q[k].pop();
        }
    }
}
int main(){
    init();
    input();
    output();
    return 0;
}/*
5
000001 000012 0 张三 男
000002 000016 0 李四 男
000003 000018 1 王五 男
000004 000019 1 钱六 男
000005 000033 0 赵八 男
*/

 

三、计算哈夫曼树的WPL值

        根据给定的n个权值(非负值),计算所构造哈夫曼树的WPL值。 基本要求:    

(1)根据给定的数据,建立哈夫曼树;      

(2)输出每个叶子结点的带权路径长度;      

(3)输出哈夫曼树的WPL值。

    测试数据要求:

        输入的n个权值之和应为100,且不允许有负值。  

 

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int n;
struct node{
    int cnt;
    node *l,*r;
    void init(){
        l = r = NULL;
    }
};
struct cnode{
    node *x;
    cnode *nex;
};
struct QuQ{
    cnode head;
    int Cnt;
    void init(){
        Cnt = 0;
        head.x = (node*)malloc(sizeof(node));
        head.x->cnt = -1;
        head.nex = NULL;
    }
    void push(node *x){
        ++Cnt;
        cnode *p = (cnode*)malloc(sizeof(cnode)),*s = &head;
        p->x = x;
        p->nex = NULL;
        if(!head.nex){
            head.nex = p;
            return;
        }
        while(s->nex&&s->nex->x->cnt<=x->cnt)
            s = s->nex;
        if(!s->nex)
            s->nex = p;
        else{
            p->nex = s->nex;
            s->nex = p;
        }
    }
    node* pop(){
        if(!head.nex)
            return NULL;
        --Cnt;
        cnode* s = head.nex;
        head.nex = s->nex;
        node* ans = s->x;
        free(s);
        return ans;
    }
}quq;
node* Create(){
    quq.init();
    printf("the number \n");
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        node* x = (node*)malloc(sizeof(node));
        x->init();
        scanf("%d",&x->cnt);
        quq.push(x);
    }
    while(quq.Cnt>1){
        node *t1,*t2,*t3 = (node*)malloc(sizeof(node));
        t1 = quq.pop(),t2 = quq.pop();
        t3->cnt = t1->cnt+t2->cnt;
        t3->l = t1,t3->r = t2;
        quq.push(t3);
    }
    return quq.pop();
}
int dfs(node* x,int i){
    if(!x->l&&!x->r){
        printf("%d\n",i*x->cnt);
        return i*x->cnt;
    }
    int ans = 0;
    if(x->l)
        ans += dfs(x->l,i+1);
    if(x->r)
        ans += dfs(x->r,i+1);
    return ans;
}
int main(){
    node* tree = Create();
    printf("WPL:%d\n",dfs(tree,0));
    return 0;
}/*
3
20 30 50
4
30 24 26 20
*/

 

四、图的应用

        学校要建立一个娱乐中心,设计该娱乐中心的位置,使得各部门到中心的距离较近。

基本要求:

      (1)顶点表示各部门,顶点之间连线上的权值表示两个部门的距离;

     (2)采用邻接表存储图;

     (3)采用Flody算法求最短路径;

     (4)输出各路径及其距离。

        测试数据要求:       输入表示权值的整数必须是正整数。  

 

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e3+7;
int head[maxn],cnt,n,m;
int ans[maxn][maxn],pre[maxn][maxn];
struct node{
    int to,val,nex;
}E[maxn*maxn];
void init(){
    memset(head,-1,sizeof(head));
    memset(pre,-1,sizeof(pre));
    for(int i=0;i<maxn;i++)
    for(int j=0;j<maxn;j++)
        ans[i][j] = 0x3f3f3f3f;
}
void add(int u,int v,int val){
    E[cnt] = {v,val,head[u]};
    head[u] = cnt++;
}
void floyd(){
    for(int i=1;i<=n;i++){
        for(int j=head[i];~j;j=E[j].nex){
            if(ans[i][E[j].to]>E[j].val)
                ans[i][E[j].to]=E[j].val;
        }
    }
    for(int k=1;k<=n;k++){
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                if(ans[i][j]>ans[i][k]+ans[k][j])
                    ans[i][j] = ans[i][k]+ans[k][j],pre[i][j] = k;
            }
        }
    }
}
void dfs(int i,int j){
    if(pre[i][j]==-1)
        return;
    dfs(i,pre[i][j]);
    printf("->%d",pre[i][j]);
    dfs(pre[i][j],j);
}
void input(){
    init();
    printf("the number of point\n");
    scanf("%d",&n);
    printf("the number of edge \n");
    scanf("%d",&m);
    printf("the two point and the value:\n");
    int u,v,w;
    for(int i=0;i<m;i++)
        scanf("%d%d%d",&u,&v,&w),add(u,v,w),add(v,u,w);
}
void output(){
    int dis = 0x3f3f3f3f,ansi = -1;
    for(int i=1;i<=n;i++){
        int tans = 0;
        for(int j=1;j<=n;j++)
        if(i!=j)
            tans += ans[i][j];
        if(dis>tans){
            dis = tans;
            ansi = i;
        }
    }
    printf("the Recreation Center should be create in the %d-th point\n",ansi);
    for(int i=1;i<=n;i++){
        for(int j=1+i;j<=n;j++){
            printf("from %d-th to %d-th :\nWeight:",i,j);
            if(ans[i][j]==0x3f3f3f3f)
                printf("%4d\n",-1);
            else{
                printf("%4d\n",ans[i][j]);
                printf("path: %d",i);
                dfs(i,j);
                printf("->%d\n",j);
            }
        }
    }
}
int main(){
    init();
    input();
    floyd();
    output();
    return 0;
}/*
3
3
1 2 5
2 3 6
3 1 5

4
4
1 2 5
2 3 6
3 4 7
2 4 1
*/

 

五、哈希表的应用

     根据给定的一组整数,建立哈希表。 基本要求:

      (1)设计哈希函数;

      (2)分别采用线性探测再散列法和链地址法解决冲突;

      (3)对哈希表进行查找,输出查找成功和不成功的信息。

       测试数据要求:         建立哈希表时输入的数据可以有相同的值。

线性探测再散列法

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int len = 30,k = 3,b = 5;
int p[len],vis[len];
int Hash(int x){
    return (3*x*x+b)%len;
}
void Push(int x){
    int pos = Hash(x);
    if(vis[pos]){
        if(p[pos] == x)
            return;
        while(vis[pos]){
            pos = (pos+1)%len;
        }
    }
    printf("pos ( %02d ) : %02d\n",x,pos);
    vis[pos] = 1;
    p[pos] = x;
}
void Find(int x){
    int pos = Hash(x);
    if(p[pos]!=x){
        int tp = (pos-1+len)%len;
        while(pos!=tp && p[pos]!=x){
            pos = (pos+1)%len;
        }
    }
    printf("%s\n",(vis[pos] && p[pos]==x)?"Yes":"No");
}
int main(){
    int a[5] = {1,2,6,4,10};
    for(int i=0;i<5;i++){
        printf("hash( %02d ) : %02d --> ",a[i],Hash(a[i]));
        Push(a[i]);
    }
    for(int i=0;i<=10;i++)
        printf("Find %3d: ",i),Find(i);
    return 0;
}

链地址法

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int len = 30,k = 3,b = 5;
int p[len],vis[len];
int cnt,head[len];
struct node{
    int val,nex;
}edg[len];
void init(){
    memset(head,-1,sizeof(head));
}
int Hash(int x){
    return (3*x*x+b)%len;
}
void Push(int x){
    int pos = Hash(x);
    if(vis[pos]){
        edg[cnt] = {x,head[pos]};
        head[pos] = cnt++;
        return;
    }
    vis[pos] = 1;
    p[pos] = x;
}
void Find(int x){
    int pos = Hash(x);
    if(!vis[pos]){
        printf("No\n");
        return;
    }
    if(p[pos] == x){
        printf("Yes\n");
        return;
    }
    else{
        for(int e = head[pos];~e;e = edg[e].nex){
            if(edg[e].val == x){
                printf("Yes\n");
                return ;
            }
        }
    }
    printf("No\n");
}
int main(){
    init();
    int a[5] = {1,2,4,6,10};
    for(int i=0;i<5;i++){
        printf("hash( %02d ) : %02d \n",a[i],Hash(a[i]));
        Push(a[i]);
    }
    for(int i=0;i<=10;i++)
        printf("Find %2d: ",i),Find(i);
    return 0;
}

 

 

 

 

六、汽车牌照的快速查询

      对一组汽车牌照进行排序和查找。 基本要求:

    (1)利用排序算法对汽车牌照进行排序;

    (2)采用折半查找思想完成查找。

     测试数据要求:

      测试的数据不得少于50个,不得有重复的牌照。

      车牌号中可以是数字和字符的组合,车牌号可以人工输入,也可以自动生成。  

 

#include <bits/stdc++.h>
using namespace std;
const int k = 60;
struct node{
    char name[300];
}car[100];
void lower_bound_Find(node car[],int n,char p[]){
    int l = 0,r = n-1,mid,sul = 0;
    while(l<=r){
        mid = (l+r)/2;
        if(strcmp(car[mid].name,p)<=0)
            l = mid+1,sul = mid;
        else
            r = mid-1;
    }
    if(strcmp(car[sul].name,p)==0)
        printf("%-3d-th  is  %s\n",sul+1,p);
    else
        printf("Can not find %s\n",p);
}
void Ram(){
    for(int i=0;i<k;i++){
        int len = rand()%11+10;
        for(int j=0;j<len;j++)
            car[i].name[j] = rand()&1?(rand()%10+'0'):(rand()%26+rand()&1?'a':'A');
        car[i].name[len] = '\0';
    }
}
void out(){
    for(int i=0;i<k;i++)
        printf("%-3d-th  is  %s\n",i+1,car[i].name);
}
void combsort(node car[],int n){
    int gap = n/1.3;
    while(gap){
        for(int i=0;i+gap<n;i+=gap)
        if(strcmp(car[i].name,car[i+gap].name)>0){
            char s[100];
            strcpy(s,car[i].name);
            strcpy(car[i].name,car[i+gap].name);
            strcpy(car[i+gap].name,s);
        }
        gap/=1.3;
    }
    gap = 1;
    while(gap){
        gap = 0;
        for(int i=0;i<n-1;i++)
        if(strcmp(car[i].name,car[i+1].name)>0){
            char s[100];
            strcpy(s,car[i].name);
            strcpy(car[i].name,car[i+1].name);
            strcpy(car[i+1].name,s);
            gap++;
        }
    }
}
int main(){
    srand(time(0));
    Ram();
    out();
    combsort(car,k);
    out();
    char s[100];
    while(1){
        printf("\n\tinput the array \n");
        scanf("%s",s);
        lower_bound_Find(car,k,s);
    }
    return 0;
}

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值