刷算法题之链表专题

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

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

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);
}
相关推荐
为什么这亚子1 小时前
九、Go语言快速入门之map
运维·开发语言·后端·算法·云原生·golang·云计算
1 小时前
开源竞争-数据驱动成长-11/05-大专生的思考
人工智能·笔记·学习·算法·机器学习
~yY…s<#>1 小时前
【刷题17】最小栈、栈的压入弹出、逆波兰表达式
c语言·数据结构·c++·算法·leetcode
幸运超级加倍~2 小时前
软件设计师-上午题-16 算法(4-5分)
笔记·算法
yannan201903132 小时前
【算法】(Python)动态规划
python·算法·动态规划
埃菲尔铁塔_CV算法2 小时前
人工智能图像算法:开启视觉新时代的钥匙
人工智能·算法
EasyCVR2 小时前
EHOME视频平台EasyCVR视频融合平台使用OBS进行RTMP推流,WebRTC播放出现抖动、卡顿如何解决?
人工智能·算法·ffmpeg·音视频·webrtc·监控视频接入
linsa_pursuer2 小时前
快乐数算法
算法·leetcode·职场和发展
小芒果_012 小时前
P11229 [CSP-J 2024] 小木棍
c++·算法·信息学奥赛
qq_434085902 小时前
Day 52 || 739. 每日温度 、 496.下一个更大元素 I 、503.下一个更大元素II
算法