赞
踩
目录
题目链接:OJ链接
题目描述:
方法1:递归删除
情况1:不存在值的情况,返回一个空链表
情况2:头节点要删除,删除完继续返回新的头节点进行判断
情况3:不是情况1,2,不动原来的值,继续下一个节点的判断
最后返回头节点
- struct ListNode* removeElements(struct ListNode* head, int val)
- {
- // 不存在值的情况,链表为空
- if(head == NULL)
- {
- return NULL;
- }
- // 头节点的值是要删除的值的情况
- if(head->val == val)
- {
- // 新头节点指向下一个节点
- struct ListNode* newhead = head->next;
- // 释放原头节点的内存
- free(head);
- // 头节点赋值为新的头节点
- head = newhead;
-
- // 递归调用函数,去除剩余节点中的值为val的节点
- head = removeElements(head, val);
- }
- else
- {
- // 递归调用函数,去除剩余节点中的值为val的节点
- head->next = removeElements(head->next, val);
- }
- return head;
- }
方法2:连续尾插
先头尾节点置为空,然后传入pcur值,没有pcur值说明停止循环
当不是删除值时
链表为空,头尾节点都指向当前的节点。
链表不为空时,尾插pcur。
是删除值时,pcur走向下一个节点
当尾节点是要删除的值时(且要存在),pcur就不要往下走了,newtail->next=NULL.
- 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)
- {
- // 如果新链表的尾节点为空,表示新链表为空
- if(newtail == NULL)
- {
- // 新链表的头尾节点都指向当前节点
- newhead = newtail = pcur;
- }
- else
- {
- // 将当前节点添加到新链表的尾部
- newtail->next = pcur;
- newtail = newtail->next;
- }
- }
- // 指针指向下一个节点
- pcur = pcur->next;
- }
- // 如果新链表的尾节点不为空,将尾节点的next指针置为NULL
- if(newtail)
- {
- newtail->next = NULL;
- }
- // 返回新链表的头节点
- return newhead;
- }
题目链接:OJ链接
方法:快慢指针
慢指针每次走一步,快指针每次走两步
奇数时,快指针的下一个节点指向NULL时停止,返回慢指针此时位置
偶数时,快指针的节点指向NULL时停止,返回慢指针此时的位置
- typedef struct ListNode ListNode; // 定义结构体指针类型 ListNode
-
- struct ListNode* middleNode(struct ListNode* head)
- {
- ListNode* slow, * fast; // 定义慢指针 slow 和快指针 fast
- slow = fast = head; // 将慢指针和快指针都指向链表头部
-
- while (fast && fast->next) // 当快指针和快指针的下一个节点都不为空时
- {
- slow = slow->next; // 慢指针向后移动一步
- fast = fast->next->next; // 快指针向后移动两步
- }
-
- return slow; // 返回慢指针,即链表的中间节点
- }
注意:不要写成while(fast->next&&fast),因为如果fast为空指针,fast->next便不存在了。会报错
题目链接:OJ链接
创建三个指针
n1指向为空(NULL),n2指向第一个节点,n3指向下一个节点
如果n2不为空,n2节点的指针由指向n3改为指向n1
n1=n2,n2=n3,n3=n3->next
以此类推,直到n2不为空。
- typedef struct ListNode ListNode; // 定义一个别名为ListNode的结构体
-
- struct ListNode* reverseList(struct ListNode* head)
- {
- if(head==NULL) // 如果头节点为空,则直接返回头节点
- return head;
-
- ListNode* n1, *n2, *n3; // 定义三个指针n1、n2、n3
- n1 = NULL; // n1指向NULL,表示反转链表的最后一个节点
- n2 = head; // n2指向头节点
- n3 = head->next; // n3指向头节点的下一个节点
-
-
- while(n2)
- {
- n2->next = n1; // 将n2的next指针指向n1,实现反转
- n1 = n2; // 将n2赋值给n1,更新n1的位置
- n2 = n3; // 将n3赋值给n2,更新n2的位置
- if(n3)
- n3 = n3->next; // 如果n3不为空,则将n3指向n3的下一个节点
- }
-
- return n1; // 返回反转后的链表的头节点
- }
注意,n3为空就不用往下走了。
题目链接:OJ链接
- typedef struct ListNode ListNode;
- struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2)
- {
- if(list1==NULL)
- return list2;
- if(list2==NULL)
- return list1;
- ListNode*n1,*n2;
- n1=list1,n2=list2;
- ListNode*newhead,*newtail;
- newhead=newtail=NULL;
- while(n1&&n2)
- {
- if(n1->val<n2->val)
- {
- if(newhead==NULL)
- {
- // 如果新链表头为空,则将当前节点设为新链表头和新链表尾
- newhead=newtail=n1;
- }
- else
- {
- // 如果新链表头不为空,则将当前节点接在新链表尾后,并更新新链表尾
- newtail->next=n1;
- newtail=newtail->next;
- }
- n1=n1->next;
- }
- else
- {
- if(newhead==NULL)
- {
- // 如果新链表头为空,则将当前节点设为新链表头和新链表尾
- newhead=newtail=n2;
- }
- else
- {
- // 如果新链表头不为空,则将当前节点接在新链表尾后,并更新新链表尾
- newtail->next=n2;
- newtail=newtail->next;
- }
- n2=n2->next;
- }
- }
- if(n1)
- {
- // 如果list1还有剩余节点,则将剩余节点接在新链表尾后,并更新新链表尾
- newtail->next=n1;
- newtail=newtail->next;
- }
- if(n2)
- {
- // 如果list2还有剩余节点,则将剩余节点接在新链表尾后,并更新新链表尾
- newtail->next=n2;
- newtail=newtail->next;
- }
- return newhead;
- }
题目链接:环形链表的约瑟夫问题_牛客题霸_牛客网
方法:环形链表
创建一个环形链表,每个人对应一个节点,将对应的离开人数的节点释放掉,并且改边释放节点前后指针的指向,直到剩一人为止
- typedef struct ListNode ListNode; // 定义一个 ListNode 结构体的别名为 ListNode
- ListNode* BuyNode(int x) // 定义一个函数 BuyNode,用于创建一个新的节点并返回指向该节点的指针
- {
- ListNode*newnode=(ListNode*)malloc(sizeof(ListNode)); // 分配内存空间
- newnode->val=x; // 设置节点的值为 x
- newnode->next=NULL; // 下一个节点指针为空
- return newnode; // 返回指向新节点的指针
- }
- // 创建不带头环形链表
- ListNode*ctreatelist(int n)
- {
- ListNode*phead=BuyNode(1); // 创建头节点
- ListNode*ptail=phead; // 尾节点指向头节点
- for(int i=2;i<=n;i++) // 循环创建 n 个节点
- {
- ptail->next=BuyNode(i); // 创建新节点并连接到尾节点的下一个
- ptail=ptail->next; // 尾节点指向新创建的节点
- }
- ptail->next=phead; // 尾节点指向头节点,形成环形链表
- return phead; // 返回头节点指针
- }
- // 约瑟夫环问题
- int ysf(int n, int m ) {
- ListNode*head=ctreatelist(n); // 创建包含 n 个节点的环形链表
- ListNode*pcur=head; // 当前节点指针指向头节点
- ListNode*prev=NULL; // 前一个节点指针初始化为空
- int count=1; // 计数器初始化为 1
- while(pcur->next!=pcur) // 当链表中还有多于一个节点时循环
- {
- if(count==m) // 当计数器等于 m 时
- {
- // 删除当前节点
- prev->next=pcur->next; // 前一个节点的指针指向当前节点的下一个节点
- free(pcur); // 释放当前节点的内存空间
- pcur=prev->next; // 当前节点指针指向下一个节点
- count=1; // 计数器重置为 1
- }
- else
- {
- prev=pcur; // 前一个节点指针指向当前节点
- pcur=pcur->next; // 当前节点指针指向下一个节点
- count++; // 计数器加 1
- }
- }
- return pcur->val; // 返回最后剩下的节点的值
- }
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。