- 删除链表中的节点
- 大喜! 虽然很简单这道题,但是对于用c写的我,需要自己造东西,不看资料写出了虚拟头结点,开心 但是maybe只是凑巧加油!
- e 现在是24日的0:46 睡觉 明天补 这几天在干综测 又是班委 害`
-
struct ListNode* removeElements(struct ListNode* head, int val){ typedef struct ListNode ListNode; ListNode *shead; shead = (ListNode*)malloc(sizeof(ListNode)); shead->next = head; ListNode *cur = shead; while (cur->next) { if (cur->next->val == val) { ListNode* temp = cur->next; cur->next = cur->next->next; free(temp); } else { cur = cur->next; } } head = shead->next; free(shead); return head; }- 可以见得 上面我们使用了虚拟头结点 为什么要使用这个东西呢
- 如果直接对head操作, 那么我们就需要对head->val == val 时 特殊操作一个while 可是如果够早了虚拟头结点 那么我们就可以直接以一套方法处理整个链表
- 其次 我们使用了一个typedef的东西,这是一个给别人起小名的方法,比如你叫张李王防守打法水电费防守打法,但是我给你起个小名叫小张。typedef struct ListNode ListNode; 橙色的是原名 绿色的是小名
- 此外 我们也使用了free(temp);这个东西,将不符合的节点删除掉,虽然在我们简单地额程序中删不删无所谓,但是对于大型程序,不删很有可能造成内存泄露。所以我们培养好习惯删掉。 删除步骤,新构造一个 listNode* temp = cur->next; free(temp);
- 可以见得 上面我们使用了虚拟头结点 为什么要使用这个东西呢
- l链表的基本操作:
-
MyLinkedList *cur = obj->next; 直接赋值有没有错呢
-
无意外的 简答题叠加在一块就会出现各种各样的错, 太令人不开心啦错 错误代码:
-
typedef struct { int val; struct MyLinkedList* next; } MyLinkedList; MyLinkedList* myLinkedListCreate() { MyLinkedList* head; head = (MyLinkedList*)malloc(sizeof(MyLinkedList)); head->next = NULL; return head; } int myLinkedListGet(MyLinkedList* obj, int index) { MyLinkedList* cur; cur = obj->next; int i = 0; while (i != index && cur != NULL) { cur = cur->next; i++; } if (cur != NULL) return cur->val; else return -1; } void myLinkedListAddAtHead(MyLinkedList* obj, int val) { MyLinkedList* cur = (MyLinkedList*)malloc(sizeof(MyLinkedList)); cur->val = val; cur->next = obj->next; obj->next = cur; } void myLinkedListAddAtTail(MyLinkedList* obj, int val) { MyLinkedList* cur = (MyLinkedList*)malloc(sizeof(MyLinkedList)); cur = obj->next; cur->next = NULL; MyLinkedList* temp = (MyLinkedList*)malloc(sizeof(MyLinkedList)); temp->val = val; while (cur->next) { cur = cur->next; } cur->next = temp; } void myLinkedListAddAtIndex(MyLinkedList* obj, int index, int val) { if (index == 0) { myLinkedListAddAtHead(obj, val); return ; } MyLinkedList* cur = (MyLinkedList*)malloc(sizeof(MyLinkedList)); cur = obj->next; MyLinkedList* temp = (MyLinkedList*)malloc(sizeof(MyLinkedList)); temp->val = val; for (int i = 0; i < index - 1; i++) { cur = cur->next; } temp->next = cur->next; cur->next = temp; } void myLinkedListDeleteAtIndex(MyLinkedList* obj, int index) { MyLinkedList* cur = (MyLinkedList*)malloc(sizeof(MyLinkedList)); obj->next = cur; for (int i = 1; i < index && cur != NULL; i++) { cur = cur->next; } if (cur == NULL) return; else cur->next = cur->next->next; } void myLinkedListFree(MyLinkedList* obj) { while (obj != NULL) { MyLinkedList* temp = obj; obj = obj->next; free(temp); } }正确代码:
typedef struct { int val; struct MyLinkedList* next; } MyLinkedList; MyLinkedList* myLinkedListCreate() { MyLinkedList *head = (MyLinkedList *)malloc(sizeof (MyLinkedList)); head->next = NULL; return head; } int myLinkedListGet(MyLinkedList* obj, int index) { MyLinkedList *cur = obj->next; for (int i = 0; cur != NULL; i++) { if (i == index) { return cur->val; } else { cur = cur->next; } } return -1; } void myLinkedListAddAtHead(MyLinkedList* obj, int val) { MyLinkedList *nhead = (MyLinkedList*) malloc(sizeof(MyLinkedList)); nhead->val = val; nhead -> next = obj -> next; obj->next = nhead; } void myLinkedListAddAtTail(MyLinkedList* obj, int val) { MyLinkedList *tail = (MyLinkedList*) malloc(sizeof(MyLinkedList)); tail->val = val; tail->next = NULL; MyLinkedList *cur = obj; while (cur->next != NULL) { cur = cur->next; } cur->next = tail; } void myLinkedListAddAtIndex(MyLinkedList* obj, int index, int val) { MyLinkedList *middle = (MyLinkedList*)malloc(sizeof(MyLinkedList)); middle->val = val; if (index == 0) { myLinkedListAddAtHead(obj,val); return ; } MyLinkedList *cur = obj->next; for (int i = 1; cur != NULL; i++) { if (i == index) { middle->next = cur->next; cur->next = middle; return ; } else { cur = cur->next; } } } void myLinkedListDeleteAtIndex(MyLinkedList* obj, int index) { if (index == 0) { MyLinkedList *tmp = obj->next; if(tmp != NULL) { obj->next = tmp->next; free(tmp); } } MyLinkedList *cur = obj->next; for (int i = 1; cur != NULL && cur->next != NULL; i++) { if (i == index) { MyLinkedList *tmp; tmp = cur->next; cur->next = tmp->next; free(tmp); return ; } else { cur = cur->next; } } } void myLinkedListFree(MyLinkedList* obj) { while (obj != NULL) { MyLinkedList *tmp = obj; obj = obj->next; free(tmp); } }- 计数怎么计? obj->next 也就是真正的头结点是我们的第一个(0)结点
- 结构内指针域的定义方式: struct MyListNode* next;
-
- 翻转链表:
- 链表是一刷是重点内容 所以翻转其实还不错
- 唯一的缺点就是 ; 对于边界问题考虑不足,比如head 是空的时候,我们直接返回就可以 ,而不是继续一堆操作
- 另外 还有个问题就是 我什么时候需要对创建的结构体指针进行动态分配 什么时候不需要呢 answer :
- 1如果需要多添加一个节点来存储这个数据,然后放到链表中的时候,需要申请内存。
- 2如果只需要一个指针 来找链表中的某个位置,就不需要申请,只需要定义一个变量,指向某个空间的位置。
-
struct ListNode* reverseList (struct ListNode* head) { if (head == NULL) return NULL; struct ListNode* cur ; cur = head->next; struct ListNode* temp; struct ListNode* pre; pre = head; pre->next = NULL; while (cur) { temp = cur->next; cur->next = pre; pre = cur; cur = temp; } return pre; }
-
-
不断成长!加油
本文介绍了链表操作的基本技巧,包括如何使用虚拟头结点简化删除操作,以及typedef的作用。同时展示了链表节点删除、添加、查找和翻转的实现,并强调了内存管理的重要性,提醒开发者养成良好的内存释放习惯。此外,还讨论了代码中可能存在的边界问题和优化点。
143

被折叠的 条评论
为什么被折叠?



