一个 while 实现 C 翻转单向链表

听说这是 O(1) 空间复杂度 O(n) 时间复杂度 ?有大神解释下下面这个算吗?


struct MyLink {
    MyLink* next;
    int nVal;
};


MyLink* genLink(MyLink* next,int nval){
    MyLink* tmp = new MyLink;
    tmp->nVal = nval;
    tmp->next = next;
    return tmp;
}


MyLink* reverseLink(MyLink* begin){
    MyLink* tmp = nullptr;
    while (begin){
        auto top = begin->next;
        begin->next = tmp;
        tmp = begin;
        begin = top;
    }
    return tmp;
}

void printLink(MyLink* begin,const char* prfix){
    while (begin){
        printf("%s val:%d\n", prfix, begin->nVal);
        begin = begin->next;
    }
}

int _tmain(int argc, _TCHAR* argv[])
{
    MyLink*head = nullptr;
    for (auto i = 0; i < 5; i++){
        head = genLink(head, i);
    }
    printLink(head,"orglink ");
    head = reverseLink(head);
    printLink(head,"reversed link ");

    while (head){
        auto tmp = head->next;
        delete head;
        head = tmp;
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
假设我们有两个单向链表A和B,它们分别表示两个集合。现在我们要求出集合A与集合B的差集,也就是只在A中出现而不在B中出现的元素。 我们可以遍历链表A,对于每个节点,判断它是否在链表B中出现过。如果出现过,则将该节点从链表A中删除。最后返回链表A即可。 下面是C语言实现的代码: ``` #include <stdio.h> #include <stdlib.h> // 定义节点结构体 typedef struct node { int data; struct node* next; } Node; // 创建新节点 Node* createNode(int data) { Node* newNode = (Node*)malloc(sizeof(Node)); newNode->data = data; newNode->next = NULL; return newNode; } // 添加节点到链表末尾 void append(Node** headRef, int data) { Node* newNode = createNode(data); if (*headRef == NULL) { *headRef = newNode; return; } Node* tail = *headRef; while (tail->next != NULL) { tail = tail->next; } tail->next = newNode; } // 从链表中删除给定节点 void deleteNode(Node** headRef, Node* nodeToDelete) { if (*headRef == NULL) { return; } if (*headRef == nodeToDelete) { *headRef = nodeToDelete->next; free(nodeToDelete); return; } Node* prev = *headRef; while (prev->next != NULL && prev->next != nodeToDelete) { prev = prev->next; } if (prev->next == NULL) { return; } prev->next = nodeToDelete->next; free(nodeToDelete); } // 从链表A中删除在B中出现过的节点 void subtract(Node** headA, Node* headB) { Node* currA = *headA; while (currA != NULL) { Node* currB = headB; while (currB != NULL && currB->data != currA->data) { currB = currB->next; } if (currB != NULL) { deleteNode(headA, currA); currA = *headA; } else { currA = currA->next; } } } // 打印链表 void printList(Node* head) { Node* curr = head; while (curr != NULL) { printf("%d ", curr->data); curr = curr->next; } printf("\n"); } int main() { // 创建链表A Node* headA = NULL; append(&headA, 1); append(&headA, 2); append(&headA, 3); append(&headA, 4); append(&headA, 5); // 创建链表B Node* headB = NULL; append(&headB, 3); append(&headB, 4); // 求差集 subtract(&headA, headB); // 打印结果 printList(headA); return 0; } ``` 上述代码中,我们定义了一个节点结构体,包含一个整型数据和一个指向下一个节点的指针。我们还定义了一些操作链表的函数,如创建新节点、添加节点到链表末尾、删除节点等。最后,我们在主函数中创建了两个链表A和B,然后调用subtract函数求它们的差集,最后打印结果。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值