数据结构中树、图、排序、查找源代码复现(参考)

数据结构中树、图、排序、查找代码参考

写在前面

头文件定义

#include <stdio.h>
#include <malloc.h>
#define OK 1
#define ERROR 0
typedef int Status;
typedef char TElemType;

一、树

1.1 结构体定义

typedef struct BiTNode
{
    TElemType data;
    //结点结构
    //数据域
    struct BiTNode *lchild,*rchild; //左孩子域和右孩子域
}BiTNode, *BiTree;

1.2 一些操作的实现

(1)由先根遍历序列(‘#’号表空)生成二叉树 CreateBiTree

Status CreateBiTree(BiTree &T)
{
// 由标明空子树的完整先根遍历序列建立一棵二叉树
    char ch;
    scanf("%c",&ch);
    if(ch=='#')
        T=NULL;     //"#"字符表示空树
    else
    {
        T=(BiTree)malloc(sizeof(BiTNode));
        T->data=ch; //生成根结点
        CreateBiTree(T->lchild); //构造左子树CreateBiTree(T->rchild);
        CreateBiTree(T->rchild);  //构造右子树
    }
    return OK;
}

(2)遍历递归算法 Traverse

void PreRootTraverse(BiTree T) //先根遍历二叉树 T 的递归算法
{
    if(T)
    {
        printf("%c",T->data); //访问根结点
        PreRootTraverse(T->lchild); //先根遍历左子树
        PreRootTraverse(T->rchild); //先根遍历右子树
    }
}

void InRootTraverse(BiTree T)
//中根遍历二叉树 T 的递归算法
{
    if(T)
    {
        InRootTraverse(T->lchild);   //中根遍历左子树
        printf("%c",T->data);        //访问根结点
       InRootTraverse(T->rchild);    //中根遍历右子树
    }
}

void PostRootTraverse(BiTree T)
//后根遍历二叉树 T 的递归算法
{
    if(T)
    {
        PostRootTraverse(T->lchild); //后根遍历左子树
        PostRootTraverse(T->rchild); //后根遍历右子树
        printf("%c",T->data); //访问根结点
    }
}

(3)由先序序列与中序序列生成一颗树PICreateBiTree


BiTree PICreateBiTree(char PreOrder[],char InOrder[],int PreIndex,int InIndex,int count)
//已知一棵二叉树的先根遍历和中根遍历序列,建立这棵二叉树
{
    BiTree T;
    if(count>0) //先根和中根非空,count 表示二叉树中结点数
    {
        char r=PreOrder[PreIndex]; //取先根遍历序列中的第一个元素
        int i=0;
        for(;i<count;i++) //寻找根结点在中根遍历序列中的位置
        {
            if(r==InOrder[i+InIndex])
            break;
        }
        T=(BiTree)malloc(sizeof(BiTNode));
        T->data=r;  //根结点r赋值
        T->lchild=PICreateBiTree(PreOrder,InOrder,PreIndex+1,InIndex,i);
        //i是中根遍历查找到的位置,T的左子树的元素序列是根节点左子树中根遍历序列,对应先序下标+1,中序不变,左子树节点数是i
        T->rchild=PICreateBiTree(PreOrder,InOrder,PreIndex+i+1,InIndex+i+1,count-i-1);
        //T的右子树序列是根节点右子树中跟遍历序列,先序下标 +i+1,中序+i+1,右子树节点树是N-(i+1)
    }
    else
        T=NULL;
    return T;
}

这里说一下关键点:根节点是通过先序序列访问,左子树,右子树通过中序序列中的根节点前后位置来确定的。
读者可以自行想一下中序和后续如何确定一颗二叉树
请注意,只有先序和中序遍历是无法确定一颗二叉树的。

(4)通过遍历可以实现的操作(以先根遍历为例)

1.复制一棵树T2 CopyTree
int CopyTree(BiTree T1,BiTree &T2)
//复制操作
//已知一棵二叉树 T1,T2 是由 T1 复制而得
{
    if(T1)
    {
        //为根结点 T2 分配空间
        T2 = (BiTree )malloc(sizeof(BiTNode));
        if (!T2)
        //空间分配失败
            return 0;
        T2->data=T1->data;
        //根结点 T2 的数据域值与根结点 T1 相等
        CopyTree(T1->lchild,T2->lchild);
        //复制左子树
        CopyTree(T1->rchild,T2->rchild);
        //复制右子树
    }
    else
        T2=NULL;
    return 1;
}
2.判断两颗树是否相等 PreCompare
int PreCompare(BiTree T1, BiTree T2)
//比较操作
//用先根遍历方法判断两棵二叉树是否相等
{
    if (!T1&&!T2)
        return 1;
    if (T1&&T2)
        if (T1->data==T2->data)
            if (PreCompare(T1->lchild,T2->lchild))
                if(PreCompare(T1->rchild,T2->rchild))
        return 1;
    return 0;
}
3.二叉树深度Depth
int depth(BiTree T)
//采用后根遍历对二叉树遍历,遍历过程中求得二叉树的深度
{
    int depthLeft,depthRight,depthval;
    if(T!=NULL)
    {
        depthLeft=Depth(T->lchild);
        depthRight=Depth(T->rchild);
        depthval=1+(depthLeft>depthRight?depthLeft:depthRight);
    }
    else
    {
        depthval=0;
    }
    return depthval;
}
4.统计(叶子)结点个数
void CountLeaf(BiTree T,int &num)
{
    if(T!=NULL)
    {
        if(!T->lchild&&!T->rchild){ //满足叶子节点度为0的条件
            num++;
        }
        CountLeaf(T->lchild,num);   //查找左子树的满足条件的节点
        CountLeaf(T->rchild,num);   //查找右子树满足条件节点
    }
}

二、图

2.1 结构体构造

2.1.1 邻接矩阵(注意图和网的区别)

const int maxn=105;
int adj[maxn][maxn]={0};    //定义邻接矩阵

2.1.2 邻接表

//边
typedef struct arcnode
{
  int adjvex;              //邻接顶点的位置序号值
  struct arcnode *nextarc; //指向下一条边的指针
} arcnode;                 //边的结点类型

//顶点
typedef struct vexnode
{
  arcnode *firstarc; //指向与该顶点相关联的第一条边的指针
  int tag;           //顶点的访问标志
} vexnode;           //顶点类型

typedef struct
{
  vexnode adjlist[MAX_VERTEX_NUM]; //存储顶点信息的数组
  int vexnum, arcnum;              //顶点数和边数
} Agraph;                          //用邻接表表示的图类型

2.1.3 前向星

struct Edge
{
    int to, w, next; //终点,边权,同起点的上一条边的编号
} edge[maxn];        //边集
int head[maxn];      // head[i],表示以i为起点的第一条边在边集数组的位置(编号)

2.2 一些操作(参考)

关键在于应用,这里仅给出思路模板。

(1)DFS搜索

void dfs()//参数用来表示状态
{
    if(到达终点状态)
    {
        ...//根据需求添加
        return;
    }
    if(越界或者是不合法状态)
        return;
    if(特殊状态)//剪枝,去除一些不需要访问的场景,不一定i俺家
        return ;
    for(扩展方式)
    {
        if(扩展方式所达到状态合法)
        {
            修改操作;//根据题意来添加
            标记;
            dfs();
            (还原标记);
            //是否还原标记根据题意
            //如果加上(还原标记)就是 回溯法
        }

    }
}

(2)BFS搜索

/**
 * 返回合适的检索数据
 */
int BFS(Node root, Node target)
{
    Queue<Node> queue;  //创建队列
    int step = 0;       // 当前队列的步骤点
    // initialize
    add root to queue;
    // BFS
    while (queue is not empty)
    {
        step = step + 1;
        //步数逐渐增加
        int size = queue.size();
        for (int i = 0; i < size; ++i)
        {
            Node cur = the first node in queue;
            if cur is target
                return step - 1;
            for (Node next : the neighbors of cur)
            {//这里常用一个二维方向数组实现
                add next to queue;
            }
            remove the first node from queue;
        }
    }
    return -1;          //出错返回值
}

(3)Prim算法

#include <stdio.h>
#include <stdlib.h>
#define n 20
#define MaxNum 10000  /*定义一个最大整数*/

/*定义邻接矩阵类型*/
typedef int adjmatrix[n + 1][n + 1];
typedef struct {
    int fromvex, tovex;                 //生成树的起点和终点
    int weight;                         //边的权重
} Edge;
typedef Edge *EdgeNode;                 //定义生成树的别名
int arcnum;     /*边的个数*/

/*建立图的邻接矩阵*/
void CreatMatrix(adjmatrix GA) {
    int i, j, k, e;
    printf("=============================\n");
    printf("图中有%d个顶点\n", n);
    for(i=1; i<=n; i++) {
        for(j=1; j<=n; j++) {
            if(i==j) {
                GA[i][j]=0;         /*对角线的值置为0*/
            } else {
                GA[i][j]=MaxNum;    /*其他位置的值置初始化为一个最大整数*/
            }
        }
    }
    printf("请输入边的个数:\n");
    scanf("%d", &arcnum);
    printf("请输入边的信息,依照起点,终点,权值的形式输入:\n");
    for(k=1; k<=arcnum; k++) {
        scanf("%d,%d,%d",&i,&j,&e);  /*读入边的信息*/
        GA[i][j]=e;
        GA[j][i]=e;
    }
}

/*初始化图的边集数组*/
void InitEdge(EdgeNode GE,int m) {
    int i;
    for(i=1; i<=m; i++) {
        GE[i].weight=0;
    }
}

/*依据图的邻接矩阵生成图的边集数组*/
void GetEdgeSet(adjmatrix GA,EdgeNode GE) {
    int i, j, k = 1;
    for(i=1; i<=n; i++) {
        for(j=i+1; j<=n; j++) {
            if(GA[i][j] !=0 && GA[i][j] != MaxNum) {
                GE[k].fromvex = i;
                GE[k].tovex = j;
                GE[k].weight = GA[i][j];
                k++;
            }
        }
    }
}

/*按升序排列图的边集数组*/
void SortEdge(EdgeNode GE,int m) {
    int i,j,k;
    Edge temp;
    for(i=1; i<m; i++) {
        k=i;
        for(j=i+1; j<=m; j++) {
            if(GE[k].weight > GE[j].weight) {
                k=j;
            }
        }
        if(k!=i) {
            temp = GE[i];
            GE[i]=GE[k];
            GE[k]=temp;
        }
    }
}

/*利用普里姆算法从初始点v出发求邻接矩阵表示的图的最小生成树*/
void Prim(adjmatrix GA,EdgeNode T) {
    int i,j,k,min,u,m,w;
    Edge temp;
    /*给T赋初值。相应为v1依次到其余各顶点的边*/
    k=1;
    for(i=1; i<=n; i++) {
        if(i!=1) {
            T[k].fromvex=1;
            T[k].tovex=i;
            T[k].weight=GA[1][i];
            k++;
        }
    }
    /*进行n-1次循环,每次求出最小生成树中的第k条边*/
    for(k=1; k<n; k++) {
        min=MaxNum;
        m=k;
        for(j=k; j<n; j++) {
            if(T[j].weight<min) {
                min=T[j].weight;
                m=j;
            }
        }
        /*把最短边对调到k-1下标位置*/ 可用swap替换
        temp=T[k];
        T[k]=T[m];
        T[m]=temp;
        /*把新增加最小生成树T中的顶点序号赋给j*/
        j=T[k].tovex;
        /*改动有关边,使T中到T外的每个顶点保持一条到眼下为止最短的边*/
        for(i=k+1; i<n; i++) {
            u=T[i].tovex;
            w=GA[j][u];
            if(w<T[i].weight) {
                T[i].weight=w;
                T[i].fromvex=j;
            }
        }
    }
}

/*输出边集数组的每条边*/
void OutEdge(EdgeNode GE,int e) {
    int i;
    printf("依照起点,终点。权值的形式输出的最小生成树为:\n");
    for(i=1; i<=e; i++) {
        printf("%d,%d,%d\n",GE[i].fromvex,GE[i].tovex,GE[i].weight);
    }
    printf("=============================\n");
}

int main() {
    adjmatrix GA;
    Edge GE[n*(n-1)/2], T[n];
    CreatMatrix(GA);
    InitEdge(GE,arcnum);
    GetEdgeSet(GA,GE);
    SortEdge(GE,arcnum);
    Prim(GA,T);
    printf("\n");
    OutEdge(T,n-1);
    return 0;
}

(4)Kruskal算法

#include<stdio.h>

#define MAXEDGE 100
#define MAXVERTEX 100
typedef struct Edge {
    int begin;//边的起点
    int end;  //边的终点
    int wight;//边的权值
} Edge;

typedef struct Graph {
    char vertex[MAXVERTEX];//顶点
    Edge edges[MAXEDGE];//边
    int numvertex,numedges;//顶点和边的个数
} MGraph;

void CreateGraph(MGraph* G) {
    printf("请输入顶点和边的个数:\n");
    scanf("%d%d", &G->numvertex, &G->numedges);
    printf("请输入顶点:\n");
    getchar();//利用该函数除去上一系我们在输入结束时按得回车符
    for (int i = 0; i < G->numvertex; i++) {
        scanf("%c", &G->vertex[i]);
    }
    printf("按权值从小到大输入边(vi,vj)对应的起点和终点的下标,begin,end以及权值wight:\n");
    for (int k = 0; k < G->numedges; k++) {
        Edge e;
        scanf("%d%d%d", &e.begin, &e.end, &e.wight);
        G->edges[k] = e;
    }
}

int Find(int *parent, int f) {
    while (parent[f]>0) {
        f = parent[f];
    }
    return f;
}

//最小生成树,克鲁斯卡尔算法
void Kruskal(MGraph *G) {

    int parent[MAXVERTEX];//存放最小生成树的顶点
    for (int i = 0; i < G->numvertex; i++) {
        parent[i] = 0;
    }
    int m, n;
    for (int i = 0; i < G->numedges; i++) {
        n = Find(parent, G->edges[i].begin);
        m = Find(parent, G->edges[i].end);
        if (n != m) { //m=n说明有环
            parent[n] = m;
            printf("(%d,%d) %d\t", G->edges[i].begin, G->edges[i].end, G->edges[i].wight);//打印边和权值
        }
    }
}

int main() {
    MGraph G;
    CreateGraph(&G);
    Kruskal(&G);

    return 0;
}

三、排序

3.1插入排序

void Sort_Insert(SqList &L)
//带监视哨的直接插入排序算法
{
    int i, j;
    for (i = 2; i <= L.length; ++i)
        if (L.r[i].key < L.r[i - 1].key) //将L.r[i]插入它前面的有序子表
        {
            L.r[0] = L.r[i];     //将待插入的第i条记录暂存在r[0]中,同时r[0]为监视哨
            L.r[i] = L.r[i - 1]; // 将前面的较大者L.r[i-1]后移
            for (j = i - 2; L.r[0].key < L.r[j].key; --j)
                L.r[j + 1] = L.r[j]; //后移
            L.r[j + 1] = L.r[0];     // 将L.r[i]插入第j+1个位置
        }                            // if
}

3.2冒泡选择排序(交换)

void Sort_Bubble(SqList &L)
//对顺序表L进行冒泡排序
{
    int i, j, change;
    RedType temp;
    change = TRUE;                           //设置交换标志变量,初值为真
    for (i = L.length; i > 1 && change; --i) //控制做n-1趟排序
    {
        change = FALSE; //每趟排序开始时设置交换标志变量值为假
        for (j = 1; j < i; ++j)
            if (L.r[j].key > L.r[j + 1].key)
            {
                temp = L.r[j];
                L.r[j] = L.r[j + 1];
                L.r[j + 1] = temp;
                change = TRUE;
            } // if
    }         // for i
}
void Sort_Select(SqList &L)
//对表L进行直接选择排序
{
    for (int i = 1; i < L.length; ++i) //控制n-1趟排
    {
        int min = i; //假设无序子表中的第一条记录的关键字最小
        for (int j = i + 1; j <= L.length; ++j)
            if (L.r[j].key < L.r[min].key)
                min = j;
        if (min != i) //如果最小关键字记录不在无序子表的第一个位置,则交换
        {
            RedType temp = L.r[i];
            L.r[i] = L.r[min];
            L.r[min] = temp;
        } // if
    }     // for i
}

3.3希尔排序 Sort_Shell

void Sort_Shell(SqList &L, int dk)
//对表L做一趟希尔排序,增量为dk
{
    int i, j;
    for (i = 1 + dk; i <= L.length; i++)
        if (L.r[i].key < L.r[i - dk].key) //将 L.r[i]插入有序增量子表
        {
            L.r[0] = L.r[i]; //将待插入的第i个记录暂存在r[0]中,同时r[0]为监视哨
            L.r[i] = L.r[i - dk];
            for (j = i - 2 * dk; j > 0 && L.r[0].key < L.r[j].key; j -= dk)
                L.r[j + dk] = L.r[j]; // 将前面的较大者L.r[j+dk]后移
            L.r[j + dk] = L.r[0];     // 将L.r[i]插入第j+dk个位置
        }
}
void Sort_Shell(SqList &L, int dlta[], int t)
// 按照增量dlta[0..t-1]对L做希尔排序
{
    for (int k = 0; k < t; ++k)
        Sort_Shell(L, dlta[k]); //完成一趟增量为dlta[k]的希尔排序
}

3.4快速排序Partition

int Partition(SqList &L, int low, int high)
//对L中的子表L.r[low..high]做一趟快速排序
{
    L.r[0] = L.r[low];                //将无序区低下标的记录设置为枢轴,并暂存在r[0]中
    KeyType privotkey = L.r[low].key; //将枢轴记录的关键字暂存在变量pivotkey中
    while (low < high)                // 当low==high时,结束本趟排序
    {
        while (low < high && L.r[high].key >= privotkey) //向前搜索
            --high;
        if (low < high)
            L.r[low++] = L.r[high];                     //将比枢轴小的记录移至低端low的位置 ,然后low后移一位
        while (low < high && L.r[low].key <= privotkey) //向后搜索
            ++low;
        if (low < high)
            L.r[high--] = L.r[low]; //将比枢轴小的记录移至低端low的位置  ,然后high前移一位
    }
        L.r[low] = L.r[0];          //枢轴记录移至最后位置
        return low;                 //返回枢轴所在的位置
    }                               //算法7-5结束
    void Q_Sort(SqList & L, int low, int high)
    //对表r[low..high]采用递归形式的快速排序算法
    {
        if (low < high) //如果无序表长大于1
        {
            int pivotloc = Partition(L, low, high); //完成一次划分,确定枢轴位置
            Q_Sort(L, low, pivotloc - 1);           //递归调用,完成左子表的排序
            Q_Sort(L, pivotloc + 1, high);          //递归调用,完成右子表的排序
        }
    } //算法7-6结束
    void Sort_Quick(SqList & L)
    {
        Q_Sort(L, 1, L.length);
    } //算法7-7结束

(5) 归并排序Merge

void Merge(RedType SR[], RedType TR[], int i, int m, int n)
//将两个相邻有序表SR[i .. m] 与SR[m+1.. n]归并为有序表TR[i .. n]
{
    int j = m + 1, k = i;
    while (i <= m && j <= n) // 将SR中两个相邻有就有序子表由小到大并入TR中
    {
        if (SR[i].key <= SR[j].key)
            TR[k++] = SR[i++];
        else
            TR[k++] = SR[j++];
    }
    while (i <= m) //将前一有序子表的剩余部分复制到TR
        TR[k++] = SR[i++];
    while (j <= n) //将后一有序子表的剩余部分复制到TR
        TR[k++] = SR[j++];

} //算法7-10

void M_Sort(RedType SR[], RedType TR1[], int s, int t)
// 将SR[s..t]归并排序为TR[s..t]
{
    RedType TR2[MAXSIZE + 1];
    if (s == t)
        TR1[s] = SR[s];
    else
    {                              //待排序的记录序列只含一条记录
        int m = (s + t) / 2;       // 以m为分界点,将无序表分成前、后两部分
        M_Sort(SR, TR2, s, m);     //对前部分递归归并为有序子表TR2[s..m]
        M_Sort(SR, TR2, m + 1, t); //对后部分递归归并为有序子表TR2[m+1..t]
        Merge(TR2, TR1, s, m, t);  //将TR2[s..m]与TR2[s..m]归并成有序表TR1[s..t]
    }
} //算法7-11

四、查找

4.1 结构体构造

typedef struct
{
    KeyType key;        //关键字域
    InfoType otherinfo; // 其它数据项
} ElemType;             //记录类型
typedef struct
{
    ElemType *elem; //记录存储空间基地址,构造表时按实际长度分配,0号单元留空
    int length;     //表长度
} SSTable;          //静态查找表类型

4.2 一些操作

(1)顺序查找Search_Seq

int Search_Seq(SSTable ST, KeyType key) //顺序查找函数
                                        // 采用带监视哨的顺序查找方法在查找表的n个记录中查找出关键字值为key的记录
//若查找成功,则返回其下标位置;否则,返回0
{
    int i;
    ST.elem[0].key = key; //"哨兵"
    for (i = ST.length; ST.elem[i].key != key; i--)
        ;     //从后往前进行查找
    return i; //若找到,则返回下标位置;若没有找到,则返回0
} // Search_Seq

(2)二分查找 Search_Bin

int Search_Bin(SSTable ST, KeyType key) //二分查找函数
// 采用二分查找方法在有序表的n个记录中查找出关键字值为key的记录
//若查找成功,则返回其下标位置;否则,返回0
{
    int low = 1;          //查找范围的下界
    int high = ST.length; //查找范围的上界
    while (low <= high)
    {
        int mid = (low + high) / 2; //中间位置,当前比较的记录位置
        if (key == ST.elem[mid].key)
            return mid; //查找成功,返回下标位置
        else if (key < ST.elem[mid].key)
            high = mid - 1; //查找范围缩小到前半段
        else
            low = mid + 1; //查找范围缩小到后半段
    }
    return 0;
} // Search_Bin

(3)分块查找(索引)

源代码
#include<stdio.h>
#include<malloc.h>
#define MAXSIZE 100
#define OK 1
#define OVERFLOW -1

typedef int Status;
typedef int KeyType; //整型关键字类型
typedef struct BNode
{
    KeyType key;        //存储块中记录的关键字值
    struct BNode *next; //指向块链中下一记录结点的指针
} BNode;                //块链中的结点类型
typedef struct SNode
{
    KeyType Maxkey; //存储各块记录中的最大关键字值
    BNode *head;    //块链的头指针
} SNode;            //索引表中元素的类型
typedef struct
{
    SNode r[MAXSIZE];           //用于存放索引表中快元素的数组
    int length;                 //用于存放索引表中快的个数
} STable;                       //索引查找表的结构类型

Status Creat_STable(STable &ST) //构造一个空的索引表
{
    for (int i = 1; i <= MAXSIZE; i++)
        ST.r[i].head = NULL;
    ST.length = 0;
    return OK;
} // Creat_SSTable

int FindBlock(STable ST, KeyType key)
//用二分查找法在索引查找表ST的索引表中确定关键字值为key的待查找记录所在的块号,
//函数并返回值其块号值
{
    int low, high, mid;
    low = 1;
    high = ST.length;
    while (low <= high)
    {
        mid = (low + high) / 2;
        if (key == ST.r[mid].Maxkey)
            return mid;
        else if (key < ST.r[mid].Maxkey)
            high = mid - 1;
        else
            low = mid + 1;
    }
    return high + 1;
} // FindBlock

void FindRec(STable ST, KeyType key, int &Bno, int &pos)
//用顺序查找法在索引查找表的块链中确定关键字值为key的待查找记录的存储位置
//如果查找成功,记录所在的快号和在快中的位序号分别为Bno和pos,否则都为0
{
    BNode *p;
    int i = 1;
    Bno = FindBlock(ST, key);  //调用函数,确定待查记录所在块号
    p = ST.r[Bno].head;        //取到待查记录所在块链的头指针
    while (p && p->key != key) //顺着链指针依次查找
    {
        p = p->next;
        i++;
    }
    if (p)
        pos = i; //查找成功,在快中的位置为i
    else
        pos = 0; //查找不成功,在快中的位置为0
}

int main()
{
    char ch;
    int Bno=0,pos=0,n;
    STable ST;
    KeyType key;
    Creat_STable(ST);
    printf("兄弟,索引表需要多少长?\n");
    scanf("%d",&ST.length);
    getchar();
    for(int i=1;i<=ST.length;i++){
        printf("现在输入第%d列的数据!(注意大于前一列的最大值)\n",i);
        ST.r[i].Maxkey=-999999;
        ST.r[i].head=(BNode*)malloc(sizeof(BNode));
        BNode *p=ST.r[i].head;
        p->key=ST.r[i].Maxkey;
        do{
            p->next=(BNode*)malloc(sizeof(BNode));
            scanf("%d",&p->next->key);
            p=p->next;
            ST.r[i].Maxkey=p->key>ST.r[i].Maxkey?p->key:ST.r[i].Maxkey;
        }while((ch=getchar())!='\n');
    }
    //debug
    printf("可以,你输完了所有数据。现在的情况是:\n");
    for(int i=0;i<ST.length;i++){
        printf("第%d个索引表的最大长度:%d\n",i+1,ST.r[i+1].Maxkey);
    }
    while(true){
        Bno=0;pos=0;
        printf("请输入你想查找的关键字(输入-1以结束)\n");
        scanf("%d",&key);
        if(key==-1){
            printf("bye!\n");
            break;
        }
        FindRec(ST,key,Bno,pos);
        if(Bno==0||pos==0){
            printf("查找失败!!\n");
        }
        else{
            printf("他在索引表的第%d块的第%d个位置,下标为%d\n",Bno,pos,pos-1);
        }
    }

    return 0;
}
posted @ 2022-01-01 13:50  yuezi2048  阅读(34)  评论(0编辑  收藏  举报