刷算法题之链表专题

链表的定义:用一组任意的存储单元存储线性表的数据元素。
注意:存储单元可以是连续的,也可以是不连续的

链表的分类:
静态链表:
动态链表:

leetcode203

删除链表中的元素的时候,

c 复制代码
// 对原链表操作
struct ListNode* removeElements(struct ListNode* head, int val) {
    struct ListNode *tmp; // 存放临时节点,
    while( head != NULL && head->val == val) // 若链表中的元素 [1,1,1,1,1] 删除的头节点
    {
        tmp = head;
        head = head->next;
        free(tmp); // 要释放的元素
    }
    struct ListNode * curt = head; // 删除的元素并不会改变头节点
    while(curt != NULL && (tmp = curt->next))
    {  
        if(tmp->val == val) // 若cur->next的值等于val
        {  
            curt->next = tmp->next; // 改变链表的前驱, 将cur->next设置为cur->next->next并删除cur->next
            free(tmp);
        } 
        else 
        {
            curt = curt->next;
        } 
    }
    return head;
}

// 构造一个虚拟头节点
struct ListNode* removeElements(struct ListNode* head, int val) {
    struct ListNode* new_head= (struct ListNode*)malloc(sizeof(struct ListNode));
    new_head->next = head; // 为head构造一个虚拟节点的前驱节点
    struct ListNode *cur = new_head; // 将当前节点指向head
    while(cur->next != NULL)
    {
        if(cur->next->val == val)
        {
            struct ListNode *tmp = cur->next;
            cur->next = cur->next->next;
            free(tmp);
        }
        else
        {
            cur = cur->next;
        }
    }
    head = new_head->next;
    free(new_head);
    return head;
}

leetcode707

考察链表的基本的操作,增删改查。

c 复制代码
typedef struct Node{
    int data;
    struct LNode *lnext;
}LNode;

typedef struct {
    int val;
    LNode *next;
} MyLinkedList;



MyLinkedList* myLinkedListCreate() {
    MyLinkedList *obj = (MyLinkedList *)malloc(sizeof(MyLinkedList));
    LNode *head = (LNode *)malloc(sizeof(LNode));
    if (!obj || !head)
    {
        return -1; // 分配空间失败 直接退出
    }
    head->lnext = NULL;
    obj->next = head;
    obj->val = 0;
    return obj;
}


int myLinkedListGet(MyLinkedList* obj, int index) {
    if (index < 0 || index >= obj->val) 
    {
        return -1;
    }
    LNode *cur = obj->next;
    while(index-- >= 0)
    {
        cur = cur->lnext;
    }
    return cur->data;
}

void myLinkedListAddAtHead(MyLinkedList* obj, int val) {
    LNode *node = (LNode *)malloc(sizeof(LNode));
    node->data = val;
    node->lnext = obj->next->lnext;
    obj->next->lnext = node;
    obj->val ++;
    
}

void myLinkedListAddAtTail(MyLinkedList* obj, int val) {
    LNode * cur = obj->next;
    while(cur->lnext != NULL)
    {
        cur = cur->lnext;
    }
    LNode * temp = (LNode *)malloc(sizeof(LNode));
    temp->data = val;
    temp->lnext = NULL;;
    cur->lnext = temp;
    obj->val++;
}

void myLinkedListAddAtIndex(MyLinkedList* obj, int index, int val) {
    if(index > obj->val) 
    {
        return;
    }
    LNode * cur = obj->next;
    while(index-- > 0)
    {
        cur = cur->lnext;
    }
    LNode * temp = (LNode *)malloc(sizeof(LNode)); // 为插入的节点开辟空间
    temp->data = val;
    temp->lnext = cur->lnext;
    cur->lnext = temp;
    obj->val++;
}

void myLinkedListDeleteAtIndex(MyLinkedList* obj, int index) {
    if(index < 0 || index >= obj->val)
    {
        return;
    }
    LNode *cur = obj->next;
    while(index-- > 0) 
    {
        cur = cur->lnext;
    }
    LNode * temp = cur->lnext;
    cur->lnext = temp->lnext;
    free(temp);
    obj->val--;
}

void myLinkedListFree(MyLinkedList* obj) {
    LNode *tmp = obj->next;
    while(tmp != NULL)
    {
        LNode *n = tmp;
        tmp = tmp->lnext;
        free(n); 
    }
    free(obj);
}

/**
 * Your MyLinkedList struct will be instantiated and called as such:
 * MyLinkedList* obj = myLinkedListCreate();
 * int param_1 = myLinkedListGet(obj, index);
 
 * myLinkedListAddAtHead(obj, val);
 
 * myLinkedListAddAtTail(obj, val);
 
 * myLinkedListAddAtIndex(obj, index, val);
 
 * myLinkedListDeleteAtIndex(obj, index);
 
 * myLinkedListFree(obj);
*/

leetcode206

链表反转:头变尾,尾变头

思路:使用双指针处理这道题

c 复制代码
struct ListNode* reverseList(struct ListNode* head) {
    struct ListNode *cur = head; //保存cur的下一个结点
    struct ListNode *temp; // 中间变量
    struct ListNode *pre = NULL; // /pre指针指向前一个当前结点的前一个结点
    while( cur != NULL)
    {
        temp = cur->next;    //保存下一个结点的位置
        cur->next = pre; //翻转操作
        pre = cur; //更新结点
        cur = temp;
    }
    return pre; // 
}

// 递归解法
struct ListNode *reverse(struct ListNode *pre, struct ListNode *cur)
{
	// 遍历的终止条件
	if(cur == NULL)
	{
		return pre;
	}
	struct ListNode *temp = curt->next;
	curt->next = pre;
	return reverse(cur, temp);
}
struct ListNode *reverseList(struct ListNode *head)
{
	return reverse(NULL, head);
}
相关推荐
知来者逆25 分钟前
计算机视觉——速度与精度的完美结合的实时目标检测算法RF-DETR详解
图像处理·人工智能·深度学习·算法·目标检测·计算机视觉·rf-detr
阿让啊30 分钟前
C语言中操作字节的某一位
c语言·开发语言·数据结构·单片机·算法
এ᭄画画的北北30 分钟前
力扣-160.相交链表
算法·leetcode·链表
爱研究的小陈1 小时前
Day 3:数学基础回顾——线性代数与概率论在AI中的核心作用
算法
渭雨轻尘_学习计算机ing1 小时前
二叉树的最大宽度计算
算法·面试
BB_CC_DD2 小时前
四. 以Annoy算法建树的方式聚类清洗图像数据集,一次建树,无限次聚类搜索,提升聚类搜索效率。(附完整代码)
深度学习·算法·聚类
梁下轻语的秋缘3 小时前
每日c/c++题 备战蓝桥杯 ([洛谷 P1226] 快速幂求模题解)
c++·算法·蓝桥杯
CODE_RabbitV3 小时前
【深度强化学习 DRL 快速实践】逆向强化学习算法 (IRL)
算法
mit6.8244 小时前
[贪心_7] 最优除法 | 跳跃游戏 II | 加油站
数据结构·算法·leetcode
keep intensify4 小时前
通讯录完善版本(详细讲解+源码)
c语言·开发语言·数据结构·算法