0
点赞
收藏
分享

微信扫一扫

数据结构4:基于单链表的通讯录项目

心存浪漫 2024-04-17 阅读 9
算法

目录

一、链表的中间节点

1.1 题目

1.2 题解

1.3 收获

二、移除链表元素

2.1 题目

2.2 题解

2.3 收获

2.4递归详解

三、反转链表

3.1 题目

3.2 题解

3.3 解释

四、合并两个有序列表

4.1 题目

4.2 题解

4.3 递归详解


声明:本文所有题目均摘自leetcode

一、链表的中间节点

1.1 题目

1.2 题解

struct ListNode* middleNode(struct ListNode* head) {
struct ListNode* slow=head;
struct ListNode* fast=head;
while(fast!=NULL&&fast->next!=NULL)
{
fast=fast->next->next;
slow=slow->next;
}
return slow;
}

1.3 收获

  • 快慢指针的用法:
  • 链表长度为奇数: 当快指针走到尾节点时,慢指针正好走到中间节点。
  • 链表长度为偶数: 当快指针走到NULL时,慢指针正好走到第二个中间节点。

二、移除链表元素

2.1 题目

2.2 题解

//创建虚拟节点法
struct ListNode* removeElements1(struct ListNode* head, int val) {
struct ListNode* dummyHead = malloc(sizeof(struct ListNode));
dummyHead->next = head;
struct ListNode* temp = dummyHead;
while (temp->next != NULL) {
if (temp->next->val == val) {
temp->next = temp->next->next;
}
else {
temp = temp->next;
}
}
return dummyHead->next;
}
//创建新链表法
struct ListNode* removeElements3(struct ListNode* head, int val) {
struct ListNode* phead = NULL;
struct ListNode* ptail = NULL;

struct ListNode* pcur = head;
while (pcur) {
if (pcur->val != val) {
if (phead == NULL) {
phead = ptail = pcur;
}
else {
ptail->next = pcur;
ptail = ptail->next;
}
}
pcur = pcur->next;
}
if (phead) {
ptail->next = NULL;
}
return phead;
}
//双指针法
struct ListNode* removeElements(struct ListNode* head, int val) {
while (NULL != head && head->val == val) {
head = head->next;
}
struct ListNode* pcur = head;
struct ListNode* prev = head;
while (pcur)
{
if (pcur->val != val)
{
prev = pcur;
}
else
{
prev->next = pcur->next;
}
pcur = pcur->next;
}
return head;
}
//递归做法
struct ListNode* removeElements2(struct ListNode* head, int val) {
if (head == NULL) {
return head;
}
head->next = removeElements(head->next, val);
if (head->val == val)
{
return head->next;
}
else
{
return head;
}
}

2.3 收获

  • 创建虚拟头节点:好处是可以只维护一个指针
  • 创建新链表法:思路简单:仅仅为挑选符合条件的数据复制即可
  • 双指针法:保存前一个链表的指针

2.4递归详解

  • 停止条件:当遍历链表的指针为空时。
  • 如何递归:判断节点值是否等于给定值,并决定是否要删除。

三、反转链表

3.1 题目

3.2 题解

struct ListNode* reverseList(struct ListNode* head) {
if (head == NULL) {
return head;
}
struct ListNode* a = NULL;
struct ListNode* b = head;
struct ListNode* c = head->next;

while (b) {
b->next = a;
a = b;
b = c;
if (c) {
c = c->next;
}
}
return a;
}

3.3 解释

三指针法:循环保留三个指针,修改朝向即可;

四、合并两个有序列表

4.1 题目

4.2 题解

 //创建新链表法
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2) {
if (list1 == NULL)
{
return list2;
}
if (list2 == NULL)
{
return list1;
}
if (list1 == NULL && list2 == NULL)
{
return NULL;
}
struct ListNode* l1 = list1;
struct ListNode* l2 = list2;
struct ListNode* newhead;
struct ListNode* newtail;
newhead = 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 (l1 == NULL NULL)
{
newtail->next = l2;
while (l2->next)
{
l2 = l2->next;
}
newtail = l2;
}
if (l2 == NULL NULL)
{
newtail->next = l1;
while (l1->next)
{
l1 = l1->next;
}
newtail = l1;
}
return newhead;
}
//递归
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2) {
struct ListNode* l1 = list1;
struct ListNode* l2 = list2;
if (l1 == NULL) {
return l2;
}
if (l2 == NULL) {
return l1;
}
if (list1 == NULL && list2 == NULL)
{
return NULL;
}
if (l1->val <= l2->val) {
l1->next = mergeTwoLists(l1->next, l2);
return l1;
}
l2->next = mergeTwoLists(l1, l2->next);
return l2;
}

4.3 递归详解

  • 停止条件:当两个链表都为空时。
  • 如何递归:我们判断两个头结点哪个更小,然后较小结点的 next 指针指向其余结点。
举报

相关推荐

0 条评论