链表使用操作

1.链表常用函数

        1.malloc函数

        malloc函数在内存之中动态分配一块size大小的内存空间,它是为链表操作的基础。

        void *malloc(unsigned int size);

        2.calloc函数

        calloc函数用在内存中动态分配n个长度为size的连续空间。

        void *calloc(unsigned n,unsigned size);

        3.free函数

        free函数用来进行释放指针ptr指向的内存区域,使该部分内存可以被其它变量使用。

        void free(void *ptr);

        4.realloc函数

        realloc函数的功能将对应ptr指针指向的内存空间大小改为size;

        void *realloc(void *ptr,size_t size);

2.链表使用办法

1.头插法

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

struct Node 
{
    int data;
    struct Node* next;
};

// 创建新节点
struct Node* newNode(int data) 
{
    struct Node* node = (struct Node*)malloc(sizeof(struct Node));
    node->data = data;
    node->next = NULL;
    return node;
}

// 在链表头部插入节点
void insertAtHead(struct Node** head, int data) 
{
    struct Node* newNode = createNode(data);
    newNode->next = *head;
    *head = newNode;
}

// 打印链表数据
void printList(struct Node* head) 
{
    struct Node* temp = head;
    while (temp != NULL) {
        printf("%d ", temp->data);
        temp = temp->next;
    }
    printf("\n");
}

int main() {
    struct Node* head = NULL;

    // 在链表头部插入节点
    insertAtHead(&head, 3);
    insertAtHead(&head, 2);
    insertAtHead(&head, 1);

    printf("链表数据:");
    printList(head);

    return 0;
}

2.尾插法

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

struct Node {
    int data;
    struct Node* next;
};

// 创建新节点
struct Node* newNode(int data) {
    struct Node* node = (struct Node*)malloc(sizeof(struct Node));
    node->data = data;
    node->next = NULL;
    return node;
}

// 在链表尾部插入节点
void insertAtTail(struct Node** head, int data) {
    struct Node* newNode = createNode(data);
    
    if (*head == NULL) {
        *head = newNode;
    } else {
        struct Node* temp = *head;
        while (temp->next != NULL) {
            temp = temp->next;
        }
        temp->next = newNode;
    }
}

// 打印链表数据
void printList(struct Node* head) {
    struct Node* temp = head;
    while (temp != NULL) {
        printf("%d ", temp->data);
        temp = temp->next;
    }
    printf("\n");
}

int main() {
    struct Node* head = NULL;

    // 在链表尾部插入节点
    insertAtTail(&head, 1);
    insertAtTail(&head, 2);
    insertAtTail(&head, 3);

    printf("链表数据:");
    printList(head);

    return 0;
}

3.双向链表

双向链表(Doubly Linked List)是一种常见的链表数据结构,它与单向链表类似,但每个节点都有一个指向前一个节点的指针(prev),除了指向后一个节点的指针(next)。

双向链表中的每个节点包含三个部分:

  1. 数据(可以是任意类型的数据)。
  2. 指向前一个节点的指针(prev)。
  3. 指向后一个节点的指针(next)。

通过这两个指针,每个节点可以在链表中的前后移动。

相较于单向链表,双向链表的优点在于:

  1. 可以从任意方向遍历链表:由于每个节点都有一个指向前一个节点的指针,所以可以从头到尾或者从尾到头遍历链表。
  2. 删除操作更高效:删除节点时,不需要像单向链表那样找到待删除节点的前一个节点,而是直接更新前后节点的指针即可。

然而,双向链表的缺点是占用更多的内存空间,因为每个节点需要存储额外的指针。

双向链表提供了更灵活的操作,使得在某些场景下更为方便。例如,在需要频繁插入和删除节点的情况下,双向链表能够更高效地执行这些操作。

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

// 双向链表节点结构
struct Node {
    int data;
    struct Node* prev;
    struct Node* next;
};

// 在链表头部插入节点
void insertAtHead(struct Node** head, int data) {
    struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
    newNode->data = data;
    newNode->prev = NULL;
    
    if (*head != NULL) {
        (*head)->prev = newNode;
    }
    
    newNode->next = *head;
    *head = newNode;
}

// 在链表尾部插入节点
void insertAtTail(struct Node** head, int data) {
    struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
    newNode->data = data;
    newNode->next = NULL;
    
    if (*head == NULL) {
        newNode->prev = NULL;
        *head = newNode;
        return;
    }
    
    struct Node* temp = *head;
    while (temp->next != NULL) {
        temp = temp->next;
    }
    
    temp->next = newNode;
    newNode->prev = temp;
}

// 打印链表数据(正向)
void printForward(struct Node* head) {
    struct Node* temp = head;
    printf("正向打印链表数据:");
    while (temp != NULL) {
        printf("%d ", temp->data);
        temp = temp->next;
    }
    printf("\n");
}

// 打印链表数据(逆向)
void printBackward(struct Node* head) {
    struct Node* temp = head;
    if (temp == NULL) {
        return;
    }
    
    while (temp->next != NULL) {
        temp = temp->next;
    }
    
    printf("逆向打印链表数据:");
    while (temp != NULL) {
        printf("%d ", temp->data);
        temp = temp->prev;
    }
    printf("\n");
}

int main() {
    struct Node* head = NULL;

    // 在链表头部插入节点
    insertAtHead(&head, 3);
    insertAtHead(&head, 2);
    insertAtHead(&head, 1);

    // 在链表尾部插入节点
    insertAtTail(&head, 4);
    insertAtTail(&head, 5);

    // 正向打印链表数据
    printForward(head);

    // 逆向打印链表数据
    printBackward(head);

    return 0;
}

举个函数学生信息的链表函数

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

struct student
{
    int num;
    char name[64];
    float score;
    struct student* pnext;
};
//全局定义
void input(void);//进行成绩的录入
void delect(void);//进行学生信息的删除
void revise(void);//进行学生信息的修改
void find(void);//进行学生信息的查找
void show(void);//显示学生信息
struct student *phead=NULL;//全局定义链表头函数

int main()
{
    int choice=0;
face:
    while(1)
    {
        printf("********学生管理系统********\n");
        printf("*****1.进行学生信息记录*****\n");
        printf("*****2.进行学生信息删除*****\n");
        printf("*****3.进行学生信息修改*****\n");
        printf("*****4.进行学生信息查找*****\n");
        printf("*****5.返回学生信息界面*****\n");
        printf("*****6.退出学生管理系统*****\n");
        printf("请输入您所需要进行的操作\n");
        scanf("%d",&choice);
        if((choice>0&&choice<7)||(choice=99))
        {
            if(choice==1)
            {
                input();//记录
            }
            else if(choice==2)
            {
                delect();//删除
            }
            else if(choice==3)
            {
                revise();//选择
            }
            else if(choice==4)
            {
                find();//查找
            }
            else if(choice==5)
            {
                printf("正在返回学生主界面......\n");
                goto face;
            }
            else if(choice==6)
            {
                printf("正在退出学生信息管理系统......\n");
                goto over;
            }
            else if(choice==99)
            {
                show();
            }
        }
        else
        {
            printf("您所输入的数字不合规则\n");
            goto face;
        }
    }
over:
    printf("谢谢使用\n");
}
void input(void)//进行成绩的录入
{
    struct student *pnew=NULL;
    struct student *ptemp=phead;
    pnew=(struct student*)malloc(sizeof(struct student));//给新录入的数开辟空间
    pnew->pnext=NULL;
    printf("学号\n");
     scanf("%d",&pnew->num);
    printf("姓名\n");
     scanf("%s",pnew->name);
    printf("成绩\n");
     scanf("%f",&pnew->score);
    if(phead==NULL)
    {
        phead=pnew;
    }
    else
    {
        while(ptemp->pnext!=NULL)
        {
            ptemp=ptemp->pnext;
        }
        ptemp->pnext=pnew;
    }
    return;
}
void delect(void)//进行学生信息的删除
{
    int num1=0;
    struct student *ptemp=phead;
    struct student *pdel=NULL;
    printf("请输入您所需要进行删除的学号\n");
    scanf("%d",&num1);
    if (phead==NULL)
    {
        printf("该空间并不存在该学生\n");
        return;
    }
    if (ptemp->num==num1)//判定第一个节点是否为要进行删除的节点
    {
        pdel=phead;
        phead=phead->pnext;
        free(pdel);
        printf("已经删除了对应学号的学生\n");
        return ;
    }
    while(ptemp->pnext!=NULL)//如果不是第一个节点
    {
        if(ptemp->pnext->num==num1)
        {
            pdel=ptemp->pnext;
            ptemp->pnext=ptemp->pnext->pnext;
            free(pdel);
            printf("已经删除了对应学号的学生\n");
            return ; 
        }
        ptemp=ptemp->pnext;
    }
    printf("查无此人\n");
}
void revise(void)//进行学生信息的修改
{
    int num1;
    struct student *pnew=phead;
    printf("正在进行修改中......\n");
    printf("请输入您想所需要进行修改的学生学号\n");
    scanf("%d",&num1);
    while(pnew!=NULL)
    {
        if(pnew->num==num1)
        {
        printf("请输入您所需要进行修改的信息\n");
        printf("学号\n");
        scanf("%d",&pnew->num);
        printf("姓名\n");
        scanf("%s",pnew->name);
        printf("成绩\n");
        scanf("%f",&pnew->score);
        printf("修改成功\n");
        break;
        }
        pnew=pnew->pnext;
    }
    if (pnew=NULL)
    {
        printf("未查到需要修改的学生\n");
    }
} 
void find(void)//进行学生信息的查找
{
    int num1;
    struct student *pfind=phead;
    printf("正在进行查找中......\n");
    printf("请输入您想所需要进行查找的学生学号\n");
    scanf("%d",&num1);
    while(pfind!=NULL)
    {
        if(pfind->num==num1)
        {
        printf("学号\t姓名\t成绩\n");
        printf("%d\t",pfind->num);
        printf("%s\t",pfind->name);
        printf("%.2f\n",pfind->score);
        break;
        }
        pfind=pfind->pnext;
    }
    if (pfind=NULL)
    {
        printf("未查到该学生\n");
    }
}
void show(void)//显示学生信息
{
    struct student *ptemp=NULL;//进行中间变量的定义
    int ilndex=0;
    printf("*****所有学生信息如下*****\n");
    printf("\n");
    printf("学号\t姓名\t成绩\n");
    ptemp=phead;

    while(ptemp!=NULL)
    {
        printf("%d\t",ptemp->num);
        printf("%s\t",ptemp->name);
        printf("%.2f\n",ptemp->score);
        ptemp=ptemp->pnext;
        ilndex++;
    }
    printf("一共录入了%d个同学\n",ilndex);
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值