当前位置: 首页 > ai >正文

数据结构与算法-单链表的应用

一. 移除链表元素

函数实现+解析:

/*** 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,*newTail;newHead=newTail=NULL;ListNode*pcur=head;while(pcur)//遍历{if(pcur->val!=val)//不是val的节点{if(newHead==NULL)//空链表,也就是刚开始王空链表放节点{newHead=newTail=pcur;}else//不是空链表,往单链表中尾插节点{newTail->next=pcur;newTail=pcur;}}pcur=pcur->next;//遍历,一次过后往后移}if(newTail)//判断是否为空,为空就不能进行解引用newTail->next=NULL;//因为尾节点既有数据也有指向下一个节点的指针,所以如果不将其NULL化,那么原先单链表的尾节点还是不会变。return newHead;
}

二. 反转链表

思路:

运用三个指针,n1,n2,n3,n1是空指针,n2初始化为头节点地址,n3初始化为n2的下一个节点,然后将n2的next指向n1,n2再往后挪到下一个节点,也就是n3指向的节点,然后n3再等于n2的next指向的节点,以此类推就可以使得单链表反转,最后循环判断条件的n2是否为空指针。

函数实现:

/*** 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=NULL;ListNode*n2=head;ListNode*n3=n2->next;//正式开始while(n2){n2->next=n1;n1=n2;n2=n3;if(n3)n3=n2->next;}return n1;
}

三. 寻找单链表中间节点

思路:

1.遍历一边,用count++计数,然后进行半遍历找到中间节点,还要区分奇偶数的条件

2.快慢指针,slow和fast进行一次遍历就好。

函数实现:(思路2)

//寻找单链表的中间节点
//如果是偶数,则会返回第二个一样的节点
//这是非常好用的快慢指针的运用
/*** Definition for singly-linked list.* struct ListNode {*     int val;*     struct ListNode *next;* };*/
typedef struct ListNode ListNode;
struct ListNode* middleNode(struct ListNode* head) {ListNode* slow = head;ListNode* fast = head;while (fast && fast->next){slow = slow->next;fast = fast->next->next;}return slow;
}

四. 合并两个有序链表

函数思路:

创建一个空链表,两个单链表节点进行比较,谁小谁就放进空链表中然后继续往后比较直到结束。

函数实现:

/*** 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*l1 = list1;ListNode*l2 = list2;//创建空链表ListNode*newHead=NULL;ListNode*newTail=NULL;while(l1&&l2){if(l1->val<l2->val){if(newHead==NULL){newHead=newTail=l1;}else{newTail->next=l1;newTail=newTail->next;}l1=l1->next;}else{if(newHead==NULL){newHead=newTail=l2;}else{newTail->next=l2;newTail=newTail->next;}l2=l2->next;}}if(l2){newTail->next=l2;}if(l1){newTail->next=l1;}return newHead;}

函数优化:

(无需重复判断新创链表是否为空,不再创建空链表,直接malloc一块空间作为节点进行使用)

/*** 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*l1 = list1;ListNode*l2 = list2;//创建空链表ListNode*newHead,*newTail;newHead=newTail=(ListNode*)malloc(sizeof(ListNode));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(l2){newTail->next=l2;}if(l1){newTail->next=l1;}ListNode*ret=newHead->next;free(newHead);newHead=NULL;return ret;
}

这里实际使用了带头链表,创建的头节点可以称之为哨兵位

五. 环形链表的约瑟夫问题

函数实现:

/*** 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可** * @param n int整型 * @param m int整型 * @return int整型*/typedef struct ListNode ListNode;//创建节点ListNode*buyNode(int x){ListNode*newHead=(ListNode*)malloc(sizeof(ListNode));if(newHead==NULL){exit(1);}newHead->val=x;newHead->next=NULL;return newHead;}
//创建循环链表
ListNode*circle(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 ) {ListNode*prev=circle(n);ListNode*pcur=prev->next;int count = 1;while(pcur->next!=pcur){if(count!=m){prev=pcur;pcur=pcur->next;count++;}else{prev->next=pcur->next;free(pcur);pcur=prev->next;count=1;}}return pcur->val;
}

http://www.xdnf.cn/news/4435.html

相关文章:

  • C语言学习之字符函数和字符串函数
  • 【Python】让Selenium 像Beautifulsoup一样,用解析HTML 结构的方式提取元素!
  • Spark 之 YarnCoarseGrainedExecutorBackend
  • Linux基本操作——网络操作文件下载
  • 1、RocketMQ 核心架构拆解
  • $在R语言中的作用
  • mdadm 报错: buffer overflow detected
  • 数字电子技术基础(五十五)——D触发器
  • 5月13日观测云发布会:这一次,我们不只是发布产品
  • 项目改 pnpm 并使用 Monorepo 发布至 npm 上
  • ChatGPT-4o:临床医学科研与工作的创新引擎
  • SQL 子查询
  • 深入浅出理解常见的分布式ID解决方案
  • 理解网站导航文件:robots.txt、sitemap.xml与LLMs.txt的全面解析
  • 控制mac地址表端口安全
  • 前端面经-VUE3篇(四)--pinia篇-基本使用、store、state、getter、action、插件
  • 【免费】2003-2018年全国各地级市进出口总额数据
  • Nginx 性能调优与深度监测全攻略
  • AI——认知科学中的认知架构建立步骤与方法
  • 【Prometheus】业务指标与基础指标的标签来源差异及设计解析(扩展版)
  • oracle 数据库sql 语句处理过程
  • LeetCode 热题 100_最长回文子串(93_5_中等_C++)(暴力破解法;动态规划)
  • LLaMA-Factory微调DeepSeek-R1-Distill-Qwen-7B
  • 2025年数字藏品行业DDoS攻防指南:技术升级与合规防御双轨制
  • 【C++】类和对象【下】
  • MySQL 中的 MVCC 是什么?
  • SRAM详解
  • vscode 安装插件
  • 软件开发模型介绍
  • MATLAB制作直方图