学生管理系统(顺序表的简单实现)

顺序表

优点:

  • 功能上类似于数组操作简单
  • 能够实现随机访问,进行查询和修改效率高

缺点:

  • 存储数据有上限
  • 对于插入和删除效率低,因为需要移动大量元素
  • 空间利用率低

结构体创建

typedef struct
{
    char name[20];
    short age;
    char sex;
} Stu_t;

typedef struct
{
    unsigned index;
    Stu_t list[50];
} Sqlist_t;

创建顺序表

sqlist_t *create_list(void)
{
    //申请表空间
    Sqlist_t *L = malloc(sizeof(sqlist_t));
    if(NULL == L)
    {
        printf("malloc memory failed!\n");
        return NULL;
    }
    
    //初始化表空间
    memset(L, 0, sizeof(Sqlist_t));
    L->index = 0;
    
    //返回表空间首地址
    return L;
}

在顺序表中任意位置插入数据

/*
功能:在顺序表的任意位置插入数据
参数:L 顺序表首地址
	 pos 要插入的位置(unsigned int)
	 value 要插入的数据
返回值: 成功返回 0
	    失败返回-1
*/
int insert_data(Sqlist_t *L, int pos, Stu_t value)
{
    //健壮性判断
    if(NULL == L)
    {
        printf("Malloc memory failed!\n");
        return -1;
    }
    //pos传入位置判断
    if(pos > L->index || pos < 0)
    {
        printf("Pos error!\n");
        return -1;
    }
    //表内空间判断
    if(NULL == L->index)
    {
        printf("List is max!\n");
        return -1;
    }
    
    //插入操作
    Sqlist_t *S = L;//用一个新的指针变量来操作,避免误操作
    int i = 0;
    for(i = S->index; i > pos; i--)
    {
        S->list[i] = S->list[i - 1];
    }
    
    S->list[pos] = value;
    
    //更新表记录标识
    S->index++;
}

插入数据算法思路

  1. 在向顺序表中插入数据时,要考虑表参数的合法性,位置参数的合法性,和表的使用状况
    1. 表参数的合法性判断比较简单(不为NULL)
    2. 位置参数合法性判断为 位置参数不可以小于0且不能大于index
    3. 判断表参数合法性主要是为了维护表的逻辑结构
    4. 表的使用情况,表满不可再进行数据插入操作
  2. 当使用者传输的所有参数(表的首地址、位置)都合法的情况下且表未满才可以进行插入操作
    1. 先移动传入位置值到index标识范围内的数据(向后移动),主要目的是不破坏原有数据,否则将失去表的意义,移动算法如下:
13456
012345
posindex
value = 2;
index = 6;
pos = 1;

for(i = index; i > pos; i--)
{
    i = i -1;
}
1value3456
012345
  • i变量定位到表使用标识的位置i = index

  • 移动结束条件为i移动到传入的位置for(i = index; i > pos; i--)

  • 然后将i前一个位置( i - 1 )的数据向后移动一个位置( i ) i = i - 1

  • 循环结束时posindex位置的数据整体向后移动了一个位置(此时pos位置上的数据与pos + 1的数据一致)

    3.将数据整体移动后在进行数据插入(插入到pos对应的位置上即可)S->list[pos] = value;

遍历顺序表

int show_list(Sqlist_t *L)
{
    //健壮性判断
    if(NULL == L)
    {
        printf("malloc memory failed!\n");
        return -1;
    }
    if(NULL == L->index)
    {
        printf("list is NULL!\n");
        return -1;
    }
    
    int i = 0;
    for(i = 0; i < L->index; i++)
    {
        printf("name:%s, age:%hd, sex:%c\n", L->list[i].name, L->list[i].age, L->list[i].sex);
    }
}

释放表空间

int free_list(Sqlist_t **L)
{
    //健壮性判断
    if(NULL == *L || NULL == L)
    {
        prinrf("传入的表参数非法\n");
        return -1;
    }
    
    free(*L);
    *L = NULL;
    
    return 0;
}

删除表中任意位置数据

int delete_data(Sqlist_t *L, int pos)
{
    //健壮性判断
    if(NULL == L)
    {
        printf("传入的表参数非法\n");
        return -1;
    }
    
    if(pos < 0 || pos >= L->index)
    {
        printf("传入位置非法\n");
        return -1;
    }
    
    if(0 == L->index)
    {
        printf("表为空表,无数据可删\n");
        return -1;
    }
    
    //删除对应位置参数
    int i = 0;
    
    //将pos位置后的数据整体向前移动一个位置,覆盖pos当前位置的数据,以达到删除的效果
    for(i = pos; i < L->index - 1; i++)
    {
        L->list[i] = L->list[i + 1];
    }
    
    //更新表记录
    L->index--;
    
    return 0;
}

判断表是否为空

int empty_list(Sqlist_t *L)
{
    if(NULL == L)
    {
        printf("传入的表参数非法\n");
        return -1;
    }
    return 0 == L->index ? 0 : -1;
}

判断表是否为满

int empty_list(Sqlist_t *L)
{
    if(NULL == L)
    {
        printf("传入的表参数非法\n");
        return -1;
    }
    return N == L->index ? 0 : -1;
}

根据学生姓名去重

int Remove_Dup(Sqlist_t *L)
{
    if(NULL == L)
    {
        printf("传入的表参数非法\n");
        return -1;
    }
    
    if(0 == empty_list(L) || 1 == L->index)
    {
        printf("表为空表 或 只有一个元素无需去重\n");
        return -1;
    }
    
    int i,j;
    
    for(i = 0; i < L->index - 1; i++)
    {
        for(j = i + 1; j < L->index; j++)
        {
            if(0 == strcmp(L->list[i].name,L->list[j].name))
            {
                delete_data(L,j);
                j--;//--是因为删除数据后,数据前移原本j位置的数据会被跳过
            }
        }
    }
}

根据学生年龄排序

int sort_age(Sqlist_t *L)
{
    if(NULL == L)
    {
        printf("传入的表参数非法\n");
        return -1;
    }
    
    if(0 == empty_list(L) || 1 == L->index)
    {
        printf("表为空表 或 只有一个元素无需排序\n");
        return -1;
    }
    
    int i, j;
    Stu_t temp;
    memset(&temp, 0, sizeof(temp));
    
    for(i = 0; i < L->index; i++)
    {
        for(j = i + 1; j < L->index; j++)
        {
            if(L->list[i].age > L->list[j].age)
            {
                temp = L->list[i];
                L->list[i] = L->list[j];
                L->list[j] = temp;
            }
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值