逆置单链表以及求链表倒数第k个结点——题集(二)

本文提供了一种高效的单链表逆置方法,并介绍了如何仅通过一次遍历找到链表的倒数第K个节点,适用于带头结点和不带头结点的链表。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

逆置单链表及求链表倒数第k个结点——题集(二)

       今天分享一下两道练习题,即逆置单链表以及求链表倒数第k个结点,要求时间复杂度为O(1)。

       首先分享一下逆置单链表的代码和运行界面。单链表分为带头结点的单链表不带头结点的单链表

       源代码如下:

#include<iostream>
using namespace std;
 
//逆置/反转单链表,要求只能遍历一次链表
struct ListNode{
int val;
ListNode* next;
ListNode(int _val)
:val(_val)
,next(NULL)
{}
};
 
ListNode* reverse(ListNode* l1){//带头结点
ListNode* head = l1;
if(l1->next==NULL) return head;
l1=l1->next;
ListNode* tail = l1;
if(l1->next==NULL) return head;
l1=l1->next;
 
tail->next=NULL;//逆置后的最后一个结点next置空//********
while(l1->next != NULL){
ListNode* next=l1->next;
 
l1->next = tail;
tail=l1;
 
l1=next;
}
l1->next=tail;//最后一个结点与倒数第二个结点链接
head->next = l1;//把最后一个结点给头结点
return head;
 
}
 
ListNode* reverse1(ListNode* l1){//不带头结点
ListNode* head = l1;
ListNode* tail = l1;
if(l1->next==NULL) return head;
l1=l1->next;
 
tail->next=NULL;//逆置后的最后一个结点next置空//********
while(l1->next != NULL){
ListNode* next=l1->next;
 
l1->next = tail;
tail=l1;
 
l1=next;
}
l1->next=tail;//最后一个结点与倒数第二个结点链接
head = l1;//让原链表的最后一个结点变成头结点
return head;
 
}
 
void Printf(ListNode* l1){//打印
while(l1!=NULL){
cout<<l1->val<<" ";
l1=l1->next;
}
printf("\n");
}
 
void Listtest(){
ListNode l0(NULL);
ListNode l1(1);
ListNode l2(2);
ListNode l3(3);
ListNode l4(4);
ListNode l5(11);
 
l0.next = &l1;
l1.next = &l2;
l2.next = &l3;
l3.next = &l4;
l4.next = &l5;
 
cout<<"逆置/反转带头结点的单链表,要求只能遍历一次链表。"<<endl;
cout<<"带头结点的单链表l1: ";
Printf(l0.next);
ListNode* tmp = reverse(&l0);
cout<<"逆置后的单链表: ";
Printf(tmp->next);
}
 
void Listtest1(){
ListNode l1(1);
ListNode l2(2);
ListNode l3(3);
ListNode l4(4);
ListNode l5(11);
 
l1.next = &l2;
l2.next = &l3;
l3.next = &l4;
l4.next = &l5;
 
cout<<"逆置/反转不带头结点的单链表,要求只能遍历一次链表。"<<endl;
cout<<"不带头结点的单链表l1: ";
Printf(&l1);
ListNode* tmp = reverse1(&l1);
cout<<"逆置后的单链表: ";
Printf(tmp);
}
 
int main(){
Listtest();//带头结点的链表逆置//7.14//逆置/反转单链表+查找单链表的倒数第k个节点,要求只能遍历一次链表
cout<<endl<<"******************************"<<endl<<endl;
Listtest1();//带头结点的链表逆置
cout<<"******************************"<<endl;
system("pause");
return 0;
}

运行界面

 

       其次是求链表的倒数第k个结点的源代码和运行界面。

       源代码如下:

#include<iostream>
using namespace std;
 
//查找单链表的倒数第k个节点,要求只能遍历一次链表
struct ListNode{
int val;
ListNode* next;
ListNode(int _val)
:val(_val)
,next(NULL)
{}
};
 
ListNode* FindK(ListNode* l1,int k){//类快慢指针
ListNode* point=l1;
if(l1 == NULL || k==0)return NULL;
int num=1;
 
while(l1->next != NULL){
if(num < k){
num++;
l1 = l1->next;
continue;
}
break;
}
if(num < k)return NULL;//链表长度小于k
 
while(l1->next != NULL){
num++;
point=point->next;
l1=l1->next;
}
 
return point;
}
 
void Listtest(){
ListNode l1(1);
ListNode l2(2);
ListNode l3(3);
ListNode l4(4);
ListNode l5(11);
 
l1.next = &l2;
l2.next = &l3;
l3.next = &l4;
l4.next = &l5;
 
cout<<"查找单链表的倒数第k个节点,要求只能遍历一次链表。"<<endl;
cout<<"不带头结点的单链表l1: ";
Printf(&l1);
ListNode* prc = FindK(&l1, 0);
cout<<"FindK(&l1, 0):";
if(prc!=NULL)
cout<<prc->val<<endl;
else
cout<<"为NULL,找不到。"<<endl;
 
prc = FindK(&l1, 2);
cout<<"FindK(&l1, 2):";
if(prc!=NULL)
cout<<prc->val<<endl;
else
cout<<"为NULL,找不到。"<<endl;
 
prc = FindK(&l1, 4);
cout<<"FindK(&l1, 4):";
if(prc!=NULL)
cout<<prc->val<<endl;
else
cout<<"为NULL,找不到。"<<endl;
 
prc = FindK(&l1, 8);
cout<<"FindK(&l1, 8):";
if(prc!=NULL)
cout<<prc->val<<endl;
else
cout<<"为NULL,找不到。"<<endl;
 
}
 
int main(){
Listtest();//查找单链表的倒数第k个节点
system("pause");
return 0;
}

运行界面

 

      分享如上!望各位学的开心!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值