数据结构课程设计

报数问题
问题描述:有n个小朋友围成一圈玩游戏,小朋友从1至n编号,2号小朋友坐在1号小朋友的顺时针方向,3号小朋友坐在2号小朋友的顺时针方向,……,1号小朋友坐在n号小朋友的顺时针方向。
  游戏开始,从1号小朋友开始顺时针报数,接下来每个小朋友的报数是上一个小朋友报的数加1。若一个小朋友报的数为k的倍数或其末位数(即数的个位)为k,则该小朋友被淘汰出局,不再参加以后的报数。当游戏中只剩下一个小朋友时,该小朋友获胜。
  例如,当n=5, k=2时:
  1号小朋友报数1;
  2号小朋友报数2淘汰;
  3号小朋友报数3;
  4号小朋友报数4淘汰;
  5号小朋友报数5;
  1号小朋友报数6淘汰;
  3号小朋友报数7;
  5号小朋友报数8淘汰;
  3号小朋友获胜。
  给定n和k,请问最后获胜的小朋友编号为多少?
输入格式
  输入一行,包括两个整数n和k,意义如题目所述。
输出格式
  输出一行,包含一个整数,表示获胜的小朋友编号。
样例输入
5 2
样例输出
3
样例输入
7 3
样例输出
4
数据规模和约定
对于所有评测用例,1 ≤ n ≤ 1000,1 ≤ k ≤ 9。
要求:利用单向循环链表存储结构模拟此过程。

#include <iostream>
#include <bits/stdc++.h>
using namespace std;
//建立单向循环链表
typedef struct node{
    int data;
    struct node *next;
}Linknode,*linklist;
int initlink(linklist &h){
    h=new Linknode;
    h->data=1;
    h->next=h;
    return 0;
}
int createlink(linklist &h,int n){
    linklist p,q;
    p=h;
    int i=2;
    while(i<=n){
        q=new Linknode;
        q->data=i;
        q->next=h;
        p->next=q;
        p=p->next;
        i++;
    }
    return 0;
}
int output(linklist &h){
    linklist p;
    p=h;
    while(p->next!=h){
        cout<<p->data<<endl;
        p=p->next;
    }
    return 0;
}
int count_off(linklist &h,int n,int k){
    int cnt=0,flag=0;
    linklist p,q;
    p=h;
    while(p->next!=h){
        p=p->next;
    }//找到尾结点
    while(p->next!=p){
        cnt++;
        if(cnt%k==0||cnt%10==k){
                q=p->next;
                p->next=q->next;
                delete q;
        }
        else{
            p=p->next;
        }
    }
    flag=p->data;
    return flag;
}
int main(){
    int n;//共有n个小朋友
    int k;//小朋友报的数为k时进行操作
    int ans=0;//获胜小朋友编号
    while(cin>>n>>k){
    linklist h;
    initlink(h);
    createlink(h,n);
   // output(h);
    ans=count_off(h,n,k);
    printf("获胜的小朋友编号;");
    cout<<ans<<endl;
    }
    return 0;
}
/*
11 5 correct 8
12 6 correct 10
7 3 correct 4
7 4 correct 7
*/

迷宫问题求解
任务:可以输入一个任意大小的迷宫数据,用非递归的方法求出一条走出迷宫的路径,并将路径输出;
要求:在上交资料中请写明:存储结构、基本算法(可以使用程序流程图)、源程序、测试数据和结果、算法的时间复杂度、另外可以提出算法的改进方法;

#include <iostream>
#include <bits/stdc++.h>
using namespace std;
typedef struct node{
    int x;
    int y;
}Node;
int n,m;
Node path[1000005];
Node prelocal[1005][1005];
char mapp[1005][1005];
int mov[4][2]={{0,1},{0,-1},{-1,0},{1,0}};
bool flag[1005][1005];
queue<Node>vis;
int inputmap(int m,int n){
    for(int i=1;i<=m;i++){
        for(int j=1;j<=n;j++){
            cin>>mapp[i][j];
        }
    }
    return 0;
}
int bfs(int x,int y,int endx,int endy){
    int ans=0;
    vis.push({x,y});
    while(!vis.empty()){
        Node tmp=vis.front();
        vis.pop();
        ans++;
        flag[tmp.x][tmp.y]=1;
        if(tmp.x==endx&&tmp.y==endy)return ans;
        for(int i=0;i<4;i++){
            int nx=tmp.x+mov[i][0];
            int ny=tmp.y+mov[i][1];
            if(nx>=1&&nx<=m&&ny>=1&&ny<=n&&mapp[nx][ny]=='0'&&flag[nx][ny]==0){
                vis.push({nx,ny});
                ans++;
                flag[nx][ny]=1;
                prelocal[nx][ny]={tmp.x,tmp.y};
            }
        }
    }
    return 0;
}
int get_map(int x,int y,int bx,int by){
    int nx=x,ny=y;
        int cnt=0;
        while(1){
            path[cnt++]={nx,ny};
            if(nx==bx&&ny==by)break;
            int t1=nx,t2=ny;
            nx=prelocal[t1][t2].x;
            ny=prelocal[t1][t2].y;
        }
        return cnt;
}
int main(){
    int beginx,beginy,endx,endy;
    memset(flag,0,sizeof(flag));
    memset(mapp,-1,sizeof(mapp));
    while(cin>>m>>n){
        inputmap(m,n);
        cin>>beginx>>beginy>>endx>>endy;
        int ans=bfs(beginx,beginy,endx,endy);
        if(ans==0)printf("Sorry! We can't find the way.\n");
        else{
        int cnt=get_map(endx,endy,beginx,beginy);
        
        for(int i=cnt-1;i>=0;i--){
            i!=0?printf("(%d,%d)->",path[i].x,path[i].y):printf("(%d,%d)\n",path[i].x,path[i].y);
        }
        }
    }
    return 0;
}
/*
4 5
01100
01110
00001
11011
1 1
4 3

15 15
101111111000110
100111111110010
110111111111111
110000111111111
111110111111111
111110111111111
111110111111111
111110111111111
111110000011111
111111111011111
111111111001111
111100000011111
111101111111111
111100001111111
111111100000111
1 2
15 12

17 50
01111111111111111111111111111111111111111111111111
01111110000000111111111111111111111111111111110111
01111110111101111111111111111111111111111111000000
00000000111101111110000000000111111111111111110111
11111110111101111110111111111111111111111111110111
11111110111101111110111111111111111111111111110111
11111110111101111110111111111111111111111111110111
11111110111101111110000000000000000001111111110111
11111110111101111110111111111111111101111111110111
11111110000000000000111111111111111101111111110111
11111111111111111111111111111111111101111111110111
11111111111111111100000000000000000001100000000111
11111111111111111101111111111111111111101111110111
11111111111111111101111111111111111111101111110111
11111111111111111101111111111111111111101111110000
11111111111111111100000000000000000000001111111011
11111111111111111111111111111111111111111111111011
1 1
17 48
*/

二叉树的构造
任务:已知二叉树的层序和中序遍历序列,或已知二叉树的先序序列、中序序列,试编写算法建立该二叉树( 用递归或非递归的方法都可以)。
要求:能够输入树的各个结点,并能够输出用不同方法遍历的遍历序列;分别建立建立二叉树存储结构的的输入函数、输出层序遍历序列的函数、输出先序遍历序列的函数;

#include <iostream>
#include <bits/stdc++.h>
using namespace std;
typedef struct Benode{
    char data;
    struct Benode *lchild,*rchild;
}BeNode,*BeTree;
BeTree root;
char pre[1005],mid[1005];
int get_midpos(char s,int l,int r){
    for(int i=l;i<=r;i++){
        if(mid[i]==s)return i;
    }
    return -1;
}
//已知先序序列和中序序列
BeTree create(BeTree &t,int pos,int l,int r){
    int tmp=get_midpos(pre[pos],l,r);
    if(tmp==-1){
        t=NULL;
        return t;
    }
    t=new Benode;
    t->data=mid[tmp];
    create(t->lchild,pos+1,l,tmp-1);
    create(t->rchild,pos+tmp-l+1,tmp+1,r);
}
int DLR_output(BeTree &t){//先序
    if(t){
        cout<<t->data;
        DLR_output(t->lchild);
        DLR_output(t->rchild);
    }
    return 0;
}
int LDR_output(BeTree &t){//中序
    if(t){
        LDR_output(t->lchild);
        cout<<t->data;
        LDR_output(t->rchild);
    }
    return 0;
}
int LRD_output(BeTree &t){//后序
    if(t){
        LRD_output(t->lchild);
        LRD_output(t->rchild);
        cout<<t->data;
    }
    return 0;
}
int level_output(BeTree &t){//层序
    int front,rear;
    Benode *que[1005];
    front=rear=0;
    if(t){
        rear=(rear+1)%1005;
        que[rear]=t;
        while(rear!=front){
            front=(front+1)%1005;
            t=que[front];
            cout<<t->data;
            if(t->lchild){
                rear=(rear+1)%1005;
                que[rear]=t->lchild;
            }
            if(t->rchild){
                rear=(rear+1)%1005;
                que[rear]=t->rchild;
            }
        }
    }
    return 0;
}
int output(){
    printf("\n先序遍历: ");
    DLR_output(root);
    printf("\n中序遍历: ");
    LDR_output(root);
    printf("\n后序遍历: ");
    LRD_output(root);
    printf("\n层次遍历: ");
    level_output(root);
    cout<<endl;
}
int main(){
    cin>>pre;
    cin>>mid;
    int len=strlen(pre);
    create(root,0,0,len-1);
    output();
    return 0;
}
/*
ABDEFCHKGJ
DBFEAHKCJG

ABDHECFIJG
HDBEAIFJCG
*/

拓扑排序
任务:编写函数实现图的拓扑排序。

#include <iostream> 
#include <bits/stdc++.h>
using namespace std;
#define MAX_VERTEX_NUM 20
typedef int VertexType;
int indegree[MAX_VERTEX_NUM],ans[MAX_VERTEX_NUM];
typedef struct ArcNode{//边结点的类型定义
    int adjvex;//边的另一顶点的在数组中的位置
    ArcNode *nextarc;//指向下一边结点的指针
}ArcNode;
typedef struct Vnode{//顶点结点及其数组的定义类型
    VertexType data;//顶点信息
    ArcNode *firstarc;//指向关联该顶点的边链表
}Vnode,AdjList[MAX_VERTEX_NUM];
typedef struct{
    AdjList vertices;//顶点结点及其数组
    int vexnum,arcnum;//图的当前顶点数和边数
    int kind;//图的种类标志
}ALGraph;//图邻接表的类型
void createALGraph(ALGraph &G){
    int i,j,k;
    ArcNode *s;//定义一个边结点指针
    printf("input vexnum and arcnum:");
    scanf("%d%d",&G.vexnum,&G.arcnum);
    printf("\ninput vertex information:");
    for(int k=1;k<=G.vexnum;k++){
        scanf("%d",&G.vertices[k].data);
        G.vertices[k].firstarc=NULL;
    }
    printf("\ninput edges:");
    for(int k=1;k<=G.arcnum;k++){
        scanf("%d%d",&i,&j);
        indegree[j]++;
        s=new ArcNode;
        s->adjvex=j;
        s->nextarc=G.vertices[i].firstarc;
        G.vertices[i].firstarc=s;
    }
}
void FindInDegree(ALGraph &G,int indegree[]){
    int t;
    ArcNode *p;
    for(int k=1;k<=G.vexnum;k++){
        indegree[k]=0;//顶点度数初始化(入)
    }
    for(int k=1;k<=G.vexnum;k++){
        p=G.vertices[k].firstarc;
        while(p!=NULL){
            t=p->adjvex;
            indegree[t]++;
            p=p->nextarc;
        }
    }
}
int TopologicalSort(ALGraph G){
    int cnt=0;
    stack<int>s;  
    for(int i=1;i<=G.vexnum;i++){
        if(indegree[i]==0)
        s.push(i);
    }
    while(!s.empty()){
        int x=s.top();
        s.pop();
        ans[cnt++]=x;
        ArcNode *p=G.vertices[x].firstarc;
        while(p!=NULL) { 
            int k=p->adjvex;
            indegree[k]--;
            if(!indegree[k])
            s.push(k);
            p=p->nextarc;
        }
    }
    if(cnt<G.vexnum)return 0;
    else return 1;
}
int main(){
    memset(ans,0,sizeof(ans));
    memset(indegree,0,sizeof(indegree));
    ALGraph ALG;
    createALGraph(ALG);
    FindInDegree(ALG,indegree);
    int a=TopologicalSort(ALG);
    if(a==0)printf("该图不是有向无环图\n");
    else{
        printf("拓扑排序得到结点序列为:\n");
    for(int i=0;i<ALG.vexnum;i++){
        i==ALG.vexnum-1?cout<<ans[i]<<endl:cout<<ans[i]<<" ";
    }
    }
    return 0;
}
/*
12 16
1 2 3 4 5 6 7 8 9 10 11 12
1 4 1 2 1 3 1 12 4 5 2 3 3 5 3 7 5 7 3 8 9 12 9 10 10 12 9 11 11 6 6 8

7 9
1 2 3 4 5 6 7
1 2 1 3 2 4 2 5 2 3 4 5 3 6 6 7 7 5

非有向无环图
7 10
1 2 3 4 5 6 7
1 2 1 3 2 4 2 5 2 3 4 5 3 6 6 7 7 5 5 6

*/

散列表的插入、删除和查找
功能要求:
(1)初始化散列表;
(2)向散列表中插入一个元素;
(3)从散列表中删除一个元素;
(4)从散列表中查找一个元素。
散列表通常采用链接法处理冲突,散列文件中每个节点的类型定义为:
Struct FLNode
{ //散列主文件中的节点类型
ElemType data ; //值域
Int next; //指向下一个节点的指针域
};
其中data域用来存储待散列的元素,next域用来存储下一个同义词元素在散列表中的存储位置,即所在节点的位置号。

#include <iostream>
#include <bits/stdc++.h>
using namespace std;
typedef int ElemType;
typedef struct FLnode{
    ElemType data;
    struct FLnode *next;
}FLNode,*HashTable,**TypeHash;
int mod;
int init(TypeHash &H){
    H=new HashTable[mod];
    for(int i=0;i<mod;i++){
        H[i]=NULL;
    }
    return 0;
}
int Insert(TypeHash &H,int x){
    HashTable insertt;
    insertt=new FLNode;
    insertt->data=x;
    insertt->next=H[x%mod];
    H[x%mod]=insertt;
    return 0;
}
int Search(TypeHash &H,int x){
    HashTable pointer=H[x%mod],t;
    int cnt=1,flag=0;
    while(pointer!=NULL){
        if(pointer->data==x){
            flag=1;
            break;
        }
    pointer=pointer->next;
    cnt++;
    }
    if(flag==0)printf("未能找到该元素\n");
    else printf("该元素在Hash表中第%d行第%d个\n",x%mod,cnt);
    return flag;
}
void Delete(TypeHash &H,int x){
    if(!Search(H,x)){
        printf("不需要进行删除操作\n");
        return;
    }
    else{
        printf("可以进行删除操作\n");
        HashTable pointer=H[x%mod],prior;
        while(pointer!=NULL){
            if(pointer->data==x){
                H[x%mod]=pointer->next;
                delete pointer;
                return;
            }
            while(pointer!=NULL){
                if(pointer->data==x){
                    prior->next=pointer->next;
                    HashTable tmp=pointer;
                    pointer=pointer->next;
                    delete tmp;
                    break;
                }
            }   
            prior=pointer;
            pointer=pointer->next;
        }
    }
    return;
}
void output(TypeHash &H){
    for(int i=0;i<mod;i++){
        printf("%d:",i);
        HashTable pointer=H[i];
        while(pointer!=NULL){
            cout<<pointer->data<<" ";
            pointer=pointer->next;
        }
        cout<<endl;
    }
    return;
}
int main(){
    TypeHash H;
    int x,del,searchh;
    cin>>mod;
    init(H);//初始化散列表
    printf("请输入待存储数据(输入0截止):\n");
    while(cin>>x&&x!=0){//待存储数据
    Insert(H,x);//插入法将数据存入H中
    }
    printf("当前散列表:\n");
    output(H);
    printf("请输入待查找数据(输入0截至):\n");
    while(cin>>searchh&&searchh!=0){
        Search(H,searchh);
    }
    printf("请输入待删除数据(输入0截止):\n");
    while(cin>>del&&del!=0){
    Delete(H,del);
    printf("当前Hash表为:\n");
    output(H);
    }
    printf("输出操作后Hash表:\n");
    output(H);
    return 0;
}
/*
5
19 14 23 1 68 20 84 27 55 11 10 79 0
10 20 0
10 12 0
*/
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值