逆置單鏈表以及求鏈表倒數第k個結點——題集(二)

逆置單鏈表及求鏈表倒數第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;
}

運行界面

 

      分享如上!望各位學的開心!

發佈了72 篇原創文章 · 獲贊 15 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章