单链表逆置我们大概很熟悉,但对于链表前k个逆置,可能不大常见,这是一道链表逆置的变种,其中变种的还有链表倒数第k个、链表k个组成一组,组内逆置,在这里我给大家分享一下我的想法。
对于单链表的逆置有两种方法可以实现:
(1)利用辅助指针
基本思想:在遍历结点过程中,设置辅助指针,用于记录先前遍历的结点。这样依次编译的过程中只需修改其后继结点的next域即可。
typedef int DataType; //类型定义
typedef struct node{ //单链表定义
DataType data;
struct node* next;
}LinkedNode,*LinkList;
void ReverseList(LinkList& ListHead)
{
cout<<"Begin to Reverse the List"<<endl;
if( (NULL==ListHead)||(NULL==ListHead->next) )return ; //边界检测
LinkedNode* pPre=ListHead; //先前指针
LinkedNode* pCur=pPre->next; //当前指针
LinkedNode* pNext=NULL; //后继指针
while(pCur!=NULL)
{
pNext=pCur->next;
pCur->next=pPre;
pPre=pCur;
pCur=pNext;
}
ListHead->next=NULL;
ListHead=pPre; //记录下新的头结点
}
(2)递归
基本思想:在对当前结点逆置时,先递归地逆置其后继结点,然后将后继结点指向当前结点。
实现代码:
写了两个版本
I、返回值为空
void ReverseList(LinkedNode* pCur,LinkList& ListHead)
{
if( (NULL==pCur)||(NULL==pCur->next) )
{
ListHead=pCur;
}
else
{
LinkedNode* pNext=pCur->next;
ReverseList(pNext,ListHead); //递归逆置后继结点
pNext->next=pCur; //将后继结点指向当前结点。
pCur->next=NULL;
}
}
void ReverseList(LinkedNode* pCur,LinkList& ListHead)
{
if( (NULL==pCur)||(NULL==pCur->next) )
{
ListHead=pCur;
}
else
{
LinkedNode* pNext=pCur->next;
ReverseList(pNext,ListHead); //递归逆置后继结点
pNext->next=pCur; //将后继结点指向当前结点。
pCur->next=NULL;
}
}
II、返回值为结点类型
LinkedNode* ReverseList(LinkedNode* pCur,LinkList& ListHead)
{
cout<<"Begin to Reverse the List"<<endl;
if( (NULL==pCur)||(NULL==pCur->next) )
{
ListHead=pCur;
return pCur;
}
else
{
LinkedNode* pTemp=ReverseList(pCur->next,ListHead); //递归逆置后继结点
pTemp->next=pCur; //将后继结点指向当前结点
pCur->next=NULL;
return pCur;
}
}
//逆置前k个
Node* swapListByK(Node* pHead, int k) {
if (k <= 1)
return pHead;
int pos;
Node* pNode = pHead;
Node* pNewHead;
Node* pNextNode;
Node* pLastNode = NULL;;
pHead = NULL;
while (pNode) {
pos = 0;
pNewHead = pNode;
while (pNode && pos < k - 1) {
pNode = pNode->_next;
pos++;
}
if (pNode) {
pNextNode = pNode->_next;
pNode->_next = NULL;
if (NULL != pLastNode) {
pLastNode->_next = NULL;
}
pNewHead = reverseList(pNewHead);
if (NULL == pHead) {
pHead = pNewHead;
}
else {
pLastNode->_next = pNewHead;
}
pNode = getLastNode(pNewHead);
pNode->_next = pNextNode;
pLastNode = pNode;
pNode = pNextNode;
}
else {
break;
}
}
return pHead;
}
k各组成一组,组内逆置
ListNode* reverseKGroup(ListNode* head, int k)
{
ListNode *pre = new ListNode(-1), *tail = pre;
ListNode *p = head;
while(p != NULL)
{
ListNode *q = p;
int cnt = 0;
for (int i = 0; i < k && q != NULL; ++i)
{
q = q->next;
++cnt;
}
if (cnt < k)
{
tail->next = p;
break;
}
ListNode *end = p;
while(p != q)
{
ListNode *t = p->next;
p->next = tail->next;
tail->next = p;
p = t;
}
tail = end;
}
return pre->next;
}
链表倒数第k个
//.查找单链表的倒数第k个节点,要求只能遍历一次链表
PNode FindLastKNode(PNode pHead, size_t k)
{
//1.链表为空
//2.链表元素少于K
//3.链表元素多余K
PNode pfast = pHead;
PNode pslow = pHead;
if (NULL == pHead || k < 0)
return NULL;
while (k--)
{
pfast = pfast->_pNext; //pfast指向K的下一个节点
}
while (pfast)
{
pfast = pfast->_pNext; //pfast -> null
pslow = pslow->_pNext; //pslow -> 倒数第k个节点
}
return pslow; //指针pslow指向倒数第K个结点
}
完整代码:
#include<iostream>
using namespace std;
const int N=6;
typedef int DataType;//类型定义
typedef struct node{ //单链表
DataType data;
struct node* next;
}LinkedNode,*LinkList;
/****由数组创建单链表****/
LinkList CreateList(DataType a[N])
{
LinkedNode* ListHead=new LinkedNode();
ListHead->data=a[0];
ListHead->next=NULL;
for(int i=N-1;i>=1;i--)
{
LinkedNode* p=new LinkedNode();
p->data=a[i];
p->next=ListHead->next;
ListHead->next=p;
}
return ListHead;
}
/****输出单链表****/
void PrintList(LinkList ListHead)
{
if(NULL==ListHead)cout<<"The List is empty!"<<endl;
else
{
LinkedNode* p=ListHead;
while(p!=NULL)
{
cout<<p->data<<" ";
p=p->next;
}
cout<<endl;
}
}
void ReverseList(LinkedNode* pCur,LinkList& ListHead)
{
if( (NULL==pCur)||(NULL==pCur->next) )
{
ListHead=pCur;
}
else
{
LinkedNode* pNext=pCur->next;
ReverseList(pNext,ListHead); //递归逆置后继结点
pNext->next=pCur; //将后继结点指向当前结点。
pCur->next=NULL;
}
}
//逆置前k个
Node* swapListByK(Node* pHead, int k) {
if (k <= 1)
return pHead;
int pos;
Node* pNode = pHead;
Node* pNewHead;
Node* pNextNode;
Node* pLastNode = NULL;;
pHead = NULL;
while (pNode) {
pos = 0;
pNewHead = pNode;
while (pNode && pos < k - 1) {
pNode = pNode->_next;
pos++;
}
if (pNode) {
pNextNode = pNode->_next;
pNode->_next = NULL;
if (NULL != pLastNode) {
pLastNode->_next = NULL;
}
pNewHead = reverseList(pNewHead);
if (NULL == pHead) {
pHead = pNewHead;
}
else {
pLastNode->_next = pNewHead;
}
pNode = getLastNode(pNewHead);
pNode->_next = pNextNode;
pLastNode = pNode;
pNode = pNextNode;
}
else {
break;
}
}
return pHead;
}
int main()
{
int a[N]={1,2,3,4,5,6};
LinkedNode* list=CreateList(a);
PrintList(list);
LinkedNode*pTemp=list;
ReverseList(pTemp,list);
PrintList(list);
return 0;
}