创建、删除、插入、输出输出动态链…

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#define LEN sizeof(struct student)

struct student
{
    int num;
    char name[10];
    float score;
    struct student *next;
};
static unsigned inode=1;   //定义全局变量,表示链表节点数(长度)
void fill(char c[],int n,char ch);                   //专门用于初始化字符数组:用c填充整个数组c[],n是数组长度
void del(struct student *ph,int n);   //删除链表对象,n是用户指定要删除的序号
void insert(struct student *ph,int n);   //插入链表节点,在ph的第n个节点之后插入,也可以在表头插入
void output(struct student *ph);               //输出函数
struct student *input(void);          //输入函数,函数会新申请一个空间,完成数据输入,返回空间首地址
void clearline(int n);

int main()      //尝试动态链表的创建与删除
{
    struct student *head,*ps,*pa,*pb;   //head是头部,ps用来特别定位到头部,pa用来访问和遍历链表,pb用来备份节点地址
    int u;     //u用来读取用户指定要删除的序号
    char flag='y';      //flag旗标用来记录用户选择
    head=ps=pa=(struct student *)malloc(LEN);   //所有指针初始化到链表头部
    fill(pa->name,10,'\0');      //字符数组初始化
    printf("请输入学生信息,格式如下,字段之间可以以TAB跳格:\n");
    printf("学号\t姓名\t成绩\n");
    while(flag!='n') {
        scanf("%d %s %f",&pa->num,pa->name,&pa->score);
        printf("Press any key input data continue,otherwise press n quit:");
        flag=getche();
        if(flag!='n') {
            clearline(60);
            pa->next=(struct student *)malloc(LEN);
            pa=pa->next;
            fill(pa->name,10,'\0');
            inode++;               //记住链表的节点数(长度)
            }
        }
    pa->next=NULL;
    output(ps);
    //删除操作开始
    printf("你想删除其中的哪一个学生?\n");
    printf("请输入你要删除的信息列表序号:");
    scanf("%d",&u);
    if(u>inode) {
        printf("输入错误!\n");
        exit(1);
        }
    if(u==1) {              //第一个节点的删除和其他不同
        pb=head;            //备份链表的原始头地址
        ps=head->next;      //备份下一个节点起始地址
        free(pb);           //释放链表的原始头节点
        head=pb=pa=ps;      //将新的链表头地址赋给pb和head以便下次调用
        }
    else
        del(ps,u);
    //删除操作结束
    output(ps);
    //插入操作开始
    printf("你要在哪条记录之后插入记录?(要在开头插入记录,请输入0):");
    scanf("%d",&u);
    if(u>inode) {
        printf("输入错误!\n");
        exit(1);
        }
    if(u==0) {
        pb=head;    //记住原链表头地址
        head=ps=pa=input(); //所有链表头部新地址确定
        pa->next=pb;    //原链表头部链接到新链表头部后面
        inode++;
        }
    else
        insert(ps,u);
    //插入操作结束
    output(ps);
    return 0;
}

void fill(char c[],int n,char ch)    //专门用于初始化字符数组:用c填充整个数组c[],n是数组长度
{
    int i;
    for(i=0;i<n;i++)
        *(c+i)=ch;
}

void del(struct student *ph,int n)
{
    int i;
    struct student *pb,*pf;
    pb=pf=ph;                       //所有指针初始化到链表头部
    for(i=1;i<=n-2;i++) {           //寻找目标节点的上一个节点
        ph=ph->next;
        }
    if(n==inode) {                  //如果是最后一个节点,删除情况与其他不同
        pb=ph->next;
        ph->next=NULL;
        free(pb);
        }
    else {
        pb=ph->next;                //备份目标节点地址
        ph->next=(ph->next)->next;  //将目标节点的下一个节点与上一个节点连接起来
        free(pb);                   //释放目标节点的内存占用
        }
    inode--;
}

void insert(struct student *ph,int n)   //需要链表首地址和插入点
{
    int i;
    struct student *pa,*pb,*p_new,*ps;
    ps=pa=ph;
    p_new=(struct student *)malloc(LEN);
    fill(p_new->name,10,'\0');      //字符数组初始化
    printf("请输入要插入的学生信息:\n");
    printf("学号\t姓名\t成绩\n");
    scanf("%d %s %f",&p_new->num,p_new->name,&p_new->score);
    for(i=1;i
        pa=pa->next;
    pb=pa->next;            //记住下一个节点地址
    pa->next=p_new;   //将新节点链接到插入点下面
    p_new->next=pb;   //将下一个节点链接到新节点下面
    inode++;
}

void output(struct student *ph)
{
    int i;
    struct student *pa;
    printf("\n*****输出信息列表*****\n");
    printf("序号\t 学号\t姓名\t\t成绩\n");
    for((i=1,pa=ph);pa->next!=NULL;(i++,pa=pa->next))
        printf("-\t]\t%-8s\t%.2f\n",i,pa->num,pa->name,pa->score);
    printf("-\t]\t%-8s\t%.2f\n",i,pa->num,pa->name,pa->score);
    printf("一共有%d个对象\n",inode);
}

struct student *input(void)
{
    struct student *pa;
    pa=(struct student *)malloc(LEN);
    printf("请输入要插入的学生信息:\n");
    printf("学号\t姓名\t成绩\n");
    scanf("%d %s %f",&pa->num,pa->name,&pa->score);
    return pa;
}


void clearline(int n)
{
    int space;
    for((printf("\r"),space=0);(printf(" "),space<n);space++);
    printf("\r");   //清除完屏幕提示信息光标回以行首开始下一次输入
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

互联网速递520

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

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

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

打赏作者

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

抵扣说明:

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

余额充值