学习c语言:单链表的应用

本文详细介绍了单链表的四种经典算法:移除链表元素、反转链表、合并两个有序链表和查找链表中间节点。同时探讨了循环链表的应用,如解决约瑟夫环问题。
摘要由CSDN通过智能技术生成

一、单链表经典算法

1.1 单链表相关经典算法OJ题1:移除链表元素     

. - 力扣(LeetCode). - 备战技术面试?力扣提供海量技术面试资源,帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。icon-default.png?t=N7T8https://leetcode.cn/problems/remove-linked-list-elements/

在做这道题的时候,采用定义两个指针,然后定义一个临时变量遍历整个链表,如果这个节点的val不等于要删除的值,就再判断头节点是否为空,如果为空插入数据就是使头节点等于未结点等于pcur newhead=newtail=pcur,不为空则将newtail的下一个定位到pcur,再将newtail移到链表未结点。经过这次遍历newtail的next为野指针,需要将它置空。返回头节点。
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
typedef struct ListNode ListNode;
struct ListNode* removeElements(struct ListNode* head, int val) {
    ListNode* newHead,*newTile;
    newHead=newTile=NULL; 
    ListNode *pcur=head;
    while(pcur){
        if(pcur->val!=val){
            if(newHead==NULL){
                newHead=newTile=pcur
            }
            else{
                newTile->next=pcur;
                newTile=newTile->next;
            }
        }
        pcur=pcur->next;
    }
    if(newTile){
        newTile->next=NULL;
    }
    return newHead;
}

 1.2 单链表相关经典算法OJ题2:反转链表

. - 力扣(LeetCode). - 备战技术面试?力扣提供海量技术面试资源,帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。icon-default.png?t=N7T8https://leetcode.cn/problems/reverse-linked-list/先处理特殊情况,如果head等于空直接返回head即可。然后定义三个结构体指针,n1=NULL,n2=head,n3=head->next.遍历整个链表,想要将链表反转就得将n2指向n1......然后遍历整个链表,如果n3不为空则n3=n3->next。使n1等于head,最后返回n1。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
 typedef struct ListNode ListNode;
struct ListNode* reverseList(struct ListNode* head) {
   if(head==NULL){
    return head;
   }
   ListNode* n1,*n2,*n3;
   n1=NULL;
   n2=head;
   n3=head->next;
   while(n2){
    n2->next=n1;
    n1=n2;
    n2=n3;
    if(n3){
        n3=n3->next;
    }
   }
   return n1;
}

 1.3 单链表相关经典算法OJ题3:合并两个有序链表

. - 力扣(LeetCode). - 备战技术面试?力扣提供海量技术面试资源,帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。icon-default.png?t=N7T8https://leetcode.cn/problems/merge-two-sorted-lists/先处理特殊情况假如list1==NULL就返回list2,假如list2为空就返回list1,定义两个结构体指针newhead和newtail并创建一个头节点,定义两个结构体指针l1,l2来指向list1和list2,遍历l1和l2都不为空,题目要求升序,如果l1小于l2,就newtail->next=l1,newtail到等于l1,l1移到下一位。遍历由于&& l1和l2都有可能为空判假,所以进行判断如果l1不为空就再尾插l1,否则就尾插l2.最后返回newhead的下一位,因为newhead为头节点。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
 typedef struct ListNode ListNode;
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2) {
    if(list1==NULL){
        return list2;
    }
    if(list2==NULL){
        return list1;
    }
    ListNode* newhead,*newtail;
    newhead=newtail=(ListNode*)malloc(sizeof(ListNode));
    ListNode*l1,*l2;
    l1=list1;
    l2=list2;
    while(l1&&l2){
        if(l1->val<l2->val){
            newtail->next=l1;
            newtail=newtail->next;
            l1=l1->next;
        }
        else{
            newtail->next=l2;
            newtail=newtail->next;
            l2=l2->next;
        }
    }
    if(l1){
        newtail->next=l1;
    }
    if(l2){
        newtail->next=l2;
    }
    ListNode* ret=newhead->next;
    free(newhead);
    newhead=newtail=NULL;
    return ret;
}

1.4 单链表相关经典算法OJ题4:链表的中间结点

. - 力扣(LeetCode). - 备战技术面试?力扣提供海量技术面试资源,帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。icon-default.png?t=N7T8https://leetcode.cn/problems/middle-of-the-linked-list/定义两个结构体指针,slow=fast=head,写一个循环遍历fast和fast->next都不为空,slow走一步,fast走两步。返回slow为链表的中间结点

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
typedef struct ListNode ListNode;
struct ListNode* middleNode(struct ListNode* head) {
    ListNode * slow,*fast;
    slow=fast=head;
    while(fast&&fast->next){
        slow=slow->next;
        fast=fast->next;
    }
    return slow;
}

 1.5 循环链表经典应⽤-环形链表的约瑟夫问题

环形链表的约瑟夫问题_牛客题霸_牛客网编号为 1 到 n 的 n 个人围成一圈。从编号为 1 的人开始报数,报到 m 的人离开。。题目来自【牛客题霸】icon-default.png?t=N7T8https://www.nowcoder.com/practice/41c399fdb6004b31a6cbb047c641ed8a

 创建一个节点,写一个函数来组成循环链表,当pcur->next=pcur时链表中有且仅有一个人,创建一个变量count来计数,当count==m时的那个人就离开,否则就继续遍历,最后返回这个人的编号数。

/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 * 
 * @param n int整型 
 * @param m int整型 
 * @return int整型
 */
 typedef struct ListNode ListNode;
 ListNode* BuyNode(int x){
    ListNode* newnode=(ListNode*)malloc(sizeof(ListNode));
    newnode->val=x;
    newnode->next=NULL;
    return newnode;
 }
 ListNode*createlist(int n){
    ListNode*phead=BuyNode(1);
    ListNode*ptail=phead;
    for(int i=2;i<=n;i++){
        ptail->next=BuyNode(i);
        ptail=ptail->next;
    }
    ptail->next=phead;
    return ptail;
 }
int ysf(int n, int m ) {
    // write code here
    ListNode*prev=createlist(n);
    ListNode*pcur=prev->next;
    int count=1;
    while(pcur->next!=pcur){
        if(count==m){
            prev->next=pcur->next;
            free(pcur);
            pcur=prev->next;
            count=1;
        }
        else{
            prev=pcur;
            pcur=pcur->next;
            count++;
        }
    }
    return pcur->val;
}

评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值