【2023-10-10】C语言链表基础学习

链表的创建与插入

链表的创建格式:

//定义结点类型
typedef struct _Node {
    int data;       
//数据类型,你可以把int型的data换成任意数据类型,包括结构体struct等复合类型
    struct _Node *next;          
//单链表的指针域
} Node,*LinkedList;  
//Node表示结点的类型,LinkedList表示指向Node结点类型的指针类型

链表的本质上是结构体

链表的初始化格式:

LinkedList listinit(){
    Node *L;
    L=(Node*)malloc(sizeof(Node));      //开辟空间 
    if(L==NULL){                     //判断是否开辟空间失败,这一步很有必要
        printf("申请空间失败");
        //exit(0);                  //开辟空间失败可以考虑直接结束程序
    }
    L->next=NULL;       //指针指向空
}

头插入法创建单链表:每次插入结点在头节点之前。

L表示头结点,

p代表新创建的结点,p->next表示p的指针域,p->data表示p的数据域。

//头插法建立单链表
LinkedList LinkedListCreatH() {
    Node *L;
    L = (Node *)malloc(sizeof(Node));   //申请头结点空间
    L->next = NULL;                      //初始化一个空链表
  
    int x;                         //x为链表数据域中的数据
    while(scanf("%d",&x) != EOF) { // 保证新结点的数据域不为空
        Node *p;
        p = (Node *)malloc(sizeof(Node));   //申请新的结点
        p->data = x;                     //结点数据域赋值
        p->next = L->next;     //将结点插入到表头L-->|2|-->|1|-->NULL
        L->next = p;
    }
    return L;
}

尾插入法创建单链表:

//尾插法建立单链表
  
LinkedList LinkedListCreatT() {
    Node *L;
    L = (Node *)malloc(sizeof(Node));   //申请头结点空间
    L->next = NULL;                  //初始化一个空链表
    Node *r;
    r = L;                          //r始终指向终端结点,开始时指向头结点
    int x;                         //x为链表数据域中的数据
    while(scanf("%d",&x) != EOF) {
        Node *p;
        p = (Node *)malloc(sizeof(Node));   //申请新的结点
        p->data = x;                     //结点数据域赋值
        r->next = p;            //r和L共用一个指针域,这里相当于L->next = p
//将结点插入到表头L-->|1|-->|2|-->NULL
        r = p;
    }
    r->next = NULL;
    return L;
}

链表的打印与修改

遍历输出单链表。

对于p = p->next,意思就是结点p改为它指针域指向的下一个结点。

//便利输出单链表
void printList(LinkedList L){
    Node *p=L->next;
    int i=0;
    while(p){
        printf("第%d个元素的值为:%d\n",++i,p->data);
        p=p->next;
    }
}

链表的元素修改

//链表内容的修改,在链表中修改值为x的元素变为为k。
LinkedList LinkedListReplace(LinkedList L,int x,int k) {
    Node *p=L->next;
    int i=0;
    while(p){
        if(p->data==x){
            p->data=k;
        }
        p=p->next;
    }
    return L;
}

链表的中间插入与删除操作:

free(p)表示删除p结点:

//单链表的删除,在链表中删除值为x的元素
//详情见https://zhuanlan.zhihu.com/p/249144171
  
LinkedList LinkedListDelete(LinkedList L,int x) {
    Node *p,*pre;                   //pre为前驱结点,p为查找的结点。
    p = L->next;
     
    while(p->data != x) {              //查找值为x的元素
        pre = p;
        p = p->next;
    }
    pre->next = p->next;          //删除操作,将其前驱next指向其后继。
    free(p);
     
    return L;
}
//单链表的插入,在链表的第i个位置插入x的元素
  
LinkedList LinkedListInsert(LinkedList L,int i,int x) {
    Node *pre;                      //pre为前驱结点
    pre = L;
    int tempi = 0;
    for (tempi = 1; tempi < i; tempi++) {
        pre = pre->next;                 //查找第i个位置的前驱结点
    }
    Node *p;                                //插入的结点为p
    p = (Node *)malloc(sizeof(Node));
    p->data = x;
    p->next = pre->next;
    pre->next = p;
  
    return L;
}

 


细节:点(.)是用于结构体变量访问成员,箭头(->)是用于结构体指针访问成员。
例如:


#include <stdio.h>
 
int main(void) {
    struct Smy {
          int a;
    };
    
    struct Smy test;
    struct Smy * pt;
    test.a = 1;
    pt = &test;
       
    printf("%d\n", test.a);
    printf("%d\n", pt->a);

以上是最为基础的单链表的创建、遍历、插入、查找操作。

此外还有进阶的循环链表、双向链表、循环双向链表的相同操作值得学习。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值