二 链表
-
// 单链表 struct ListNode { int val; // 节点上存储的元素 ListNode *next; // 指向下一个节点的指针 ListNode(int x) : val(x), next(NULL) {} // 节点的构造函数 };
203. 移除链表元素
-
设置虚拟头结点,统一操作
-
ListNode* removeElements(ListNode* head, int val) { if(head == nullptr) { return head; } ListNode* vhead = new ListNode(0,head); ListNode* cur = vhead; //遍历指针 while( cur->next != nullptr) //cur是从虚拟头结点开始的 用while更好一些 { if( cur->next -> val == val ) { ListNode * tmp = cur->next; cur->next = cur->next->next; delete tmp; //删除节点要delete }else{ cur = cur->next; } } head = vhead->next; delete vhead; return head; }
707. 设计链表
-
你可以选择使用单链表或者双链表,设计并实现自己的链表。
单链表中的节点应该具备两个属性:
val
和next
。val
是当前节点的值,next
是指向下一个节点的指针/引用。如果是双向链表,则还需要属性
prev
以指示链表中的上一个节点。假设链表中的所有节点下标从 0 开始。实现
MyLinkedList
类:-
MyLinkedList()
初始化MyLinkedList
对象。 -
int get(int index)
获取链表中下标为index
的节点的值。如果下标无效,则返回-1
。 -
void addAtHead(int val)
将一个值为val
的节点插入到链表中第一个元素之前。在插入完成后,新节点会成为链表的第一个节点。 -
void addAtTail(int val)
将一个值为val
的节点追加到链表中作为链表的最后一个元素。 -
void addAtIndex(int index, int val)
将一个值为val
的节点插入到链表中下标为index
的节点之前。如果index
等于链表的长度,那么该节点会被追加到链表的末尾。如果index
比长度更大,该节点将 不会插入 到链表中。 -
void deleteAtIndex(int index)
如果下标有效,则删除链表中下标为index
的节点。
-
-
class MyLinkedList { public: class listNode{ public: int val; listNode* next; listNode() : val(0), next(nullptr) {} listNode(int x) : val(x), next(nullptr) {} listNode(int x,listNode*next) : val(x), next(next) {} }; MyLinkedList():_size(0),vhead(new listNode()) { } int get(int index) { //下标 if(index >= _size || index < 0) { return -1; } listNode *p = vhead->next; while(index--) { p = p->next; } return p->val; } void addAtHead(int val) { listNode * temp = new listNode(val); temp->next = vhead->next; vhead->next = temp; _size++; } void addAtTail(int val) { listNode * p = vhead; listNode*temp = new listNode(val); while(p->next != nullptr) { p = p->next; } p->next = temp; _size++; } void addAtIndex(int index, int val) { if(index > _size) { return; } listNode*p = vhead; listNode*temp = new listNode(val); while(index--) { p = p->next; } temp -> next = p->next; p->next = temp; _size++; } void deleteAtIndex(int index) { if(index >= _size || index < 0) { return ; } listNode*p = vhead; while(index--) { p = p->next; } listNode* temp = p->next; p->next = p->next->next; delete temp; _size--; //print(); } void print() { listNode *cur = vhead; while( cur->next != nullptr) { printf("%d ",cur->next->val); cur = cur->next; } printf("\n"); } private: listNode* vhead; listNode* vtail; int _size; };
-
当前指针cur一定要注意指向拿个
-
index表示下标,如果就是找那个下标,则
-
-
LinkedNode *cur = vhead->next; while(index--) { cur = cur->next; }
-
-
index表示下标,如果就是找那个下标前一个,则从头节点开始
-
LinkedNode *cur = vhead; while(index--) { cur = cur->next; }
-
206. 反转链表
-
给你单链表的头节点
head
,请你反转链表,并返回反转后的链表 -
ListNode* reverseList(ListNode* head) { ListNode *cur = head, *pre = nullptr; while(cur!=nullptr ){ ListNode *tmp=cur->next; cur->next=pre; pre=cur; cur=tmp; } return pre; }
-
注意要用三个指针变量,记录 pre cur next