王道链表综合题(上)

提示:老夫惟有,醒来明月,醉后清风


前言

建议有时间先看一下 前面这个知识点之后 再来写相关的题目,,链表相关知识
双向链表相关知识
有的时候你要知道一个问题 基础不牢地动山摇 这里后面有时间我也会将基础知识再打一遍,这里因为这一节中综合题大概有二十多道 所以分成上下两个文章来写

第一题

请添加图片描述

先谈

什么是递归?这里我就不说了,其中第三部分浅显的谈了一下递归,感兴趣的可以看一下, 大概形式是下面这样的 但是因为不带头节点 所以第一个结点是是需要特殊考虑的 同时这里我们也考虑一下最后一个结点

public void Fun(参数0) {
    if (终止条件) {
        return;
    }
    Fun(参数1)
    Fun(参数2)
            ……
    Fun(参数n)
}

代码

void Solution1(LNode* &L,int x){
	 if(L==NULL){
	 	return ;
	 }
	 if(L->data==x){
	 	if(L->next==NULL){
	 		//若是后面没有元素了 
			 free(L);
			 L=NULL; 
		 }
		 else{//后面还有元素; 
		 	L->data=L->next->data;
			LNode* cur=L;
	 		L=L->next;
	 		free(cur);	
		 }
		 Solution1(L,x);
	 }
	else Solution1(L->next,x);
}

第二题

请添加图片描述

先谈

使用上面一题中的递归的方法是一样可以解决的,还有就是直接使用一个遍历来写,也比较简单一点,这里我们使用递归 与上述做一个对比,但是这样写也是有一个bug的就是头节点中是没有存放数的 这里里面放的是0 所以若是删除的是0 则调用print()而不调用printHead();

代码

void Solution2(LNode* &L,int x){ 
	 if(L==NULL){
	 	return;
	 }
	 if(L->data==x){
	 	if(L->next==NULL){
	 		//若是后面没有元素了 
			 free(L);
			 L=NULL; 
		 }
		 else{//后面还有元素; 
		 	L->data=L->next->data;
			LNode* cur=L;
	 		L=L->next;
	 		free(cur);	
		 }
		 Solution1(L,x);
	 }
	else Solution1(L->next,x);
}

注意

至于为什么希望读者结合本代码思考一下

	case 2:{
			LNode* L=InitHeadList();int x;
			cout<<"请输入你要删除的数"<<endl; 
			cin>>x;
			Solution2(L,x);
			if(0==x){
				Print(L);
			}
			else PrintHead(L);
			break;
		} 

第三题

请添加图片描述

先谈

这个结合一个栈 就可以了,但是这样未免太浪费表情了,你应该知道若是能用栈结构实现的 自然也可以使用递归的方式, 若是你不知道,在读一遍上面的话你应该就知道了, 使用递归也不难

void Solution3(LNode* L){
	if(L==NULL){
		return;
	}
	Solution3(L->next);
	cout<<L->data<<" ";
}

运行截图

请添加图片描述

第四题

请添加图片描述

先谈

使用两个指针,一个用于保存最小位置前一个位置的指针,一个用来遍历链表

代码

void Solution4(LNode* &L){
	LNode* OldMin;
	LNode* min=L;//保存最小值的前一个指针 
	for(LNode* cur=L;cur->next->next!=NULL;cur=cur->next){
		if(cur->next->data<min->next->data){
			min=cur->next;
		}
	}
	cout<<"此时最小值是"<<min->next->data<<endl;
	OldMin=min->next;
	min->next=min->next->next;
	free(OldMin);
	PrintHead(L);
}

第五题

请添加图片描述

先谈

我的想法是通过三个指针来完成,只需改变指针的指向就可以,但是在转方向之前需要把后一个指针向后移动一个位置

代码

void Solution5(LNode* &L){
	if(L->next==NULL){
		cout<<"此时链表是为空链表"<<endl;
		return;
	}
	else if(L->next->next==NULL){
		cout<<"此时链表只有一个结点"<<endl;
		return;
	}
	else{
		
		LNode* pre=L->next;LNode* mid=pre->next;LNode* end=pre->next;
		pre->next=NULL;
		while(end!=NULL){
			end=end->next;//后一个指针向后移动一个位置
			mid->next=pre;
			pre=mid;
			mid=end;	
		}
		L->next=pre;
		PrintHead(L);	
	}
}

第六题

请添加图片描述

先谈

既然没有要求什么,则可以先将数据保存在数组中,然后对数组进行操作 然后再放入链表中也可以,或者一种思想就是将一个链表分成两个部分 一部分有序,一部分无序,其实就是插入排序的思想 这里我们写第一种 第二种王道上就有

代码

void Solution6(LNode* &L){
	vector<int> V;
	LNode *p=L->next;
	while(p){
		V.push_back(p->data);
		p=p->next; 
	}
	sort(V.begin(),V.end());
	p=L->next; 
	int i=0;
	while(p){
		p->data=V[i++];
		p=p->next; 
	}
	PrintHead(L);
}

第七题

请添加图片描述

先谈

这里我使用的是一个指针,所以要考虑的情况比较多,若是使用两个指针 一个用于检测 一个用于指向前驱 会更好写一些

代码

void Solution7(LNode* &L,int begin,int end){
	LNode* cur=L;
	if(L->next==NULL){
		cout<<"是空表"<<endl;
		return; 
	}
	else if(cur->next->next==NULL){
		if(cur->next->data<=end&&cur->next->data>=begin){
			L->next=NULL; 
		}
		else{
		} 
		PrintHead(L);
		return ;
	}
	while(cur->next->next!=NULL){
		if(cur->next->data<=end&&cur->next->data>=begin){
			LNode* oldcur=cur->next; 
			cur->next=cur->next->next;
			free(oldcur);
			
		}
		else cur=cur->next;
	}
	PrintHead(L);
}

可执行代码汇总

#include<bits/stdc++.h>
using namespace std;
#define F(i,m,n) for(int i=m;i<n;i++)
#define ElemType int
typedef struct LNode{
	ElemType data;
	struct LNode* next; 
}LNode;
void Print(LNode* L){
	cout<<"此时的链表是"<<endl;
	if(L==NULL){
		cout<<"此时是空表"<<endl;
		return;
	}
	for(LNode* i=L;i!=NULL;i=i->next){
		cout<<i->data;
	} 
	cout<<endl;
}
void PrintHead(LNode* L){
	cout<<"此时的链表是"<<endl;
	if(L->next==NULL){
		cout<<"此时是空表"<<endl;
		return;
	}
	for(LNode* i=L->next;i!=NULL;i=i->next){
		cout<<i->data;
	} 
	cout<<endl;
}
LNode* InitHeadList(){
	cout<<"请输入链表的值"<<endl;
	LNode* L=(LNode*)malloc(sizeof(LNode));
	L->data=0;//头结点这里可以存放链表的长度 
	L->next=NULL;
	int input;
	while(scanf("%d",&input)!=EOF){
		LNode* cur=(LNode*)malloc(sizeof(LNode));
		cur->data=input;
		cur->next=L->next;
		L->next=cur;
	}
	PrintHead(L);
	return L;
}
LNode* InitList(){
	cout<<"请输入链表的值"<<endl;
	int input; LNode* L=NULL;
	while(scanf("%d",&input)!=EOF){
		LNode* cur=(LNode*)malloc(sizeof(LNode));
		cur->next=L;
		cur->data=input;
		L=cur;
	}
	Print(L);
	return L;
} 
void Solution1(LNode* &L,int x){
	 if(L==NULL){
	 	return ;
	 }
	 if(L->data==x){
	 	if(L->next==NULL){
	 		//若是后面没有元素了 
			 free(L);
			 L=NULL; 
		 }
		 else{//后面还有元素; 
		 	L->data=L->next->data;
			LNode* cur=L;
	 		L=L->next;
	 		free(cur);	
		 }
		 Solution1(L,x);
	 }
	else Solution1(L->next,x);
}
void Solution2(LNode* &L,int x){ 
	 if(L==NULL){
	 	return;
	 }
	 if(L->data==x){
	 	if(L->next==NULL){
	 		//若是后面没有元素了 
			 free(L);
			 L=NULL; 
		 }
		 else{//后面还有元素; 
		 	L->data=L->next->data;
			LNode* cur=L;
	 		L=L->next;
	 		free(cur);	
		 }
		 Solution1(L,x);
	 }
	else Solution1(L->next,x);
}
void Solution3(LNode* L){
	if(L==NULL){
		return;
	}
	Solution3(L->next);
	cout<<L->data<<" ";
}
void Solution4(LNode* &L){
	LNode* OldMin;
	LNode* min=L;//保存最小值的前一个指针 
	for(LNode* cur=L;cur->next->next!=NULL;cur=cur->next){
		if(cur->next->data<min->next->data){
			min=cur->next;
		}
	}
	cout<<"此时最小值是"<<min->next->data<<endl;
	OldMin=min->next;
	min->next=min->next->next;
	free(OldMin);
	PrintHead(L);
}
void Solution5(LNode* &L){
	if(L->next==NULL){
		cout<<"此时链表是为空链表"<<endl;
		return;
	}
	else if(L->next->next==NULL){
		cout<<"此时链表只有一个结点"<<endl;
		return;
	}
	else{
		
		LNode* pre=L->next;LNode* mid=pre->next;LNode* end=pre->next;
		pre->next=NULL;
		while(end!=NULL){
			end=end->next;//后一个指针向后移动一个位置
			mid->next=pre;
			pre=mid;
			mid=end;	
		}
		L->next=pre;
		PrintHead(L);	
	}
}
void Solution6(LNode* &L){
	vector<int> V;
	LNode *p=L->next;
	while(p){
		V.push_back(p->data);
		p=p->next; 
	}
	sort(V.begin(),V.end());
	p=L->next; 
	int i=0;
	while(p){
		p->data=V[i++];
		p=p->next; 
	}
	PrintHead(L);
}
void Solution7(LNode* &L,int begin,int end){
	LNode* cur=L;
	if(L->next==NULL){
		cout<<"是空表"<<endl;
		return; 
	}
	else if(cur->next->next==NULL){
		if(cur->next->data<=end&&cur->next->data>=begin){
			L->next=NULL; 
		}
		else{
		} 
		PrintHead(L);
		return ;
	}
	while(cur->next->next!=NULL){
		if(cur->next->data<=end&&cur->next->data>=begin){
			LNode* oldcur=cur->next; 
			cur->next=cur->next->next;
			free(oldcur);
			
		}
		else cur=cur->next;
	}
	PrintHead(L);
}
void Menu(){
	int choice;
	cout<<"请输入你要解决第几题"<<endl;
	cin>>choice;
	switch(choice){
		case 1:{
			LNode* L=InitList();int x;
			cout<<"请输入你要删除的数"<<endl; 
			cin>>x;
			Solution1(L,x);
			Print(L);
			break;
		}
		case 2:{
			LNode* L=InitHeadList();int x;
			cout<<"请输入你要删除的数"<<endl; 
			cin>>x;
			Solution2(L,x);
			if(0==x){
				Print(L);
			}
			else PrintHead(L);
			break;
		} 
		case 3:{
			LNode* L=InitHeadList();
			cout<<"逆向输出是"<<endl;
			Solution3(L->next);
			break;
		}
		case 4:{
			LNode* L=InitHeadList();
			Solution4(L);
			break;
		}
		case 5:{
			LNode* L=InitHeadList();
			Solution5(L);
			break;
		}
		case 6:{
			LNode* L=InitHeadList();
			Solution6(L);
			break;
		}
		case 7:{
			int begin;int end;
			LNode* L=InitHeadList();
			cout<<"请输入给定的区间"<<endl;
			cin>>begin>>end;
			Solution7(L,begin,end);
			break;
		}
		default:{
			break;
		}
	}
}
int main(){
	Menu();
}

总结

因为有二五题 这里就分成三个部分 感觉不错点个赞呗 铁子
此时附上今天吊到的的一条鱼,请添加图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值