【复习】单链表代码实现C++ 含链表翻转、链表合并等算法

单链表的代码实现

  • 结点

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;
}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值