刷算法题之链表专题

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

leetcode203

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

// 对原链表操作
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
考察链表的基本的操作,增删改查。

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
链表反转:头变尾,尾变头
思路:使用双指针处理这道题

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);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

可厉害的土豆

你的鼓励是我创作的源泉

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值