刷算法题之链表专题

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

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

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);
}
相关推荐
Jasmine_llq19 分钟前
《 火星人 》
算法·青少年编程·c#
闻缺陷则喜何志丹30 分钟前
【C++动态规划 图论】3243. 新增道路查询后的最短距离 I|1567
c++·算法·动态规划·力扣·图论·最短路·路径
Lenyiin1 小时前
01.02、判定是否互为字符重排
算法·leetcode
鸽鸽程序猿1 小时前
【算法】【优选算法】宽搜(BFS)中队列的使用
算法·宽度优先·队列
Jackey_Song_Odd1 小时前
C语言 单向链表反转问题
c语言·数据结构·算法·链表
Watermelo6171 小时前
详解js柯里化原理及用法,探究柯里化在Redux Selector 的场景模拟、构建复杂的数据流管道、优化深度嵌套函数中的精妙应用
开发语言·前端·javascript·算法·数据挖掘·数据分析·ecmascript
乐之者v1 小时前
leetCode43.字符串相乘
java·数据结构·算法
A懿轩A2 小时前
C/C++ 数据结构与算法【数组】 数组详细解析【日常学习,考研必备】带图+详细代码
c语言·数据结构·c++·学习·考研·算法·数组
古希腊掌管学习的神2 小时前
[搜广推]王树森推荐系统——矩阵补充&最近邻查找
python·算法·机器学习·矩阵