C语言中的线性表演示代码

#include<stdio.h>
#include<stdlib.h>
 #include <string.h>

#define NofsNumber 10 //学号设置最长为10个字符
#define NofName 10 //名字设置最长为10个字符
typedef  int score_type; //分数的类型默认设置为unsigned char类型[0 , 255]

//线性表中每个节点的struct,包含 : 学号、名字、3科成绩加上一个平均成绩
typedef struct ElemType
{
    char sNumber[NofsNumber]; 
    char name[NofName]; 
    score_type scores[4];
}ElemType;

//线性表struct
typedef struct List {
   ElemType *list;  /*存线性表元素的动态存储空间的指针*/
   int len;         /*保存线性表当前长度*/
   int MaxSize;     /*能存储的线性表的最大长度*/
}List;

//下面的各个函数不一一注释了,直接翻阅PPT对照即可
void InitList( List *L, int max_size);
void ClearList(List *L);
int SizeList(List *);
void GetElem(List *, int pos);
void TraverseList(List *);//输出表中所有的值
int FindList(List *, ElemType *);
int InsertPosList(List*,int,ElemType);//在pos位置插入一个节点
void printInfo();
void printNode(ElemType *);//打印输出节点的值
void InsertNode(List *);//插入一个节点
void getNode(ElemType *);//输入节点的信息
void SortList(List *);//线性表的排序,很重要
void InsertInitialNodes(List *);//插入初始的信息,5个同学
void printGua(List *);//输出至少挂了一科的同学
void printBigerThanX(List *);//输出平均成绩大于x的同学
int isSmaller(ElemType *p1 , ElemType *p2);


int main()
{
    //定义一个线性表
    ElemType node;
    List mylist;
    mylist.len = 0;
    mylist.MaxSize = 0;
    mylist.list = NULL;
    InitList( &mylist, 4);
    printInfo();
    int p; 
    while(1)
    {
        printf("请输入指令 : ");
        char select;
        select = getchar();
        switch(select)
        {
            case 'c'://清空
                ClearList(&mylist);
                printf("线性表已经清空!\n");
                break;
            case 's':
                printf("线性表的长度是%d,容量是%d\n", mylist.len, mylist.MaxSize);
                break;
            case 'q'://退出
                if(mylist.list != NULL)
                {
                    free(mylist.list);
                    mylist.list = NULL;
                }
                printf("成功退出!\n");
                return 0;
            case 'g'://获取指定位置的元素
                 printf("\n请输入元素的位置:\n");
                 int pos; 
                 scanf("%d", &pos);
                 GetElem(&mylist, pos);
                 break;
            case 'i'://节点的插入
                InsertNode(&mylist);
                SortList(&mylist);
                break;
            case 't'://打印
                TraverseList(&mylist);
                break;
            case 'f'://元素查找
                getNode(&node);
                p = FindList(&mylist, &node);
                if(p == -1)
                    printf("未找到!\n");
                else
                    printf("找到了,位置在%d\n",p);
                break;
            case 'x'://3题的运行结果
                printGua(&mylist);
                break;
            case 'y'://4题的运行结果
                printBigerThanX(&mylist);
                break;
        }
    }
    return 0;
}

void InitList( List *L, int max_size)
{
    //线性表初始化函数
    /*检查max_size是否有效,若无效则退出运行*/
    if(max_size<=0) {printf(" max_size值非法!\n"); exit(1);}
    /*置线性表空间大小为max_size*/
    L->MaxSize=max_size;  
    /*动态存储空间分配,分配成功返回该内存地址,失败则返回NULL*/
    L->list=(ElemType*)malloc(max_size*sizeof(ElemType));  
    if(!L->list) {
        printf("动态存储分配失败!\n");
        exit(1); /*执行此函数则中止程序运行,此函数在stdlib.h中有定义*/
    }
    /*初始置线性表为空*/
    L->len=0;  
    InsertInitialNodes(L);
}

void InsertInitialNodes(List *L)
{
    //插入默认的节点
    ElemType *pNode = L->list;
    //第一位同学
    strcpy( pNode->name, "刘子祥"); strcpy(pNode->sNumber, "09");
    pNode->scores[0] = 80;pNode->scores[1] = 85; pNode->scores[2] = 87; pNode->scores[3]  = (80+85+87)/3;
    //第二位同学
    pNode = L->list + 1;
    strcpy( pNode->name, "孟祥欣"); strcpy(pNode->sNumber, "05");
    pNode->scores[0] = 81;pNode->scores[1] = 67; pNode->scores[2] = 74; pNode->scores[3]  = (81+67+74)/3;

    //第三位同学
    pNode = L->list + 2;
    strcpy( pNode->name, "谷红翠"); strcpy(pNode->sNumber, "03");
    pNode->scores[0] = 70;pNode->scores[1] = 68; pNode->scores[2] = 57; pNode->scores[3]  = (70+68+57)/3;

    //第四位同学
    pNode = L->list + 3;
    strcpy( pNode->name, "王甜甜"); strcpy(pNode->sNumber, "01");
    pNode->scores[0] = 52;pNode->scores[1] = 61; pNode->scores[2] = 52; pNode->scores[3]  = (52+61+52)/3;

    L->len = 4;

}
void ClearList(List *L)
{
    //清空表,直接调用free函数
    if(L->list != NULL)
    {
        free(L->list);
    }
    L->list = NULL;//防止二次释放
    L->len = L->MaxSize = 0;
}
void GetElem(List *L, int pos)
{
    if(L->list == NULL)
    {
        printf("表中无元素,请插入之后再访问!");
        return;
    }
    //获取pos位置的元素
    if(pos>=0 && pos < L->len)
    {
        ElemType *p = L->list + pos;
        printf("第%d位置的信息为:\n", pos);
        printNode(p);
    }
    else if(pos<=-1 && pos >= -L->len)//从后向前访问
    {
        ElemType *p = L->list + pos + L->len;
        printf("第%d位置的信息为:\n",  pos + L->len);
        printNode(p);
    }
    else//无效
    {
        printf("索引无效!");
    }
}

void getNode(ElemType *p)
{
    //获取用户输入的节点信息,以空格分开,但是不用输入平均成绩
    scanf("%s %s %d %d %d",p->sNumber, p->name, &p->scores[0], &p->scores[1], &p->scores[2]);
    int sum = 0, i; 
    for(i = 0;i<3;++i)
        sum += p->scores[i];
    p->scores[3] = sum/3;
}

void reallocate(List *L, int new_size)
{
    //重新分配内存
    ElemType *p = (ElemType*)malloc(new_size*sizeof(ElemType));  
    if(p == NULL)
    {
        printf("动态存储分配失败!\n");
        exit(1); /*执行此函数则中止程序运行,此函数在stdlib.h中有定义*/
    }
    //逐个复制到新的地方
    int  i;
    for(i = 0;i< new_size ;++i)
    {
        p[i] = L->list[i];
    }
    free(L->list);
    L->list = p;
    L->MaxSize = new_size;
}

void copybackwward(List *L, int pos)
{
    //从后向前挪,[pos, L->len)的元素向后挪一个
    int i;
    for(i = L->len-1; i>=pos;--i)
    {
        L->list[i+1] = L->list[i];
    }
}

void InsertNode(List *L)
{
    //节点的插入
    //内存不够的话重新分配内存
    //防止出现清空的情况
    if(L->len == 0 && L->MaxSize == 0)
        InitList(L, 100);

    if(L->len == L->MaxSize)
        reallocate(L, 2*L->MaxSize);

    int pos;
    printf("请输出插入节点的位置:\n");
    scanf("%d", &pos);
    //获取pos位置的元素
    ElemType node;
    if(pos>=0 && pos < L->len)
    {
        //向后拷贝,为新插入的节点挪挪地方
        printf("请输入节点信息,从左往右依次为学号、姓名、3科成绩,以空格隔开:\n");
        getNode(&node);
        copybackwward(L, pos);
        L->list[pos]= node;
        printf("节点插入成功!\n");
        L->len += 1;
    }
    else if(pos<=-1 && pos >= -L->len)//从后向前访问
    {
        //ElemType *p = L->list + pos + L->len;
        printf("请输入节点信息,从左往右依次为学号、姓名、3科成绩,以空格隔开:\n");
        getNode(&node);
        copybackwward(L, pos + L->len);
        L->list[pos + L->len] = node;
        L->len += 1;
        printf("节点插入成功!\n");
    }
    else if(pos==0 && pos == L->len)
    {
        //插入空表首部
        printf("请输入节点信息,从左往右依次为学号、姓名、3科成绩,以空格隔开:\n");
        getNode(&node);
        //printf("插入空表\n");
        L->list[0] = node;
        L->len += 1;
        printf("节点插入成功!\n");
        //printNode(&node);
    }
    else if(pos== L->len)
    {
        //尾部
        printf("请输入节点信息,从左往右依次为学号、姓名、3科成绩,以空格隔开:\n");
         getNode(&node);
        //printf("插入空表\n");
        L->list[pos] = node;
        L->len += 1;
        printf("节点插入成功!\n");
        //printNode(&node);
    }
    else//无效
    {
        printf("索引无效,插入失败!\n");
    }
}

void printInfo()
{
    printf("***********************欢迎来到线性表演示系统***********************\n");
    printf(" 操作指南:插入--i ;  清空--c;  获取长度--s; 获得第pos位置的元素 -- g \n");
    printf("     遍历打印--t ; 查找--f; 退出 -- q; 第3题 -- x; 第4题 -- y       \n");
     printf("*****************************************************************\n");
}

void printNode(ElemType *p)
{
    //打印节点的信息
    printf("学号:%s, 姓名 :%s, 线性代数:%d, 大学物理:%d, 数据结构:%d, 平均分:%d\n",
    p->sNumber, p->name, p->scores[0], p->scores[1],p->scores[2],p->scores[3]);
}

void TraverseList(List *L)
{
    if(L->len ==0 || L->list == NULL)
    {
        printf("空表,请勿打印!\n");
        return;
    }
    int  i;
    for(i = 0;i<L->len;++i)
        printNode(L->list + i);
}
int isequal(ElemType *p1, ElemType *pNode)
{
    //判断两个元素是否相等
    if(strcmp(p1->name, pNode->name) == 0 && strcmp(p1->sNumber, pNode->sNumber) == 0
        && p1->scores[0] == pNode->scores[0] && p1->scores[1] == pNode->scores[1]
        && p1->scores[2] == pNode->scores[2])//每个元素都要相等
        return 1;
    return 0;
}
int FindList(List *L, ElemType *pNode)
{
    //查找节点
     if(L->len ==0 || L->list == NULL)
    {
        printf("空表!\n");
        return -1;
    }
    int pos = -1;
    int i;
    for(i = 0;i<L->len;++i)
    {
        ElemType *p1 = L->list + i;
        printNode(pNode);
        if (isequal(p1, pNode))
        {
             pos = i;
             break;
        }
    }
    return pos;  
}

void SortList(List *L)
{
    //这个函数用于线性表的排序,由于本身默认的线性表大致有序,故在此采用
     if(L->len ==0 || L->list == NULL)
    {
        printf("空表!\n");
        return;
    }
    //插入排序
    int i;
    for(i =  1;i< L->len;++i)
    {
        int p = i-1;
        ElemType tmp = L->list[i];
        while(p >=0 && isSmaller(L->list + p , &tmp))
        {
            L->list[p+1] = L->list[p];
            p--;
        }
         L->list[p+1] = tmp;
    }
    TraverseList(L);
}
int isSmaller(ElemType *p1 , ElemType *p2)
{
    //该函数用来判断 *p1 是否小于 *p2
    int sum1 = 0, sum2 =0;
    int i;
    for(i = 0;i< 3;++i)
    {
        sum1 +=  p1->scores[i];
        sum2 +=  p2->scores[i];
    }
    return sum1 < sum2;
}

void printGua(List *L)
{
    //输出至少挂了一科的同学
    char *subjects[3] = {"线性代数", "大学物理", "数据结构"};
    int  i;
    for(i = 0;i<L->len;++i)
    {
        int j;
        for(j = 0;j<3;++j)
        {
            if((L->list[i]).scores[j] < 60)
                break;
        }
        if(j == 3)
            continue;
        printf("%s ",(L->list[i]).name);
        for(j = 0;j<3;++j)
        {
            if((L->list[i]).scores[j] < 60)
            {
                printf("%s--%d ",subjects[j], (L->list[i]).scores[j]);
            }
        }
        printf("\n");
    }
}

void printBigerThanX(List *L)
{
    //实验报告第四题
    printf("请输入x:\n");
    int x;
    scanf("%d", &x);
    if(x <= 0 || x >= 100)
    {
        printf("x的值不符合要求!\n");
        return;
    }
    int count = 0,i;
     for(i = 0;i<L->len;++i)
    {
       if((L->list[i]).scores[3] > x)
       {
            printf("%s %d\n", (L->list[i]).name, (L->list[i]).scores[3]);
            count++;
       }
    }
    if(count == 0)
        printf("输入的x太大了,没有符合条件的,换一个小点儿的\n");
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值