刷算法题之链表专题

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

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

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);
}
相关推荐
serve the people几秒前
神经网络中梯度计算求和公式求导问题
神经网络·算法·机器学习
闻缺陷则喜何志丹6 分钟前
【二分查找、滑动窗口】P10389 [蓝桥杯 2024 省 A] 成绩统计|普及+
c++·算法·蓝桥杯·二分查找·滑动窗口·洛谷·成绩
乔冠宇1 小时前
蓝桥杯算法——铠甲合体
算法·职场和发展·蓝桥杯
商bol451 小时前
算阶,jdk和idea的安装
数据结构·c++·算法
迷迭所归处1 小时前
C语言 —— 愿文明如薪火般灿烂 - 函数递归
c语言·开发语言·算法
柠檬鲨_4 小时前
C语言100天练习题【记录本】
c语言·数据结构·算法
float_六七4 小时前
二叉树三种遍历方式——前序、中序、后序(C++)
开发语言·c++·算法
CYRUS_STUDIO9 小时前
常用加解密算法介绍
算法·安全·逆向
weixin_5358542211 小时前
快手,蓝禾,优博讯,三七互娱,顺丰,oppo,游卡,汤臣倍健,康冠科技,作业帮,高途教育25届春招内推
java·前端·python·算法·硬件工程
C_V_Better11 小时前
Java 导出 PDF 文件:从入门到实战
java·开发语言·算法·pdf