单链表的基本操作3.0(C++)

接上一篇博客:单链表的基本操作2.0(C++)

9、反转链表
为正确反转一个链表,需要调整链表中指针的方向。如下图所示,经过若干操作,我们已经把节点 i 之前的指针调整完毕,这些节点的next都指向前一个节点。但由于节点 i 的next指向 h ,我们无法在链表中遍历到 j,所以除了要知道节点 i 本身,还需要知道 i 的前一个节点 h,同时还需要事先保存 i 的下一个节点 j 。所i以需要三个指针。
在这里插入图片描述

void LinkList::ReverseList(int n){
	Node* pRHead=NULL;  //原链表中的尾节点
	Node* pNode=head; //当前节点
	Node* pPre=NULL; //原链表中的下一个节点
	while(pNode!=NULL){
		Node* pNext=pNode->next;
		if(pNext==NULL){
			pRHead=pNode;
		}
		pNode->next=pPre;
		pPre=pNode;
		pNode=pNext;
	}
	Node* p;
	p=pRHead;
	cout<<"反转后链表为:";	
	for(int i=0;i<n;i++){
		cout<<p->value<<" ";
		p=p->next;
	}
}

10、合并两个递增排序好的链表
使得产生的新链表中的节点仍是递增排序的。
注意两方面的问题:
①合并后的链表中间不要断裂(递归)
②鲁棒性(空指针)
在这里插入图片描述

Node*  LinkList::MergeList(Node* head1,Node* head2){
	Node* temp=NULL;
	if(head1==NULL){
		return head2;
	}
	else if(head2==NULL){
		return head1;
	}	
	else{
		if(head1->value<head2->value){
			temp=head1;
			temp->next=MergeList(head1->next,head2);
		}
		else{
			temp=head2;
			temp->next=MergeList(head1,head2->next);
		}
	}
	return temp;
}

源代码

/*
实现单链表操作3.0 
*/ 
#include<iostream>
using namespace std;

//定义节点结构体
struct Node{
	int value;
	Node* next;
}; 

//定义链表类
class LinkList{
	private:
		Node* head;
	public:
		LinkList();//构造函数
		void CreateLinklist(int n);
		void ReverseList(int n);
		Node*  MergeList(Node* head1,Node* head2);
		Node*  getHead();		 
}; 

//构造函数 
LinkList::LinkList(){
	head=new Node;
	head->next=NULL; 
}

//创建链表 
void LinkList::CreateLinklist(int n){
	Node* temp;
	Node* p;
	p=head;
	cout<<"请依次输入"<<n<<"个节点的值:";
	for(int i=0;i<n;i++){
		temp=new Node;
		cin>>temp->value;
		p->next=temp;
		p=p->next;
	}
	p->next=NULL;
}

//反转链表
void LinkList::ReverseList(int n){
	Node* pRHead=NULL;
	Node* pNode=head;
	Node* pPre=NULL;
	while(pNode!=NULL){
		Node* pNext=pNode->next;
		if(pNext==NULL){
			pRHead=pNode;
		}
		pNode->next=pPre;
		pPre=pNode;
		pNode=pNext;
	}
	Node* p;
	p=pRHead;
	cout<<"反转后链表为:";	
	for(int i=0;i<n;i++){
		cout<<p->value<<" ";
		p=p->next;
	}
}
//合并两个递增排序的链表
Node*  LinkList::MergeList(Node* head1,Node* head2){
	Node* temp=NULL;
	if(head1==NULL){
		return head2;
	}
	else if(head2==NULL){
		return head1;
	}	
	else{
		if(head1->value<head2->value){
			temp=head1;
			temp->next=MergeList(head1->next,head2);
		}
		else{
			temp=head2;
			temp->next=MergeList(head1,head2->next);
		}
	}
	return temp;
}

//获取链表的第一个节点
Node*  LinkList::getHead()
{
  return head->next;
}

int main(){
	LinkList list;
	int num;
	cout<<"请输入要反转的链表的节点数:";
	cin>>num;
	list.CreateLinklist(num);
	list.ReverseList(num);
	cout<<endl<<endl;

	LinkList list1;
	LinkList list2;
	LinkList sum;
	int num1,num2;
	cout<<"请输入要合并的第一个链表的节点数:";
	cin>>num1;
	list1.CreateLinklist(num1);
	
	cout<<"请输入要合并的第二个链表的节点数:";
	cin>>num2;
	list2.CreateLinklist(num2);
	
	Node* h1;
	Node* h2;
	h1=list1.getHead();
	h2=list2.getHead();	
	Node* h;
	h=sum.MergeList(h1,h2);
	cout<<"合并后的链表为:";
	for(int i=0;i<(num1+num2);i++){
		cout<<h->value<<" ";
		h=h->next;
	}	
	return 0;
}

在这里插入图片描述

参考书籍:《剑指offer 第二版》

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值