C语言链表(超详细)

前言:之前学习链表的时候总会遇到一些问题
也看了好多人的文章感觉有些不是太实用
然后后来也是自己摸索才大概写出来的.
在真正的开发中会把链表的增删改查写到函数里
但是删除有点麻烦 找了很多都是删除第几个 而不是删除某个值对应的节点 让我很难受
所以想写一些链表的操作分享一些 我也不会用长一点的名字去命名 这样阅读性会好一些

不过在实际开发中建议使用较长的名字去命名好了 话不多说


一.链表的创建


一般分为头插法和尾插法
1.我在写项目的时候喜欢使用头插法
因为我希望在创建结点的时候按照某种方法去排序
如果用尾插法创建的话快 但是 如果在创建好后再排序就有些麻烦
话不多说贴代码.
第一步 让我们写出这个结点的声明`

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

然后先让我们看看主函数中该怎么写

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

int main() {
    Node *head;
    head = NULL;
    int n;//这里的n代表创建多少个结点 

    scanf("%d",&n);

    for (int i = 0; i < n; ++i) {
        int a;//这里的a代表传给结点的值 
        scanf("%d",&a);
        insert(&head, a);//insert 增加链表结点函数 
    }

    Node *temp = head;

    while(temp != NULL) { //输出这个链表 
        printf("%d ",temp->data);
        temp = temp->next;
    }
    return 0;
}

接下来就是inser()函数的写法了.
首先我们需要在这个函数里面创建一个结点

void insert(Node **head ,int value) {
  //这个参数是取头结点的地址. 
    Node *temp = (Node*)malloc(sizeof(Node)); 
    temp->next = NULL; 
    temp->data = value;
    }

然后怎么利用头结点的头插法把这个链表连起来呢?
我们首先得判断 这个头结点是不是为NULL 因为在定义的时候定义了NULL

    if((*head) == NULL) {
  //这里*head 因为head是二级指针 加个*就降了一级.
        (*head) = temp; //建议全部带括号*这个运算符的结合律防止出错都带括号把
    }

其实这个判断也就是判断是不是第一次创建 头结点有没有东西
头结点要是有了东西呢?

else {
        Node *t = (*head); //让临时指针的从头开始遍历.
        while(t->next != NULL) { // 这里一定是t->next 如果让t连的话 就连接不起来

            t = t->next;
        }
        t->next=temp;   //指针域的作用就是连接. 
    }

好了 这就是头插法的创建
但是我们明显发现效率不高 尾插法创建一个就接到链表里面
创建一个就接进去.
但是头插法不行. 必须是创建一个 再从头开始.
但是!
看接下来的一个妙用 我要创建链表并且排序.
这里我们做一个约定 从小到大排列.让我们看看怎么做
还是像刚才创建一样 如果头是空怎么怎么样 否则怎么怎么样对吗?
想一想要改这里吗?

    if((*head) == NULL) {
        (*head) = temp;
    } else {
  

答案肯定是不用改因为没数据肯定就把第一个放进去.
那么肯定就是改下一处了
按照我们刚在的想法是不是可以这样写

    while(t != NULL) {
         if(t->next->data > temp->data) { // 如果t的下一个的数据大于了新结点
                temp->next = t->next; //让新结点的指针指向了t的下一个
                t->next = temp; //再让t指向新结点
                return; //返回就好
             }
            t = t->next;
        }

但是这里其实是有两处问题的 先说第一处:
因为是从小到大比较的 我们上面的写法是从头开始
找到比他大的地方就让他插进去.但是如果新的结点就是最大的呢
也就是跑到完都没进到 if 语句中去
所以应该加一个

while(t != NULL) {
            if(t->next == NULL)  {
  //这一次我们判断下一个是不是空
                t->next = temp; //如果是空了连接一下
                return;   //返回就行
             } else if(t-><
  • 124
    点赞
  • 685
    收藏
    觉得还不错? 一键收藏
  • 15
    评论
C语言中,链表的查询可以通过遍历链表来实现。具体的步骤如下: 1. 首先,定义一个指向链表头节点的指针,用于遍历链表。 2. 从头节点开始,依次比较每个节点的值是否与目标值相等。 3. 如果找到匹配的节点,返回该节点的位置或者其他需要的信息。 4. 如果遍历完整个链表都没有找到匹配的节点,则表示目标值不存在于链表中。 这样,我们就可以通过遍历链表来进行查询操作。 需要注意的是,在进行链表查询时,要确保链表的指针不为空,以避免出现空指针异常。另外,在遍历链表时,可以利用循环结构来实现,直到遍历到链表的末尾或者找到匹配的节点为止。 总结起来,链表的查询操作可以通过遍历链表,依次比较每个节点的值来实现。这是一个常见且基础的链表操作,对于理解链表的概念和应用非常重要。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [一看就懂-c语言链表的查找,删除,清空【初阶】](https://blog.csdn.net/weixin_64524066/article/details/122373656)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [C语言链表详解](https://blog.csdn.net/k666499436/article/details/124787990)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值