算法练习第三天||移除链表元素||设计链表||反转链表

203.移除链表元素

思路:设计一个虚拟头结点L,方便我们进行操作,其指针域指向首元节点,设置结点指针变量tmp,根据题目条件删除符合要求的结点,链表方便我们进行修改和删除结点,最后返回值要注意返回的是L->next,因为我们的修改指针都是基于L实现的,返回head会导致出现一些错误,因为我们并没有释放这些存储空间,head指向位置依旧存储信息,所以我们要返回L->next。

时间复杂度:O(n)

空间复杂度:O(1)

来看下非递归代码

struct ListNode* removeElements(struct ListNode* head, int val){
    struct ListNode* L = malloc(sizeof(struct ListNode));//设置头节点
    L->next = head;//指针域指向首元节点
    struct ListNode* tmp = L;
    while(tmp->next!=NULL){
        if(tmp->next->val==val){
            tmp->next = tmp->next->next;
        }
        else{
            tmp = tmp->next;
        }
    }
    return L->next;

}

再看下递归写法代码

struct ListNode* removeElements(struct ListNode* head, int val){
    if(head == NULL){
         return NULL;
    }
    head->next = removeElements(head->next, val);
    return head->val == val? head->next:head;
}

707.设计链表

思路:在这里我们实现的是单向非循环链表,设置头结点方便操作统一,所有的操作都是基于此实现的,代码段和注释如下。

//链表结点结构体定义
typedef struct {
    int val;
    struct MyLinkedList* next;
} MyLinkedList;

//创建链表,返回链表头指针
MyLinkedList* myLinkedListCreate() {
    MyLinkedList* L = (MyLinkedList*)malloc(sizeof(MyLinkedList));
    if(!L){
        return NULL;
    }
    L->next = NULL;
    return L;
}
//找到指定index的元素结点值
int myLinkedListGet(MyLinkedList* obj, int index) {
    int val = -1;
    int j = 0;
    MyLinkedList* p = obj->next;
    while(p != NULL && j < index){
        p = p->next;
        j++;
    }
    if(p){
        val = p->val;
        return val;
    }
    else{
        return val;
    }
}

//头插法插入结点
void myLinkedListAddAtHead(MyLinkedList* obj, int val) {
    MyLinkedList* pnew = (MyLinkedList*)malloc(sizeof(MyLinkedList));
    pnew->val = val;
    pnew->next = obj->next;
    obj->next = pnew;
    return;
}

//尾插法插入结点
void myLinkedListAddAtTail(MyLinkedList* obj, int val) {
    MyLinkedList* pnew = (MyLinkedList*)malloc(sizeof(MyLinkedList));
    pnew->val = val;
    MyLinkedList* p = obj;
    while(p->next != NULL){
        p = p->next;
    }
    p->next = pnew;
    pnew->next = NULL;
    return;
}

//在指定下标结点前增添结点
void myLinkedListAddAtIndex(MyLinkedList* obj, int index, int val) {
    if (index <= 0){
        //下标小于零,相当于头插法插入结点
        //直接调用函数
        myLinkedListAddAtHead(obj, val);
        return;
    }
    int j = 1;
    MyLinkedList* pnew = (MyLinkedList*)malloc(sizeof(MyLinkedList));
    MyLinkedList* p = obj;
    while(p->next && j < index){
        p = p->next;
        j++;
    }
    if(p->next != NULL){
        p = p->next;
        pnew->next = p->next;
        pnew->val = val;
        p->next = pnew;
        return;
    }
    else{
        return;
    }
    
}

//删除指定下标的元素
void myLinkedListDeleteAtIndex(MyLinkedList* obj, int index) {
    if(index == 0){
        MyLinkedList* tmp = obj->next;
        if(tmp != NULL){
            obj->next = tmp->next;
            free(tmp);
        }
        return;
    }
    MyLinkedList* cur = obj->next;
    MyLinkedList* del = obj->next;
    int j = 0;
    while(j < index-1 && cur != NULL){
        j++;
        cur = cur->next;
        del = del->next;
    }
    if(del != NULL && del->next != NULL){
        del = del->next;
        cur->next = del->next;
        free(del);
    }
    return;
}

//释放链表
void myLinkedListFree(MyLinkedList* obj) {
    while(obj!=NULL){
        MyLinkedList* tmp = obj;
        obj = obj->next;
        free(tmp);
    }
}

206.反转链表

思路:利用两个指针,不断修改链表结点的指针域即可,最后将head指针域置为空指针,返回最后一个结点位置即可。

非递归:

时间复杂度:O(n)

空间复杂度:O(1)

递归:

时间复杂度:O(n)

空间复杂度:O(n)

看下非递归解法代码

struct ListNode* reverseList(struct ListNode* head){
    struct ListNode* L = (struct ListNode*)malloc(sizeof(struct ListNode));
    L->next = head;
    struct ListNode* pl = L;
    struct ListNode* pr = L->next;
    struct ListNode* tmp = NULL;
    if(!head){
        return NULL;
    }
    while(pr){
        tmp = pr->next;
        pr->next = pl;
        pl = pr;
        pr = tmp;
    }
    head->next = NULL;
    return pl;
}

递归解法代码

struct ListNode* reverseList(struct ListNode* head) {
    if (head == NULL || head->next == NULL) {
        return head;
    }
    struct ListNode* ntail = reverseList(head->next);
    head->next->next = head;
    head->next = NULL;
    return ntail;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值