单链表的代码实现
struct ListNode{
int val;
ListNode *next;
ListNode(int val){
this->val=val;
this->next=NULL;
}
};
增删查改等
class LinkedList{
private:
ListNode *head;
public:
LinkedList(){
head = NULL;
}
ListNode *insertHead(int val){
ListNode *newNode = new ListNode(val);
ListNode *p = head;
newNode->next = head;
head = newNode;
return head;
}
ListNode *insertTail(int val){
ListNode *newNode = new ListNode(val);
ListNode *p = head;
if(p == NULL)
insertHead(val);
else{
while(p->next != NULL){
p = p->next;
}
p->next = newNode;
}
return head;
}
ListNode *insertPosition(int pos, int val){
ListNode *newNode = new ListNode(val);
ListNode *p = head;
if(pos > size() || pos < 0){
cout<<"Out of the size!!"<<endl;
return NULL;
}
else if(pos == 0) // AT HEAD
insertHead(val);
else if(pos == size()) // AT TAIL
insertTail(val);
else{ // IN THE MIDDEL
for(int i=0;i<pos-1;i++) // FIND THE ELEMENT BEFORE THIS INDEX
p = p->next;
newNode->next = p->next;
p->next= newNode;
}
return head;
}
ListNode *deleteNode(int val){
ListNode *pre = head;
ListNode *cur = head;
if(head == NULL){
cout << "The list is empty!" << endl;
return NULL;
}
else if(cur->val == val){ // HEAD
head = cur->next;
delete(cur);
}
else{
while(cur != NULL && cur->val != val){
pre = cur;
cur = cur->next;
}
if(cur == NULL){
cout<<"Value "<<val<<" doesn't exist."<<endl;
return NULL;
}
else{
pre->next= cur->next;
delete cur;
}
}
return head;
}
int searchNode(int val){
ListNode *p = head;
for(int i=1; p != NULL; i++ ){
if(p->val == val){
cout<<"Value "<<val<<" at position "<<i<<"."<<endl;
return i;
}
p = p->next;
}
cout<<"Value "<<val<<" doesn't exist."<<endl;
return 0;
}
int updateNode(int oldVal, int newVal){
ListNode *p = head;
for(int i=0; p != NULL; i++ ){
if(p->val == oldVal){
cout<<"Value "<<oldVal<<" at position "<<i;
cout<<" becomes value "<<newVal<<endl;
p->val = newVal;
return i;
}
p = p->next;
}
cout<<"Value "<<oldVal<<" doesn't exist."<<endl;
return 0;
}
int const size(){
int len=0;
ListNode *p = head;
while(p != NULL){
p = p->next;
len++;
}
return len;
}
ListNode *getHead(){
return head;
}
};
void printList(ListNode *p){
while(p != NULL){
cout<<p->val<<" ";
p = p->next;
}
cout<<endl;
}
1. 迭代翻转
(图片来自:递归思维:如何跳出细节?)
ListNode *reverseList_iteration(ListNode *h){
ListNode *pre = NULL;
ListNode *cur = h;
ListNode *nxt = NULL;
if(h == NULL)
return NULL;
if(h->next== NULL){
return h;
}
while(cur != NULL){
nxt = cur->next;
cur->next = pre;
pre = cur;
cur = nxt;
}
return pre;
}
2. 递归翻转
(图片来自优秀讲解:视频讲解,递归 + 迭代)
ListNode *reverseList_recursion(ListNode *h){
// Find the last node, end of the recursion
if(h == NULL)
return NULL;
if(h->next== NULL){
return h;
}
// Recursion
// Deal with the list with head of h->next
ListNode *newHead = reverseList_recursion(h->next);
// Deal with the current node
h->next->next = h;
h->next= NULL;
return newHead;
}
3. k个一组翻转
(图片来自优秀讲解:图解k个一组翻转链表)
ListNode *reverseList_KGroup(ListNode* h, int k){
ListNode *dummy = new ListNode(0); // Pseudo node points to head
dummy->next= h;
ListNode *pre = dummy;
ListNode *start = pre->next;
ListNode *end = dummy;
ListNode *nxt = NULL;
if(k <= 1 || k>= size()) return h;
while(end->next != NULL){
// Find the end of one reverse group
for(int i=0; i<k && end != NULL; i++)
end = end->next;
if(end == NULL)
break;
nxt = end->next;
start = pre->next;
end->next = NULL;
pre->next = reverseList_recursion(start);
start->next = nxt;
pre = start;
end = pre;
}
return dummy->next;
}
1. 合并两个有序链表
超简洁递归方法来自:画解算法:21. 合并两个有序链表
ListNode *mergeTwoLists(ListNode* l1, ListNode* l2){
if(l1 == NULL) {
return l2;
}
if(l2 == NULL) {
return l1;
}
if(l1->val < l2->val) {
l1->next = mergeTwoLists(l1->next, l2);
return l1;
}
else {
l2->next = mergeTwoLists(l1, l2->next);
return l2;
}
}
结果:
解题思路:
- 用快慢指针找到中间节点
- 用
归并排序思想
分成两个子链 - 将排序好的两个子链合并成一个,使用链表合并算法
mergeTwoLists()
- 此解时间复杂度
O
(
n
l
o
g
n
)
O(nlogn)
O(nlogn),空间复杂度
O
(
n
)
O(n)
O(n)
(图片来自:Sort List (归并排序链表),可参考题解二归并排序(从底至顶直接合并),以满足时间复杂度 O ( n l o g n ) O(nlogn) O(nlogn),空间复杂度 O ( 1 ) O(1) O(1))
ListNode *sortList(ListNode *head) {
if (head == NULL || head->next == NULL) return head;
// Define fast and slow pointer to get the middel node of the list
ListNode *fast = head->next;
ListNode *slow = head;
while (fast != NULL && fast->next != NULL) {
slow = slow->next;
fast = fast->next->next;
}
// Get the head of right list
ListNode *mid = slow->next;
// Cut into two list, set the end of left list points to NULL
slow->next = NULL;
// Merge two sortList
// left:[head, slow]
// right:[slow->next, right]
return mergeTwoLists(sortList(head), sortList(mid));
}
结果:
int main(){
LinkedList* list = new LinkedList();
list->insertTail(3);
list->insertTail(4);
list->insertTail(5);
list->insertHead(2);
list->insertHead(1);
list->insertPosition(5,999);
//cout<<"List1:"<<endl;
printList(list->getHead());
list->searchNode(2);
list->deleteNode(888);
list->revList_rec();
printList(list->getHead());
list->revList_KGroup(2);
printList(list->getHead());
/*
LinkedList* list2 = new LinkedList();
list2->insertTail(4);
list2->insertTail(5);
list2->insertTail(6);
cout<<"List2:"<<endl;
printList(list2->getHead());
cout<<"Merge:"<<endl;
printList(mergeTwoLists(list->getHead(),list2->getHead()));
*/
return 0;
}