双向循环链表相关操作

本实验主要完成双向循环链表的
创建
添加数据
查找数据
删除数据
遍历
实验过程中遇到的问题:
1、malloc空间申请
2、malloc空间释放
问题1
函数129行处,在输入学生姓名之前为姓名申请了20个字符的空间;可以看到,链表的数据域是一个结构体,结构体包含学生的三个属性信息;
在实现的过程中,将姓名申请为字符指针用于存储学生姓名;因此除了在添加节点时为节点Node申请空间外,还需要为姓名申请空间(如果将姓名指定为字符数组将不涉及这个问题);
问题2
空间释放问题
函数169行处,在删除节点之后,我们需要释放节点申请的空间(Node);同时也需要将存放名字的空间释放掉,但是问题是,我们需要函数返回姓名,如果在del函数中将空间释放掉,我们将无法获取姓名,所以本文在调用完del函数后在主函数总释放了姓名的空间;

关于双向循环链表:
1、头结点
这里写图片描述
作为头结点,数据域为空,前向指针和后向指针都指向自己;
2、其他节点
这里写图片描述
如图这样三个节点Node是头结点,其他两个是数据节点;
假设现在需要删除节点Node1;
需要先将图中的四条线断开(×号标注)
这里写图片描述
断开后会发现,Node2的prior和Node的next没有指向的节点,此时需要将Node2的prior指向Node,Node的next指向Node2;
这里写图片描述
节点的增加也是这样,先断后连,但是需要注意的是断和连的先后关系,有些时候需要中间变量;注意这样的逻辑就不会出错。

#include<stdio.h>
#define ERROR -1
#define OK 0
#define NOTEXIST 1
typedef int State;
struct studentInfo
{
    int id;
    int age;
    char *name;
}studentInfo;
struct Node
{
    struct studentInfo student;
    struct Node *prior;
    struct Node *next;
}Node;
typedef struct Node * LinkList;
typedef struct studentInfo * Student;
int system(const char *string);
//创建链表
State createLinkList(LinkList *L) {
    (*L) = (LinkList)malloc(sizeof(Node));
    if ((*L) == NULL)
        return ERROR;
    (*L)->next = (*L);
    (*L)->prior = (*L);
    return OK;
}
//向链表中添加数据
//链表中添加数据有两种方式
//一种头插法一种尾插法
//尾插法需要寻找链表尾部

State addDataFirst(LinkList *L, struct studentInfo student) {
    LinkList p;
    p = (LinkList)malloc(sizeof(Node));
    p->student = student;
    p->next = (*L)->next;
    (*L)->next->prior = p;
    (*L)->next = p;
    p->prior = (*L);
//  printf("%d,%d,%s\n", student.id, student.age, student.name);
    return OK;
}

State addDataLast(LinkList *L, struct studentInfo student) {
    LinkList p;
    p = (LinkList)malloc(sizeof(Node));
    p->student = student;
    (*L)->prior->next = p;
    p->prior = (*L)->prior;
    (*L)->prior = p;
    p->next = (*L);
//  printf("%d,%d,%s\n", student.id, student.age, student.name);
    return OK;
}
//数据查找
//感兴趣的朋友可以多写几个查找函数,完成按照姓名,学号,
//年龄等不同属性查找的功能。
State findData(LinkList L, int id, Student findStu) {
    LinkList p;
    p = L->next;
    while ((p->student).id != id)
    {
        if (p->next == L) {
            return NOTEXIST;
        }
        p = p->next;
    }
    *findStu = (p->student);
    return OK;
}
//数据删除
State deleData(LinkList *L, int id, Student studentPtr) {
    LinkList p;
    p = (*L)->next;
    while ((p->student).id != id)
    {
        if (p->next == L) {
            return NOTEXIST;
        }
        p = p->next;
    }
    p->next->prior = p->prior;
    p->prior->next = p->next;
    (*studentPtr) = p->student;
    free(p);
    return OK;
}
//数据遍历
State printData(LinkList L) {
    LinkList p;
    struct studentInfo student;
    p = L->next;
    if (p == L)
        return NOTEXIST;
    while (p != L) {
        student = p->student;
        printf("%d,%d,%s\n", student.id, student.age, student.name);
        p = p->next;
    }
    return OK;
}
int main() {
    struct studentInfo student;
    LinkList L;
    LinkList p;
    State state = 0;
    int option =1;
    char flag = 0;
    int id;
    createLinkList(&L);
    printf("Add student information(0)\n");
    printf("Find the student information by id(1)\n");
    printf("Delete the student information by id(2)\n");
    printf("Check all students information(3)\n");
    printf("Quite(4)\n");
    while (1) {
        printf("please input the option!\n");
        scanf("%d", &option);
        system("cls");
        if(option>4 || option <0 ) {
            printf("Don't have this option!\n");
            printf("please resume load!\n");
        }
        while (option == 0) {
            printf("Add student information is:\n");
            student.name = (char *)malloc(20 * sizeof(char));
            scanf("%d,%d,%s", &student.id, &student.age, student.name);
            state = addDataLast(&L, student);
            if (!state)
                printf("Add student sucessed!\n");
            printf("press[ENTER]continue!press others quite...\n");
            flag=getchar();
            flag = getchar();
            if (flag != '\n')
                break;
        }
        while (option == 1) {
            printf("Find the student by id(1)\n");
            printf("please input id:\n");
            scanf("%d", &id);
            state = findData(L, id, &student);
            if (state == OK) {
                printf("Find sucessed!\nThe information is:\n");
                printf("%d,%d,%s\n", student.id, student.age, student.name);
            }
            else {
                printf("This id don't exit!\n");
                printf("All student is:\n");
                printData(L);
                printf("please input id agin!\n");
            }
            printf("press[ENTER]continue!press others quite...\n");
            flag = getchar();
            flag = getchar();
            if (flag != '\n')
                break;
        }
        while(option == 2) {
            printf("Delete the student information by id(2)\n");
            printf("please input id\n");
            scanf("%d", &id);
            state = deleData(&L, id, &student);
            if (state == OK) {
                printf("Delete sucessed!\nThe information is :\n");
                printf("%d,%d,%s\n", student.id, student.age, student.name);
                free(student.name);
            }
            else {
                printf("This id don't exit!\n");
                printf("All student is:\n");
                printData(L);
                printf("please input id agin!\n");
            }
            printf("press[ENTER]continue!press others quite...\n");
            flag = getchar();
            flag = getchar();
            if (flag != '\n')
                break;
        }

        if (option == 3) {
            printf("All student is:\n");
            printData(L);
        }
        else if (option == 4)
            break;
        else
            ;
    }
    return OK;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值