链表
一、定义与方法
使用结构体
1 2 3 4 5 6
| struct ListNode { int val; ListNode *next; ListNode(int x): val(x), next(NULL) {} };
|
使用类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
| class LNode { public: int val; LNode *next;
LNode(int x) : val(x), next(nullptr) {} };
class LinkedList { private: LNode *head; public: LinkedList() : head(nullptr) {} void append(int data) { LNode *newNode = new LNode(data); if (head == nullptr){ LNode* dummyHead = new LNode(0); head=dummyHead; head->next= newNode; } else{ LNode *cur = head; while (cur->next!= nullptr) cur=cur->next; cur->next = newNode; } } void printList(){ LNode *cur = head->next; while(cur!=nullptr){ std::cout << cur->val; cur=cur->next; if(cur==nullptr) std::cout<< std::endl; else cout <<" "; } }
int len(){ LNode *cur = head->next; int n=0; while(cur!=nullptr){ cur=cur->next; n++; } return n; } void insert(int pos,int data){ if(pos>len()||pos<1) cout<<"Insertion position is invalid."<<endl; else{ LNode *newNode = new LNode(data); LNode *cur = head,*pre; while(pos--){ pre = cur; cur = cur->next; } newNode->next=cur; pre->next = newNode; printList(); } } void deleteL(int pos){ if(pos<1||pos>len()) cout<<"Deletion position is invalid."<<endl; else{ LNode *cur = head,*pre; while(pos--){ pre=cur; cur=cur->next; } pre->next = cur->next; printList(); } } };
|
二、相关题目
203.移除链表元素
题目链接
注意:
1.使用虚拟头节点方便操作
2.注意移除节点后删除内存(包括虚拟头节点)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| class Solution { public: ListNode* removeElements(ListNode* head, int val) { ListNode *dummyhead = new ListNode(0); dummyhead->next = head; ListNode *cur = dummyhead; while(cur->next!=nullptr){ if(cur->next->val==val){ ListNode *tem = cur->next; cur->next=tem->next; delete tem; }else cur=cur->next; } head=dummyhead->next; delete dummyhead; return head; } };
|
707.设计链表
题目链接
类的初始化中,使用私有变量来记录长度和虚拟节点
1 2 3 4
| private: int _size; LinkedNode * _dummyhead; };
|
1 2 3 4
| MyLinkedList() { _size = 0; _dummyhead = new LinkedNode(0); }
|
删除节点后将tmp指向nullptr
1 2 3 4 5 6
| delete tmp; tmp=nullptr;
|
完整代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
| class MyLinkedList {
public: struct LinkedNode { int val; LinkedNode* next; LinkedNode(int val):val(val), next(nullptr){} };
MyLinkedList() { _size = 0; _dummyhead = new LinkedNode(0); } int get(int index) { if(index>(_size-1)||index<0) return -1; LinkedNode *cur=_dummyhead->next; while(index--) { cur=cur->next; } return cur->val; } void addAtHead(int val) { LinkedNode *newLNode = new LinkedNode(val); newLNode->next = _dummyhead->next; _dummyhead->next = newLNode; _size++; } void addAtTail(int val) { LinkedNode *newLNode = new LinkedNode(val); LinkedNode *cur=_dummyhead; while(cur->next!=nullptr){ cur=cur->next; } newLNode->next = cur->next; cur->next = newLNode; _size++; } void addAtIndex(int index, int val) { if(index>_size||index<0)return; LinkedNode *newLNode = new LinkedNode(val); LinkedNode *pre=_dummyhead; while(index--){ pre=pre->next; } newLNode->next = pre->next; pre->next = newLNode; _size++;
} void deleteAtIndex(int index) { if(index<0||index>(_size-1)) return; LinkedNode *pre=_dummyhead,*tem; while(index--){ pre=pre->next; } tem=pre->next; pre->next=tem->next; delete tem; _size--;
} private: int _size; LinkedNode * _dummyhead; };
|
206.反转链表
题目链接
第一版
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| class Solution { public: ListNode* reverseList(ListNode* head) { if (head == nullptr) return head; else { ListNode* dummyNode = new ListNode(0); ListNode *cur = head, *nex; while (cur!= nullptr) { nex = cur->next; cur->next = dummyNode->next; dummyNode->next = cur; if(nex==nullptr)break; else{ cur = nex; nex = nex->next; } } cur = dummyNode->next; delete dummyNode; return cur; } } };
|
缺点: 虚拟头节点
改进方法1: 双链表法
时间复杂度 : $O(n)$
空间复杂度 : $O(1)$
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| class Solution { public: ListNode* reverseList(ListNode* head) { ListNode* temp; ListNode* cur = head; ListNode* pre = NULL; while(cur) { temp = cur->next; cur->next = pre; pre = cur; cur = temp; } return pre; } };
|
其余方法:递归法
时间复杂度 : $O(n)$
空间复杂度 : $O(n)$
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| class Solution { public: ListNode* reverse(ListNode* pre,ListNode* cur){ if(cur == NULL) return pre; ListNode* temp = cur->next; cur->next = pre; return reverse(cur,temp); } ListNode* reverseList1(ListNode* head) { return reverse(NULL, head); } ListNode* reverseList2(ListNode* head) { if(head == NULL) return NULL; if (head->next == NULL) return head; ListNode *last = reverseList(head->next); head->next->next = head; head->next = NULL; return last; }
};
|