线性表
数据结构 - 线性表
线性表就是一个队列
类似于node.js的队列,但是感觉很像,也不清楚是不是
直接上题,♪(∇*)
使用线性表来储存一组学生信息,并支持常规的增删查改
需要以下的几个子函数
- 建立顺序表
- 求线性表的长度
- 输出线性表
- 在线性表的指定位置插入一个元素
- 根据键值查找指定的元素
- 获取指定位置的元素信息
- 删除指定位置的元素
- 释放线性表
 需要储存学生的信息有
- 学号
- 姓名
- 年龄
- 专业
- 入学年份
定义基本的数据类型
需要知道学生的学号,姓名,年龄,专业,入学年份,所以需要定义基本的数据类型
typedef struct {
    char num[20];
    char name[20];
    int age;
    char major;
    int registerYear;
}ElemType;
定义物理储存
定义线性表的物理储存方式
typedef struct {
    ElemType data[MAXCOUNT];    // 定义数据
    int len;    // 定义长度
};
以上完成了线性表的物理储存方式
定义主函数实现功能
暂时不考虑输入和输出
int main() {
    int option;
    printf("学生管理系统进入成功\n");
    printf("************选项*******************\n");
    printf("1 建立线性表\n");
    printf("2 求线性表的长度\n");
    printf("3 输出详细表\n");
    printf("4 在线性表的位置插入一个元素\n");
    printf("5 根据键值对查找指定的元素\n");
    printf("6 获取指定位置的元素的信息\n");
    printf("7 删除指定位置的元素\n");
    printf("8 释放线性表\n");
    printf("9 退出系统\n");
    printf("**************end!*********************\n");
    
    while(1) {
        printf("请输入选项\n");
        scanf("%d", &option);
        switch(option) {
            case 1:
                createList();
                break;
            case 2:
                listLength();
                break;
            case 3:
                printfList();
                break;
            case 4:
                insterList();
                break;
            case 5:
                selectList();
                break;
            case 6:
                infoList();
                break;
            case 7:
                deleteList();
                break;
            case 8:
                freeList();
                break;
            case 9:
                return 0;
            default:
                printf("您输入的有错误,请重新输入");
                break;
        }
    }
    return 0;
}
下面实现分开的函数
建立线性表
思路:申请内存空间
/*
 * 建立线性表
*/
// in 传入空指针 out 线性表的首地址
int createList(SeqList *myLIst) {
    myList = (SeqList *)malloc(sizeof(SeqList));    // 申请一块储存空间
    if (myLIst == NULL) {
        return -1;   // 创建储存空间失败
    } else {
        return 1;   // 创建储存空间成功
    }
}
求线性表长度
// in 线性表 out 长度
int listLength(const SeqList *myList) {
    // 未创建线性表
    if (myList == NULL)
        return -1;
    // 创建线性表
    return myList -> len;
};
输出线性表
/*
 * 输出线性表
*/
// in 线性表 out 线性表的内容
int printfList(const SeqList *myList) {
    int i, len;
    // 判断是否为空指针
    if (myList == NULL)
        return -1;
    // 获取线性表长度
    len = myList -> len;
    if (len == 0) {
        printf ("您输入的线性表为空\n");
    }
    // 输出线性表
    for (i = 0; i < len; i++) {
        printf("输出第%d组数组\n", i + 1);
        printf("学号 = %s\n", myList->data[i].num);
        printf("年龄 = %d\n", myList ->data[i].age);
        printf("专业 = %s\n", myList ->data[i].major);
        printf("姓名 = %s\n", myList ->data[i].name);
        printf("入学年份 = %d\n", myList ->data[i].registerYear);
    }
    printf("线性表输出成功\n");
    return 1;
}
在线性表的指定位置插入
设计子函数中的主函数
/*
 * 在线性表的指定位置插入
*/
// in 线性表 out 结果
int insterList(SeqList *myList) {
    int tmp, col;
    ElemType *tmpList = NULL;
    // 判断传入地址是否为空
    if (myList == NULL) {
        return -1;
    }
    /*
     * 进行插入
     */
    // 获取用户输入
    tmp = inputList(&tmpList, &col);
    // 判断是否获取成功
    if (tmp == -1)
        return -1;
    // 进行插入操作
    // 调用函数,往后逐步移动
    tmp = moveList(myList, col, 1);    // 1代表向后移动  0 向前移动
    // 判断获取结果
    if (tmp == -1) {
        return -1;
    }
    // 将值插入
    myList->data[col-1] = *tmpList;
    // 维护长度
    (myList ->len)++;
    // 释放储存空间
    free(tmpList);
    // 设置空指针
    tmpList = NULL;
    return 1;
}
接着继续设计插入信息的子函数
// 获取用户输入要插入线性表的信息
// in 插入的信息 插入的位置 out 结果
int inputList(ElemType **tmpList, int *col) {
    // 申请储存的内存空间
    *tmpList = (ElemType *)malloc(sizeof(ElemType));
    if (*tmpList == NULL){
        printf("空间不足,无法申请\n");
        return -1;
    }
    // 获取用户的要插入的内容
    fflush(stdin);
    printf("请输入学号\n");
    gets(((*tmpList) ->num));
    fflush(stdin);
    printf("请输入姓名\n");
    gets((*tmpList) ->name);
    fflush(stdin);
    printf("请输入年龄\n");
    scanf("%d",&((*tmpList) ->age));
    fflush(stdin);
    printf("请输入主修专业\n");
    gets((*tmpList)->major);
    fflush(stdin);
    printf("请输入入学年份\n");
    scanf("%d", &((*tmpList)->registerYear));
    fflush(stdin);
    printf("请输入要插入的位置\n");
    scanf("%d", col);
    fflush(stdin);
    return 1;   // 获取用户输入的信息完成
}
接着设计移动元素的子函数,分为前移动和后移动
// 移动线性表函数
// 其中option中1往后移动,0往前移动 col 为要插入的位置,从1开始
int moveList(SeqList *myList, int col, int option) {
    int i;
    // 判断传入的线性表是否为空
    if (myList == NULL) {
        printf ("线性表为空\n");
        return -1;
    }
    // 判断线性表是否已满
    if (listLength(myList) >= MAXCOUNT) {
        printf("线性表已满,无法插入,请删除后插入\n");
        return -1;
    }
    // 判断col是否越界,导致线性表不连贯
    if ((col > listLength(myList) && col - listLength(myList) != 1 ) || col < 1) {
        printf("输入的插入位置错误,请确认后重新插入\n");
        return -1;
    }
   // 判断前移还是后移
   switch(option) {
        case 1:
            // 线性表往后移动
           // 移动线性表
           col--;
           for(i = listLength(myList); i >= col; i--) {
               myList ->data[i] = myList ->data[i-1];
           };
           break;
        case 0:
            // 线性表往前移动
            for(i = col; i < listLength(myList); i++) {
                myList ->data[i - 1] = myList ->data[i];
            }
            break;
       default:
           printf("输入的选型错误\n");
           return -1;
    }
    return 1;
}
根据键值查找线性表
// 根据键值查找线性表
int selectList(SeqList *myList) {
    if (myList == NULL) {
        return -1;
    }
    char key[20];
    int i;
    // 获取键值
    printf("请输入键值,即学号\n");
    gets(key);
    // 进行遍历操作
    for (i = 0; i< listLength(myList); i++) {
        if (strcmp(myList ->data[i].num, key) == 0) {
            break;
        }
    }
    return i;
}
获取指定位置的元素信息
// 获取指定位置的元素信息
int infoList(SeqList *myList) {
    int key;
    // 获取需要的索引值
    printf("请输入索引值\n");
    scanf("%d\n", &key);
    // 检查输入的key
    if (key > listLength(myList) || key < 0) {
        return -1;  // 输入的索引错误
    }
    // 输出值对应的学号
    printf("学号 = %s\n", myList ->data[key].num);
    return 1;
}
删除元素
// 删除元素
int deleteList(SeqList *myList) {
    char num[20];
    int tmp;
    // 检查myList是否为空
    if (myList == NULL) {
        return -1;
    }
    // 获取要删除的学号
    printf("请输入要删除的学号\n");
    fflush(stdin);
    gets(num);
    // 查找对应的索引值
    tmp = selectList(myList, num);
    if (tmp == -1) {
        return -1;
    }
    // 向前移动
    tmp = moveList(myList, tmp, 1);
    if (tmp == -1) {
        return -1;
    }
    return 1;
}
释放线性表
// 释放线性表
int DestroyList(SeqList *myList) {
    if (myList == NULL) {
        return -1;
    }
    free(myList);
    return 1;
}
总文件
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXCOUNT 50
// 定义要储存的线性表
typedef struct {
    char num[20];   // 定义学号
    char name[20];  // 定义姓名
    int age;    // 定义年龄
    char major[20]; // 定义专业
    int registerYear;   // 定义入学年份
}ElemType;
// 定义线性表的物理储存
typedef struct {
    ElemType data[MAXCOUNT];    // 定义数据
    int len;    // 定义长度
}SeqList;
int createList(SeqList **myList);
int listLength(const SeqList *myList);
int printfList(const SeqList *myList);
int inputList(ElemType **tmpList, int *col);
int moveList(SeqList *myList, int col, int option);
int selectList(SeqList *myList, char *key);
int infoList(SeqList *myList, int key);
int DestroyList(SeqList *myList);
int main() {
    // 定义一些变量
    int option, tmp;
    SeqList *myList; // 定义一个SeqList类型的空指针,用来储存线性表
    myList = NULL;
    char key[20];
    int num;
    // 输出选项
    printf("学生管理系统进入成功\n");
    printf("************选项*******************\n");
    printf("1 建立线性表\n");
    printf("2 求线性表的长度\n");
    printf("3 输出详细表\n");
    printf("4 在线性表的位置插入一个元素\n");
    printf("5 根据键值对查找指定的元素\n");
    printf("6 获取指定位置的元素的信息\n");
    printf("7 删除指定位置的元素\n");
    printf("8 释放线性表\n");
    printf("9 退出系统\n");
    printf("**************end!*********************\n");
    // 进行选项的输入
    // 进行基本逻辑的处理
    while(1) {
        printf("请输入选项\n");
        scanf("%d", &option);
        switch(option) {
            // 建立线性表
            case 1:
                tmp = createList(&myList);   // 捕获结果,并创建线性表
                // 输出结果
                if (tmp == 1) {
                    printf("建立线性表成功!\n");
                } else {
                    printf("建立线性表失败!\n");
                };
                break;
            // 查询线性表的长度
            case 2:
                tmp = listLength(myList);
                if (tmp == -1) {
                    printf("查询线性表长度失败,未指定线性表\n");
                } else {
                    printf("查询线性表的长度为%d\n", tmp);
                };
                break;
            // 输出线性表
            case 3:
                tmp = printfList(myList);
                if (tmp == -1)
                    printf("输出线性表失败,未指定线性表\n");
                else
                    printf("输出线性表如上\n");
                break;
             // 插入线性表
             case 4:
                tmp = insterList(myList);
                if (tmp == -1)
                    printf("插入线性表失败\n");
                else
                    printf("插入线性表成功\n");
                break;
            case 5:
                // 根据键值查找索引值
                printf("请输入键值,即学号\n");
                fflush(stdin);
                gets(key);
                fflush(stdin);
                tmp = selectList(myList, key);
                if (tmp == -1)
                    printf("查找错误\n");
                else if (tmp >= listLength(myList))
                    printf("未找到!");
                else
                    printf("索引值为 %d\n", tmp);
                break;
            case 6:
                // 根据索引值查找键值
                printf("请输入索引值\n");
                scanf("%d", &num);
                tmp = infoList(myList, num);
                if (tmp == -1) {
                    printf("查找失败\n");
                } else {
                    printf("输出的信息如上\n");
                }
                break;
            case 7:
                // 根据键值删除对应的数据
                tmp = deleteList(myList);
                if (tmp == -1)
                    printf("删除失败\n");
                else
                    printf("删除成功");
                break;
            case 8:
                tmp = DestroyList(myList);
                if (tmp == -1) {
                    printf("释放失败\n");
                } else {
                    printf("释放成功\n");
                }
                break;
            case 9:
                return 0;
            default:
                printf("您输入的有错误,请重新输入");
                break;
        }
    }
    return 0;
}
/*
 * 建立线性表
*/
// in 传入空指针 out 线性表的首地址
int createList(SeqList **myList) {
     *myList = (SeqList *)malloc(sizeof(SeqList));    // 申请一块储存空间
    if (*myList == NULL) {
        return -1;   // 创建储存空间失败
    } else {
        return 1;   // 创建储存空间成功
    }
}
/*
 * 求线性表长度,
*/
// in 线性表 out 长度
int listLength(const SeqList *myList) {
    // 未创建线性表
    if (myList == NULL)
        return -1;
    // 创建线性表
    return myList -> len;
};
/*
 * 输出线性表
*/
// in 线性表 out 线性表的内容
int printfList(const SeqList *myList) {
    int i, len;
    // 判断是否为空指针
    if (myList == NULL)
        return -1;
    // 获取线性表长度
    len = myList -> len;
    if (len == 0) {
        printf ("您输入的线性表为空\n");
        return 1;
    }
    // 输出线性表
    for (i = 0; i < len; i++) {
        printf("输出第%d组数组\n", i + 1);
        printf("学号 = %s\n", myList->data[i].num);
        printf("年龄 = %d\n", myList ->data[i].age);
        printf("专业 = %s\n", myList ->data[i].major);
        printf("姓名 = %s\n", myList ->data[i].name);
        printf("入学年份 = %d\n", myList ->data[i].registerYear);
    }
    printf("线性表输出成功\n");
    return 1;
}
/*
 * 在线性表的指定位置插入
*/
// in 线性表 out 结果
int insterList(SeqList *myList) {
    int tmp, col;
    ElemType *tmpList = NULL;
    // 判断传入地址是否为空
    if (myList == NULL) {
        return -1;
    }
    /*
     * 进行插入
     */
    // 获取用户输入
    tmp = inputList(&tmpList, &col);
    // 判断是否获取成功
    if (tmp == -1)
        return -1;
    // 进行插入操作
    // 调用函数,往后逐步移动
    tmp = moveList(myList, col, 1);    // 1代表向后移动  0 向前移动
    // 判断获取结果
    if (tmp == -1) {
        return -1;
    }
    // 将值插入
    myList->data[col-1] = *tmpList;
    // 维护长度
    (myList ->len)++;
    // 释放储存空间
    free(tmpList);
    // 设置空指针
    tmpList = NULL;
    return 1;
}
// 获取用户输入要插入线性表的信息
// in 插入的信息 插入的位置 out 结果
int inputList(ElemType **tmpList, int *col) {
    // 申请储存的内存空间
    *tmpList = (ElemType *)malloc(sizeof(ElemType));
    if (*tmpList == NULL){
        printf("空间不足,无法申请\n");
        return -1;
    }
    // 获取用户的要插入的内容
    fflush(stdin);
    printf("请输入学号\n");
    gets(((*tmpList) ->num));
    fflush(stdin);
    printf("请输入姓名\n");
    gets((*tmpList) ->name);
    fflush(stdin);
    printf("请输入年龄\n");
    scanf("%d",&((*tmpList) ->age));
    fflush(stdin);
    printf("请输入主修专业\n");
    gets((*tmpList)->major);
    fflush(stdin);
    printf("请输入入学年份\n");
    scanf("%d", &((*tmpList)->registerYear));
    fflush(stdin);
    printf("请输入要插入的位置\n");
    scanf("%d", col);
    fflush(stdin);
    return 1;   // 获取用户输入的信息完成
}
// 移动线性表函数
// 其中option中1往后移动,0往前移动 col 为要插入的位置,从1开始
int moveList(SeqList *myList, int col, int option) {
    int i;
    // 判断传入的线性表是否为空
    if (myList == NULL) {
        printf ("线性表为空\n");
        return -1;
    }
    // 判断线性表是否已满
    if (listLength(myList) >= MAXCOUNT) {
        printf("线性表已满,无法插入,请删除后插入\n");
        return -1;
    }
    // 判断col是否越界,导致线性表不连贯
    if ((col > listLength(myList) && col - listLength(myList) != 1 ) || col < 1) {
        printf("输入的插入位置错误,请确认后重新插入\n");
        return -1;
    }
   // 判断前移还是后移
   switch(option) {
        case 1:
            // 线性表往后移动
           // 移动线性表
           col--;
           for(i = listLength(myList); i >= col; i--) {
               myList ->data[i] = myList ->data[i-1];
           };
           break;
        case 0:
            // 线性表往前移动
            col--;
            for(i = col; i < listLength(myList); i++) {
                myList ->data[i] = myList ->data[i+1];
            }
            break;
       default:
           printf("输入的选型错误\n");
           return -1;
    }
    return 1;
}
// 根据键值查找线性表
int selectList(SeqList *myList, char * key) {
    if (myList == NULL) {
        return -1;
    }
    int i;
    // 进行遍历操作
    for (i = 0; i< listLength(myList); i++) {
        if (strcmp(myList ->data[i].num, key) == 0) {
            break;
        }
    }
    return i;
}
// 获取指定位置的元素信息
int infoList(SeqList *myList, int key) {
    if (myList == NULL) {
        return -1;
    }
    // 检查输入的key
    if (key > listLength(myList) || key < 0) {
        return -1;  // 输入的索引错误
    }
    // 输出值对应的学号
    printf("学号 = %s\n", myList ->data[key].num);
    return 1;
}
// 删除元素
int deleteList(SeqList *myList) {
    char num[20];
    int tmp;
    // 检查myList是否为空
    if (myList == NULL) {
        return -1;
    }
    // 获取要删除的学号
    printf("请输入要删除的学号\n");
    fflush(stdin);
    gets(num);
    // 查找对应的索引值
    tmp = selectList(myList, num);
    if (tmp == -1) {
        return -1;
    }
    // 向前移动
    tmp = moveList(myList, tmp, 1);
    if (tmp == -1) {
        return -1;
    }
    return 1;
}
// 释放线性表
int DestroyList(SeqList *myList) {
    if (myList == NULL) {
        return -1;
    }
    free(myList);
    return 1;
}
运行如下

源文件 https://gitlab.com/melovemingming/code/blob/practice/practice/C/2018/10/01/untitled/main.c
    在无知的道路上缓步前行
 
                    
                
 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号