链表面试题之链表逆置、指定前k个逆置

单链表逆置我们大概很熟悉,但对于链表前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;  
}  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值