数据结构课设

运动会分数

#include <math.h>
#include <process.h>
#include <stdio.h>

#define N 20 //学校最大数目
#define M 20 //男子项目最大数
#define W 20 //女子项目最大数

//存放项目信息的结构体
typedef struct
{
    int inum;     //项目编号
    int top;      //取名次的数目
    int range[5]; //名次
    int mark[5];  //分数
} itemnode;

//存放学校信息的结构体
typedef struct
{
    int snum;          //学校编号
    int score;         //学校总分
    int mscore;        //男子总分
    int wscore;        //女子总分
    itemnode t[M + W]; //项目数组
} snode;
snode a[N]; //定义一个学校数组

//菜单函数
void menu(int n, int m, int w)
{ //n代表学校数,m代表男子数,w代表女子数
    int c;
    void input(int n, int m, int w);   //输入功能
    void output(int n, int m, int w);  //输入功能
    void sortput(int n, int m, int w); //排序输出
    void search(int n, int m, int w);  //查询功能
    printf("\t\t\t欢迎使用\t\t\t\t\t\n");
    printf("华信运动会分数统计系统\n\n");
    printf("1.信息输入\n");
    printf("2.统计输出\n");
    printf("3.排序输出\n");
    printf("4.信息查询\n");
    printf("5.退出系统\n\n");
    printf("=======================================================\n\n");
    printf("请输入您想要实现的功能(0--4):");
    scanf("%d", &c);
    switch (c)
    {
    case 1:
        input(n, m, w);
        break;
    case 2:
        output(n, m, w);
        break;
    case 3:
        sortput(n, m, w);
        break;
    case 4:
        search(n, m, w);
        break;
    case 5:
        printf("感谢使用,祝您天天开心!!\n");
        exit(0); //正常退出
    default:
        printf("您输入有误,请重新输入!");
        menu(n, m, w);
    }
}

//将信息写入文件中
void savetofile()
{
    FILE *fp; //定义一个文件指针
    int i;
    if (NULL == (fp = fopen("file.txt", "w")))
    {
        printf("打开文件失败!\n");
        return;
    }
    for (i = 0; i < N; i++)
    {
        if ('\0' != a[i].snum)
            if (fwrite(&a[i], sizeof(snode), 1, fp) != 1)
            {
                printf("存入信息失败!\n");
                return;
            }
    }
    fclose(fp); //关闭文件
}

//将信息从文件里取出
void readfromfile()
{
    int i;
    FILE *fp;
    if ((fp = fopen("file.txt", "rb")) == NULL)
    {
        printf("文件打开失败!\n");
        return;
    }
    for (i = 0; i < N; i++)
    {
        fread(&a[i], sizeof(snode), 1, fp);
    }
    fclose(fp);
}

//信息输入功能
void input(int n, int m, int w)
{
    int i, j, s, k, q = 1;
    for (i = 0; i < n; i++)
    {
        printf("请输入学校的编号:");
        scanf("%d", &a[i].snum);
        for (j = 0; j < m + w; j++)
        { //总的项目的输入
            printf("请输入项目编号:");
            scanf("%d", &a[i].t[j].inum);
            printf("请输入该项目取前3还是前5(输入3或5):");
            scanf("%d", &a[i].t[j].top);
            if (3 == a[i].t[j].top)
            {
                printf("获得的名次的个数(1--3):");
            }
            else if (5 == a[i].t[j].top)
            {
                printf("获得的名次的个数(1--5):");
            }
            else
            {
                printf("输入有误!程序退出....");
                return;
            }
            scanf("%d", &k); //输入获得名次的个数
            for (s = 0; s < k; s++)
            {
                if (3 == a[i].t[j].top)
                {
                    printf("请输入获得的名次(1--3):");
                }
                else
                {
                    printf("请输入获得的名次(1--5):");
                }
                scanf("%d", &a[i].t[j].range[s]); //输入所获得的名次的信息
            }
            printf("\n");
        }
    }
    for (i = 0; i < n; i++)
    {
        //初始化分数
        a[i].score = 0;  //学校总分
        a[i].mscore = 0; //男子总分
        a[i].wscore = 0; //女子总分
    }
    for (i = 0; i < n; i++)
    {
        for (j = 0; j < m + w; j++)
        {
            if (0 == i)
            {
                printf("项目%d取得是前3还是前5(输入3或5):", j + 1);
                scanf("%d", &a[i].t[j].top);
            }
            for (s = 0; s < 5; s++)
            {
                if (3 == a[i].t[j].top)
                { //如果是取前三
                    switch (a[i].t[j].range[s])
                    {
                    case 0:
                        a[i].t[j].mark[s] = 0;
                        break;
                    case 1:
                        a[i].t[j].mark[s] = 5;
                        break;
                    case 2:
                        a[i].t[j].mark[s] = 3;
                        break;
                    case 3:
                        a[i].t[j].mark[s] = 2;
                        break;
                    }
                }
                else if (5 == a[i].t[j].top)
                {
                    switch (a[i].t[j].range[s])
                    {
                    case 0:
                        a[i].t[j].mark[s] = 0;
                        break;
                    case 1:
                        a[i].t[j].mark[s] = 7;
                        break;
                    case 2:
                        a[i].t[j].mark[s] = 5;
                        break;
                    case 3:
                        a[i].t[j].mark[s] = 3;
                        break;
                    case 4:
                        a[i].t[j].mark[s] = 2;
                        break;
                    case 5:
                        a[i].t[j].mark[s] = 1;
                        break;
                    }
                }
                else if (a[i].t[j].top != 3 || a[i].t[j].top != 5)
                {
                    printf("信息输入错误!程序退出\n");
                    printf("\n");
                    exit(0);
                }
                a[i].score = a[i].score + a[i].t[j].mark[s]; //学校总分
                if (j < m)
                {
                    a[i].mscore = a[i].mscore + a[i].t[j].mark[s];
                }
                else
                { //女子总分
                    a[i].wscore = a[i].wscore + a[i].t[j].mark[s];
                }
            }
        }
    }
    printf("输入完毕!(返回菜单请输入1):");
    scanf("%d", &q);
    printf("\n");
    if (q != 1)
    {
        printf("不能再添加信息了!");
    }
    printf("\n");
    savetofile(); //保存文件
    menu(n, m, w);
}

#if (1)
void output(int n, int m, int w) /*2.统计输出*/
{
    readfromfile();
    int i, j, s, q = 0;
    for (i = 0; i < n; i++) /*显示结果*/
    {
        printf("学校编号:%d  学校总分:%d   男子总分:%d  女子总分:%d\n", a[i].snum, a[i].score, a[i].mscore, a[i].wscore);
        for (j = 0; j < m + w; j++)
        {
            printf("项目编号:%d  所取名次数量:%d\n", a[i].t[j].inum, a[i].t[j].top);
            for (s = 0; s < 5; s++)
            {
                if (a[i].t[j].range[s] != 0)
                    printf("名次:%d  分数:%d\n", a[i].t[j].range[s], a[i].t[j].mark[s]);
            }
        }
        printf("\n");
    }
    printf("\n");
    printf("统计完毕!返回?  1是 2否"); /*返回菜单*/
    scanf("%d", &q);
    printf("\n");
    if (q != 1)
        printf("统计已经结束!");
    printf("\n");
    menu(n, m, w);
}
#endif

//排序输出
void sortput(int n, int m, int w)
{
    readfromfile();
    int c, i, j, k, q = 0;
    int temp[N];
    printf("\t**************排序输出系统**************\n\n");
    printf("\t\t****1.按学校编号输出****\n");
    printf("\t\t****2.按学校总分输出****\n");
    printf("\t\t****3.按男子总分输出****\n");
    printf("\t\t****4.按女子总分输出****\n");
    printf("=======================================================\n\n");
    do
    {
        printf("请选择您想实现的功能的编号(1--4):");
        scanf("%d", &c);
        switch (c)
        {
        case 1:
            for (i = 0; i < n; i++)
            {
                temp[i] = i;
            }
            //用的是冒泡排序输出
            for (i = 0; i < n; i++)
            {
                for (j = i + 1; j < n; j++)
                {
                    if (a[temp[i]].snum > a[j].snum)
                    {
                        k = temp[i];
                        temp[i] = temp[j];
                        temp[j] = k;
                    }
                }
            }
            for (i = 0; i < n; i++)
            {
                printf("学校标号:%d  学校总分:%d  男子总分:%d   女子总分:%d\n", a[temp[i]].snum, a[temp[i]].score, a[temp[i]].mscore, a[temp[i]].wscore);
            }
            break;
        case 2:
            for (i = 0; i < n; i++)
            {
                temp[i] = i;
            }
            for (i = 0; i < n; i++)
            {
                for (j = i + 1; j < n; j++)
                {
                    if (a[temp[i]].score < a[j].score)
                    {
                        k = temp[i];
                        temp[i] = temp[j];
                        temp[j] = k;
                    }
                }
            }
            for (i = 0; i < n; i++)
            {
                printf("学校编号:%d  学校总分:%d   男子总分:%d   女子总分:%d\n", a[temp[i]].snum, a[temp[i]].score, a[temp[i]].mscore, a[temp[i]].wscore);
            }
            break;
        case 3:
            for (i = 0; i < n; i++)
            {
                temp[i] = i;
            }
            for (i = 0; i < n; i++)
            {
                for (j = i + 1; j < n; j++)
                {
                    if (a[temp[i]].mscore < a[j].mscore)
                    {
                        k = temp[i];
                        temp[i] = temp[j];
                        temp[j] = k;
                    }
                }
            }
            for (i = 0; i < n; i++)
            {
                printf("学校编号:%d  学校总分:%d  男团总分:%d  女团总分:%d\n", a[temp[i]].snum, a[temp[i]].score, a[temp[i]].mscore, a[temp[i]].wscore);
            }
            break;
        case 4:
            for (i = 0; i < n; i++)
            {
                temp[i] = i;
            }
            for (i = 0; i < n; i++)
            {
                for (j = i + 1; j < n; j++)
                {
                    if (a[temp[i]].wscore < a[j].wscore)
                    {
                        k = temp[i];
                        temp[i] = temp[j];
                        temp[j] = k;
                    }
                }
            }
            for (i = 0; i < n; i++)
            {
                printf("学校编号:%d  学校总分:%d  男团总分:%d  女团总分:%d\n", a[temp[i]].snum, a[temp[i]].score, a[temp[i]].mscore, a[temp[i]].wscore);
            }
            break;
        default:
            printf("您的输入有误!请从新输入...");
        }
        printf("请选择 1.返回主菜单  0.继续");
        scanf("%d", &q);
        printf("\n");
    }
    //=======================
    while (0 == q);
    printf("\n");
    //=======================
    if (q != 0)
    {
        menu(n, m, w);
    }
}

//查询功能
void search(int n, int m, int w)
{
    readfromfile();
    int c, i, j, k, d, l, q = 0;
    printf("\t****************查询系统****************\n\n");
    printf("\t\t****1.按学校编号查询****\n");
    printf("\t\t****2.按项目编号查询****\n");
    printf("=======================================================\n\n");
    do
    {
        k = -1;
        d = -1;
        l = -1;
        printf("请选择要实现功能的编号(1--2):");
        scanf("%d", &c);
        switch (c)
        {
        case 1:
            printf("要查询的学校编号:"); /*查找学校编号下标*/
            scanf("%d", &c);
            for (i = 0; i < n; i++)
            {
                if (c == a[i].snum)
                {
                    k = i;
                }
            }
            if (-1 == k)
            {
                printf("错误:这个学校没有参加此次运动会!\n");
            }
            else
            {
                printf("要查询的项目编号:"); /*查找项目编号下标*/
                scanf("%d", &c);
                for (j = 0; j < m + w; j++)
                {
                    if (c == a[k].t[j].inum)
                    {
                        d = j;
                    }
                }
                if (-1 == d)
                {
                    printf("此次运动会没有这个项目\n");
                }
                else
                {
                    printf("这个项目取前 %d名,该学校的成绩如下:\n", a[k].t[d].top);
                    for (i = 0; i < 5; i++)
                    {
                        if (a[k].t[d].range[i] != 0)
                        {
                            printf("名次:%d\n", a[k].t[d].range[i]);
                        }
                    }
                }
            }
            break;
        case 2:
            printf("要查询的项目编号:"); /*查找项目编号下标*/
            scanf("%d", &c);
            for (i = 0; i < n; i++)
            {
                for (j = 0; j < m + w; j++)
                {
                    if (c == a[i].t[j].inum)
                    {
                        l = j;
                    }
                    if (-1 == l)
                    {
                        printf("此次运动会没有该项目");
                    }
                    else
                    {
                        printf("该项目取前 %d名,取得名次的学校\n", a[0].t[l].top);
                        for (i = 0; i < n; i++)
                        {
                            for (j = 0; j < 5; j++)
                            {
                                if (a[i].t[l].range[j] != 0)
                                {
                                    printf("学校编号:%d,名次:%d\n", a[i].snum, a[i].t[l].range[j]);
                                }
                            }
                        }
                    }
                }
            }
            break;
        default:
            printf("输入错误,请重试!\n");
        }
        printf("请选择:1.返回主菜单 0.继续");
        scanf("%d", &q);
        printf("\n");
    } while (0 == q);
    printf("\n");
    if (q != 0)
    {
        menu(n, m, w);
    }
}

//主函数
int main()
{
    system("chcp 65001&cls"); //更改外部控制台编码为utf-8并清屏
    int n, m, w;              //n为学校个数,m为男子数,w为女子数
    printf("\t\t\t欢迎使用\t\t\t\t\n\n");
    printf("\t***********运动会分数统计系统***********\n\n");
    printf("请先输入运动会主要信息\n");
    printf("输入学校个数:");
    scanf("%d", &n);
    printf("输入男子项目个数:");
    scanf("%d", &m);
    printf("输入女子项目个数:");
    scanf("%d", &w);
    menu(n, m, w);
}

迷宫问题

#include <fstream>
#include <iostream>
#include <stdio.h>
using namespace std;
const int MAXLENGTH = 25;
typedef int MazeType[MAXLENGTH][MAXLENGTH]; // 迷宫数组[行][列]
const int MAXSIZE = 576;
const int OK = 1;
const int ERROR = 0;
MazeType m;      //声明一个全局迷宫对象m
int curstep = 1; //走的路径长度
typedef struct   //坐标
{
    int X;
    int Y;
} PosType; //坐标结构体
typedef struct
{
    int ord;      //通道块在路径上的“序号”
    PosType seat; //通道块在迷宫中的“坐标位置”
    int di;       //从从此通道块走向下一通道块的“方向”
} SElemType;      //栈的元素类型
typedef struct
{
    SElemType *base;
    SElemType *top;
    int stacksize;
} Stack;
int InitStack(Stack &S) // 构造一个空栈S
{
    S.base = new SElemType[MAXSIZE];
    S.top = S.base;
    S.stacksize = MAXSIZE;
    return OK;
}

int Push(Stack &S, SElemType e) //入栈
{
    if (S.top - S.base == S.stacksize)
    {
        return ERROR;
    }
    *(S.top)++ = e;
    return OK;
}

int Pop(Stack &S, SElemType &e) //出栈,移除当前栈顶元素
{
    if (S.top == S.base)
        return ERROR;
    e = *--S.top;
    return OK;
}

int StackEmpty(Stack S) //检测是否为空栈
{
    if (S.top == S.base)
        return OK;
    else
        return ERROR;
}
int Pass(PosType b) // 当迷宫m的b点的序号为1(可通过路径)
{
    if (m[b.X][b.Y] == 1)
        return OK;
    else
        return ERROR;
}
void FootPrint(PosType &a) // 使迷宫m的a点的序号变为足迹(curstep)
{
    m[a.X][a.Y] = curstep;
}
PosType NextPos(PosType c, int di) // 根据当前位置及移动方向,返回下一位置
{
    PosType dir[4] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}}; // {行增量,列增量}
    //方向依次为上右下左
    c.X += dir[di].X;
    c.Y += dir[di].Y;
    return c;
}
void MarkPrint(PosType b)
{
    m[b.X][b.Y] = -1; // 使迷宫m的b点的序号变为-1(不能通过的路径)
}
int MazePath(PosType start, PosType end) // 若迷宫maze中存在从入口start到出口end的通道,则求得一条存放在栈中(从栈底到栈顶)
{
    Stack S;
    PosType curpos;
    SElemType e;
    InitStack(S);
    curpos = start; //把入口设置为当前位置
    do              //应为栈一开始是空的所以 do while
    {
        if (Pass(curpos))
        {                      // 当前位置可以通过,即是未曾走到过的通道块
            FootPrint(curpos); // 留下足迹
            e.ord = curstep;
            e.seat.X = curpos.X;
            e.seat.Y = curpos.Y; //当前位置
            e.di = 0;
            Push(S, e);                                 // 入栈当前位置及状态
            curstep++;                                  // 足迹加1
            if (curpos.X == end.X && curpos.Y == end.Y) // 到达终点(出口)
                return OK;
            curpos = NextPos(curpos, e.di); //将当前位置变为e.di方向上的临近通道块
        }
        else
        { // 当前位置不能通过
            if (!StackEmpty(S))
            {
                Pop(S, e);                          // 退栈到前一位置
                curstep--;                          //走的路径长度
                while (e.di == 3 && !StackEmpty(S)) // 前一位置处于最后一个方向(北),即当前位置的四周都无法通过
                {
                    MarkPrint(e.seat); // 留下不能通过的标记(-1)
                    Pop(S, e);         // 退回一步
                    curstep--;
                }
                if (e.di < 3) // 没到最后一个方向(北)
                {
                    e.di++; // 换下一个方向探索
                    Push(S, e);
                    curstep++;
                    curpos = NextPos(e.seat, e.di); // 设定当前位置是该新方向上的相邻块
                }
            }
        }
    } while (!StackEmpty(S));
    return ERROR;
}
void Print(int x, int y) // 输出迷宫图,0表示墙,1表示通路
{
    int i, j;
    for (i = 0; i < x; i++)
    {
        for (j = 0; j < y; j++)
            printf("%3d", m[i][j]);
        printf("\n");
    }
}
#define readDataPath "D:\\useful\\program\\dswork\\2maze\\shuju.txt"
int main()
{
    system("chcp 65001&cls"); //更改外部控制台编码为utf-8并清屏
    int X, Y, i, j, n;
    cout << "输入迷宫行列数(X,Y):";
    cin >> X >> Y;
    FILE *fp = fopen(readDataPath, "r"); //打开文件
    for (i = 0; i < X; i++)
    {
        for (j = 0; j < Y; j++)
        {
            fscanf(fp, "%d", &m[i][j]); /*每次读取一个数,fscanf函数遇到空格或者换行结束*/
        }
        fscanf(fp, "\n");
    }
    fclose(fp);
    PosType a, b;
    cout << "输入起点,终点下标:";
    cin >> a.X >> a.Y >> b.X >> b.Y;
    if (MazePath(a, b))
    {
        Print(X, Y);
    }
    else
    {
        cout << "没有路径可以到达" << endl;
    }
    system("pause");
}

行车路线问题

#include <algorithm>
#include <cstdio>
#include <math.h>
#include <queue>
#include <string.h>
#include <vector>
using namespace std;
long long int n, m, t, a, b, c, ans, tmp, dist[505][3]; //0前面的节点是大路的最小疲劳 1前面节点是小路的最小疲劳 2到此为止小路的长度
bool vis[505], f;
const long long int inf = 0x7f7f7f7f7f7f7f7f;
struct Path
{
    long long int c;
    Path()
    {
        c = inf;
    }
} path[505][505], path1[505][505];
deque<int> q;

int main()
{
    scanf("%d%d", &n, &m); //路口(1~n)和道路的数量
    for (int i = 0; i < m; i++)
    {
        scanf("%d%d%d%d", &t, &a, &b, &c);
        if (t == 0)
        {
            path[a][b].c = path[a][b].c < c ? path[a][b].c : c; //可能有重复的边 存小的
            path[b][a] = path[a][b];
        }
        else
        {
            path1[a][b].c = path1[a][b].c < c ? path1[a][b].c : c;
            path1[b][a] = path1[a][b];
        }
    }
    memset(vis, 0, sizeof(vis));
    memset(dist, 0x7f, sizeof(dist));
    for (int i = 1; i <= n; i++)
        dist[i][2] = 0;
    dist[1][0] = dist[1][1] = 0;
    q.push_back(1);
    vis[1] = true;
    while (!q.empty())
    { //spfa主代码
        int v = q.front();
        q.pop_front();
        vis[v] = 0;
        for (int i = 2; i <= n; i++)
        {
            f = false;
            if (path[v][i].c != inf)
            { //大路
                if (dist[v][0] != inf && path[v][i].c != inf && dist[v][0] + path[v][i].c < dist[i][0])
                {
                    dist[i][0] = dist[v][0] + path[v][i].c;
                    f = true;
                }
                if (dist[v][1] != inf && path[v][i].c != inf && (dist[v][1] + path[v][i].c < dist[i][0]))
                {
                    dist[i][0] = dist[v][1] + path[v][i].c;
                    f = true;
                }
            }
            if (path1[v][i].c != inf)
            { //小路
                if (dist[v][0] != inf && path1[v][i].c != inf && dist[v][0] + path1[v][i].c * path1[v][i].c < dist[i][1])
                {
                    dist[i][1] = dist[v][0] + path1[v][i].c * path1[v][i].c;
                    f = true;
                    dist[i][2] = path1[v][i].c;
                }
                if (dist[v][1] != inf && path1[v][i].c != inf)
                {
                    long long int tmp = dist[v][1] - dist[v][2] * dist[v][2] + (path1[v][i].c + dist[v][2]) * (path1[v][i].c + dist[v][2]);
                    if (tmp < dist[i][1])
                    {
                        dist[i][1] = tmp;
                        f = true;
                        dist[i][2] = dist[v][2] + path1[v][i].c;
                    }
                }
            }
            if (f && vis[i] == 0)
            {
                vis[i] = true;
                q.push_back(i);
            }
        }
    }
    printf("%lld\n", min(dist[n][0], dist[n][1]));
    system("pause");
    return 0;
}

线索化二叉树

#include <bits/stdc++.h>
#include <conio.h>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>

typedef enum
{
    Link,
    Thread
} Pointertag;

typedef struct Tree_Node
{
    struct Tree_Node *left;
    struct Tree_Node *right;
    char ch;
    Pointertag ltag;
    Pointertag rtag;
} Tree;

Tree *pre;

void menu()
{
    system("cls");
    printf("********************\n");
    printf("1.构建二叉树\n");
    printf("2.先序线索化\n");
    printf("3.中序线索化\n");
    printf("4.后序线索化\n");
    printf("********************\n");
}

Tree *create(FILE *fp)
{
    Tree *tree;
    char ch;
    if (!fp)
        fp = fopen("info.txt", "r");
    fscanf(fp, "%c", &ch);
    if (ch == '@')
        tree = NULL;
    else
    {
        tree = (Tree *)malloc(sizeof(Tree));
        tree->ch = ch;
        tree->left = create(fp);
        tree->right = create(fp);
    }
    return tree;
}

void in_thread(Tree_Node *root, Tree_Node **ptmp)
{
    if ((root == NULL))
        return;

    in_thread(root->left, ptmp);

    if (root->left == NULL)
    {
        root->left = *ptmp;
        root->ltag = Thread;
    }
    if (*ptmp != NULL && (*ptmp)->right == NULL)
    {
        (*ptmp)->right = root;
        (*ptmp)->rtag = Thread;
    }

    (*ptmp) = root;
    in_thread(root->right, ptmp);
    return;
}

Tree_Node *in_thread_nextNode(Tree_Node *root)
{
    Tree_Node *ret = NULL;

    if (root == NULL)
        return ret;
    if (root->rtag == 1) // 右标志位 1,可以直接得到后继节点
    {
        ret = root->right;
    }
    else // 右标志位0,则要找到右子树最左下角的节点
    {
        ret = root->right;
        while (ret->ltag == 0) // 查找最左下节点的位置
        {
            ret = ret->left;
        }
    }
    return ret;
}

void in_thread_Older_next(Tree_Node *root)
{
    if (root == NULL)
        return;

    while (root->ltag == 0) // 查找中序遍历的第一个节点,当ltag == 0的话
        root = root->left;

    printf("%c ", root->ch); // 访问第一个节点

    while (root->right != NULL) // 当root存在后继,依次访问后继节点
    {
        root = in_thread_nextNode(root);
        printf("%c ", root->ch);
    }

    printf("\n");
    return;
}

void preOrderThread(Tree_Node *root)
{
    if (root == NULL)
        return;
    if (root->left == NULL)
    {
        root->ltag = Thread;
        root->left = pre;
    }
    if (pre && pre->right == NULL)
    {
        pre->rtag = Thread;
        pre->right = root;
    }

    pre = root;

    if (root->ltag == Link) //防止栈溢出
        preOrderThread(root->left);
    if (root->rtag == Link)
        preOrderThread(root->right);
}

void preOrder(Tree_Node *root)
{
    if (root == NULL)
        return;
    Tree_Node *cur = root;
    while (cur)
    {
        while (cur && cur->ltag == Link)
        {
            printf("%c ", cur->ch);
            // cout <<  << " ";
            cur = cur->left;
        }
        printf("%c ", cur->ch);
        // cout << cur->ch << " ";
        //将该树的后继当成子树来访问
        cur = cur->right;

        while (cur && cur->rtag == Thread)
        {
            cur = cur->right;
            printf("%c ", cur->ch);
        }
        cur = cur->right;
    }
}

template<class T>
void Thread_Binary_tree<T>::PreOrder_Thread_Op(BT_Thread_Node<T>* &Tree)
{
	if (Tree == NULL)
		return;
 
	if (Tree->Left_Child == NULL)		//根
	{
		Tree->Ltag = Thread;
		Tree->Left_Child = Pre_Node;
	}
 
	if (Pre_Node != NULL && Pre_Node->Right_Child == NULL)
	{
		Pre_Node->Rtag = Thread;
		Pre_Node->Right_Child = Tree;
	}
 
	Pre_Node = Tree;
	if (Tree->Ltag == Link)
		PreOrder_Thread_Op(Tree->Left_Child);		//左孩子节点
	if (Tree->Rtag == Link)
		PreOrder_Thread_Op(Tree->Right_Child);		//右孩子节点
 
}


void midThread(Tree *tree)
{
    if (tree)
    {
        midThread(tree->left);
        printf("%c ", tree->ch);
        if (!tree->left)
        {
            tree->ltag = Thread;
            tree->left = pre;
        }
        if (!tree->right)
            tree->rtag = Thread;
        if (pre && pre->rtag == Thread)
            pre->right = tree;
        pre = tree;
        midThread(tree->right);
    }
}

void backThread(Tree *tree)
{
    if (tree)
    {
        backThread(tree->left);
        backThread(tree->right);
        printf("%c ", tree->ch);
        if (!tree->left)
        {
            tree->ltag = Thread;
            tree->left = pre;
        }
        if (!tree->right)
            tree->rtag = Thread;
        if (pre && pre->rtag == Thread)
            pre->right = tree;
        pre = tree;
    }
}

int main()
{
    system("chcp 65001&cls"); //更改外部控制台编码为utf-8并清屏
    int mode;
    Tree *tree, *midthtree;
    FILE *fp = NULL;
    tree = create(fp);
    while (1)
    {
        menu();
        scanf("%d", &mode);
        pre = NULL;
        switch (mode)
        {
        case 1:
            printf("先序线索化结果如下:");
            preOrderThread(tree);
            preOrder(tree);
            tree = create(fp);
            printf("键入任意键返回");
            _getch();
            break;
        case 2:
            printf("中序线索化结果如下:");
            midThread(tree);
            tree = create(fp);
            printf("键入任意键返回");
            _getch();
            break;
        case 3:
            printf("后序线索化结果如下:");
            backThread(tree);
            tree = create(fp);
            printf("键入任意键返回");
            _getch();
            break;
        }
    }
}
// DFBAEC  FDBECA

索引文件问题

#include <bits/stdc++.h>
#include <malloc.h>
#include <stdio.h>
#include <string.h>
#define MaxRec 100   //最多的记录个数
typedef struct Index //定义索引文件结构
{
    int no;      //学号
    long offset; //主文件中的记录号
} Index;
typedef struct
{
    int no;               //学号
    char name[10];        //姓名
    int age;              //年龄
    char sex[5];          //性别
    int deg1, deg2, deg3; //课程1-课程3成绩
} StudType;
void InsertSort(Index R[], int n) //采用直接插入排序法对R[0..n-1]按学号递增排序
{
    int i, j;
    Index temp;
    for (i = 1; i < n; i++)
    {
        temp = R[i];
        j = i - 1;
        while (j >= 0 && temp.no < R[j].no)
        {
            R[j + 1] = R[j]; //将关键字大于R[i].key的记录后移
            j--;
        }
        R[j + 1] = temp; //在j+1处插入R[i]
    }
}
void CreatIdxFile() //建立索引文件
{
    FILE *mfile, *idxfile;
    Index idx[MaxRec];
    StudType st;
    int n = 0, i;
    if ((mfile = fopen("stud.dat", "rb")) == NULL)
    {
        printf("  提示:不能打开主文件\n");
        return;
    }
    if ((idxfile = fopen("index.dat", "wb")) == NULL)
    {
        printf("  提示:不能建立索引文件\n");
        return;
    }
    i = 0;
    while ((fread(&st, sizeof(StudType), 1, mfile)))
    {
        idx[i].no = st.no;
        idx[i].offset = ++n;
        i++;
    }
    InsertSort(idx, n); //对idx数组按no值排序
    rewind(idxfile);
    for (i = 0; i < n; i++)
        fwrite(&idx[i], sizeof(Index), 1, idxfile);
    fclose(mfile);
    fclose(idxfile);
    printf("  提示:索引文件建立完毕\n");
}
void OutputMainFile() //输出主文件全部记录
{
    FILE *mfile;
    StudType st;
    int i = 1;
    if ((mfile = fopen("stud.dat", "rb")) == NULL)
    {
        printf("  提示:不能读主文件\n");
        return;
    }
    printf("                ----学生成绩表----\n");
    printf("记录号  学号     姓名   年龄 性别 语文 数学 英语\n");
    while ((fread(&st, sizeof(StudType), 1, mfile)) == 1)
    {
        printf("%6d%5d%10s%6d%5s%5d%5d%5d\n", i, st.no, st.name, st.age, st.sex, st.deg1, st.deg2, st.deg3);
        i++;
    }
    fclose(mfile);
}
void OutputIdxFile() //输出索引文件全部记录
{
    FILE *idxfile;
    Index irec;
    printf("     ----学生索引表----\n");
    printf("\t学号  记录号\n");
    if ((idxfile = fopen("index.dat", "rb")) == NULL)
    {
        printf("  提示:不能读索引文件\n");
        return;
    }
    while ((fread(&irec, sizeof(Index), 1, idxfile)) == 1)
        printf("\t%5d%6ld\n", irec.no, irec.offset);
    fclose(idxfile);
}
void ReadIndexFile(Index idx[MaxRec], int &n) //读索引文件数据存入idx数组中
{
    int j;
    FILE *idxfile;
    if ((idxfile = fopen("index.dat", "rb")) == NULL)
    {
        printf("  提示:索引文件不能打开\n");
        return;
    }
    fseek(idxfile, 0, 2);
    j = ftell(idxfile); //j求出文件长度
    rewind(idxfile);
    n = j / sizeof(Index); //n求出文件中的记录个数
    fread(idx, sizeof(Index), n, idxfile);
    fclose(idxfile);
}
int SearchNum(Index idx[], int n, int no) //在含有n个记录的索引文件idx中查找学号为no的记录对应的记录号
{
    int mid, low = 0, high = n - 1;
    while (low <= high) //二分查找
    {
        mid = (low + high) / 2;
        if (idx[mid].no > no)
            high = mid - 1;
        else if (idx[mid].no < no)
            low = mid + 1;
        else //idx[mid].no==no
            return idx[mid].offset;
    }
    return -1;
}
void FindStudent() //输出指定学号的记录
{
    int no;
    FILE *mfile;
    Index idx[MaxRec];
    StudType st;
    int i, n;
    if ((mfile = fopen("stud.dat", "rb+")) == NULL)
    {
        printf("  提示:主文件中没有任何记录\n");
        return;
    }
    ReadIndexFile(idx, n); //读取索引数组idx
    printf("输入学号:");
    scanf("%d", &no);
    i = SearchNum(idx, n, no); //在idx中查找
    if (i == -1)
        printf("  提示:学号%d不存在\n", no);
    else
    {
        fseek(mfile, (i - 1) * sizeof(StudType), SEEK_SET); //由记录号直接跳到主文件中对应的记录
        fread(&st, sizeof(StudType), 1, mfile);
        printf("%5d%10s%6d%5s%5d%5d%5d\n", st.no, st.name, st.age, st.sex, st.deg1, st.deg2, st.deg3);
    }
    fclose(mfile);
}
void WriteFile(StudType st[], int n) //将st数组中的n个学生记录写入stud.dat文件中
{
    int i;
    FILE *fp;
    if ((fp = fopen("stud.dat", "wb")) == NULL)
    {
        printf("\t提示:不能创建stud.dat文件\n");
        return;
    }
    for (i = 0; i < n; i++)
        fwrite(&st[i], 1, sizeof(StudType), fp);
    fclose(fp);
    printf("  提示:文件stud.dat创建完毕\n");
}
int main()
{
    system("chcp 65001&cls"); //更改外部控制台编码为utf-8并清屏
    int n = 8, sel;           //n为实际学生人数
    StudType st[] = {{1, "陈华", 20, "男", 78, 90, 84},
                     {5, "张明", 21, "男", 78, 68, 92},
                     {8, "王英", 20, "女", 86, 81, 86},
                     {3, "刘丽", 21, "女", 78, 92, 88},
                     {2, "许可", 20, "男", 80, 83, 78},
                     {4, "陈军", 20, "男", 78, 88, 82},
                     {7, "马胜", 21, "男", 56, 67, 75},
                     {6, "曾强", 20, "男", 78, 89, 82}};
    printf("建立主文件\n");
    WriteFile(st, n); //建立主文件
    do
    {
        printf("1:输出主文件 2:建索引文件 3:输出索引文件 4:按学号查找 0:退出:");
        scanf("%d", &sel);
        switch (sel)
        {
        case 1:
            OutputMainFile();
            break;
        case 2:
            CreatIdxFile();
            break;
        case 3:
            OutputIdxFile();
            break;
        case 4:
            FindStudent();
            break;
        }
    } while (sel != 0);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

叶涟风不息

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

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

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

打赏作者

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

抵扣说明:

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

余额充值