C语言链表详解

C语言链表详解

链表基础

链表的优点
  1. n个节点离散分配
  2. 每一个节点之间通过指针相连
  3. 每一个节点有一个前驱节点和一个后继节点
  4. 首节点没有前驱节点,尾节点没有后继节点
基本概念
  • 首节点:存放第一个有效数据的节点

  • 头节点:在单链表的第一个结点之前附设一个结点,它没有直接前驱,称之为头结点,头结点的数据域可以不存储任何信息,指针域指向第一个节点(首节点)的地址。头结点的作用是使所有链表(包括空表)的头指针非空

  • 头指针:指向头节点的指针

  • 尾节点:存放最后一个有效数据的节点

  • 尾指针:指向尾节点的指针

image-20211212155718512

创建链表

定义一个结构体
typedef struct linklist{
    int score;//定义数据域
    struct student *next;//定义指针域
}linklist;

创建一个链表
//初始化一个链表 n为链表节点个数
Linklist *linklistcreate(int n){
    Linklist *head,*node,*end;//定义头节点,普通节点,尾部节点;
    head = (Linklist*)malloc(sizeof(Linklist));//分配地址
    end = head;//若是空链表,则头尾节点一样
    for(int i =0;i<n;i++){
        node = (Linklist*) malloc(sizeof(Linklist));
        scanf("%d",&node->score);
        end->next = node;
        end=node;
    }
    end->next=NULL;//结束创建
    return head;
}

插入节点

image-20211212184637792

//插入节点
//插入节点就是用插入前节点的指针域链接上插入节点的数据域,再把插入节点的指针域链接上插入后节点的数据域。
//e->next = head->next;  head->next = e
void insert(Linklist *list,int n){
    Linklist *t=list,*in;
    int i =0;
    while(i<n&&t!=NULL){
        t = t->next;
        i++;
    }
    if(t!=NULL){
        in = (Linklist*) malloc(sizeof(Linklist));
        puts("请输入要插入的值:");
        scanf("%d",&in->score);
        in->next=t->next;//填充in节点的指针域,也就是说把in的指针域指向t的下一个节点
        t->next=in;//填充t节点的指针域,把t的指针域重新指向in
    }
    else{
        puts("节点不存在");
    }
}
删除节点

image-20211212184622999

//删除链表节点
//删除链表的元素也就是把前节点的指针域越过要删除的节点指向下下个节点。
// 即:p->next = q->next;然后放出q节点的空间,即free(q);

void delete(Linklist *list,int n){
    Linklist  *t = list,*in;
    int i =0;
    while(i<n && t != NULL){
        in = t;
        t = t->next;
        i++;
    }
    if(t != NULL){
        in->next= t->next;
        free(t);
    }
    else{
        puts("节点不存在");
    }
}

修改节点
//修改链表节点值
void change(Linklist *list,int n){
    Linklist *t = list;
    int i = 0;
    while (i<n&&t!=NULL){
        t = t->next;
        i++;
    }
    if(t!=NULL){
        puts("输入要修改的值:");
        scanf("%d",&t->score);
    }
    else{
        puts("节点不存在");
    }
}
输出节点
void output(Linklist *head,int n){
    Linklist *h = head;
    int i =0;

    while (h != NULL){
        h =h->next;
        printf("%d",h->score);
    }
}

完整代码

#include<stdio.h>
#include <malloc.h>
#include <stdbool.h>

//定义结构体
typedef struct linklist{
    int score;//定义数据域
    struct student *next;//定义指针域
}Linklist;

Linklist *linklistcreate(int n);
void insert( Linklist *head,int n);
void delete(Linklist *head,int n);
void change(Linklist *head,int n);
void output(Linklist *head,int n);

int main(){
    int n,in,x,y;
    char c;
    struct Linklist *head  =NULL;
    printf("请输入要创建的节点个数:\n");
    scanf("%d",&n);
    head = linklistcreate(n);
    printf(head);
    while (true){
        printf("请选择要执行的操作:\n");
        printf("1.插入节点\n2.删除节点\n3.修改节点\n4.退出\n");
        scanf("%c",&c);
        if(c =='1'){
            printf("你想要在哪插入节点:\n");
            scanf("%c",&in);
            insert(head,in);
            printf(head);
            output(head,n);
        }else if(c == '2'){
            printf("你想要删除哪个节点的数据:\n");
            scanf("%d",&x);
            delete(head,x);
            printf(head);
        }else if(c =='3'){
            printf("你想要修改哪个节点的数据:\n");
            scanf("%d",&y);
            change(head,y);
            printf(head);
        }else if(c =='4'){
            exit(0);
        }
    }
}

//初始化一个链表 n为链表节点个数
Linklist *linklistcreate(int n){
    Linklist *head,*node,*end;//定义头节点,普通节点,尾部节点;
    head = (Linklist*)malloc(sizeof(Linklist));//分配地址
    end = head;//若是空链表,则头尾节点一样
    for(int i =0;i<n;i++){
        node = (Linklist*) malloc(sizeof(Linklist));
        scanf("%d",&node->score);
        end->next = node;
        end=node;
    }
    end->next=NULL;//结束创建
    return head;
}

//插入节点
//插入节点就是用插入前节点的指针域链接上插入节点的数据域,再把插入节点的指针域链接上插入后节点的数据域。
//e->next = head->next;  head->next = e
void insert(Linklist *list,int n){
    Linklist *t=list,*in;
    int i =0;
    while(i<n&&t!=NULL){
        t = t->next;
        i++;
    }
    if(t!=NULL){
        in = (Linklist*) malloc(sizeof(Linklist));
        puts("请输入要插入的值:");
        scanf("%d",&in->score);
        in->next=t->next;//填充in节点的指针域,也就是说把in的指针域指向t的下一个节点
        t->next=in;//填充t节点的指针域,把t的指针域重新指向in
    }
    else{
        puts("节点不存在");
    }
}

//删除链表节点
//删除链表的元素也就是把前节点的指针域越过要删除的节点指向下下个节点。
// 即:p->next = q->next;然后放出q节点的空间,即free(q);

void delete(Linklist *list,int n){
    Linklist  *t = list,*in;
    int i =0;
    while(i<n && t != NULL){
        in = t;
        t = t->next;
        i++;
    }
    if(t != NULL){
        in->next= t->next;
        free(t);
    }
    else{
        puts("节点不存在");
    }
}

//修改链表节点值
void change(Linklist *list,int n){
    Linklist *t = list;
    int i = 0;
    while (i<n&&t!=NULL){
        t = t->next;
        i++;
    }
    if(t!=NULL){
        puts("输入要修改的值:");
        scanf("%d",&t->score);
    }
    else{
        puts("节点不存在");
    }
}


void output(Linklist *head,int n){
    Linklist *h = head;
    int i =0;

    while (h != NULL){
        h =h->next;
        printf("%d",h->score);
    }
}


  • 29
    点赞
  • 187
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值