【链表】反转/逆置 链表,以及升级版Node* RotateList(Node* list, size_t k)

本文介绍两种链表反转的方法:一种是基本的链表整体反转;另一种是针对链表中的每k个元素进行局部反转,形成更为复杂的链表结构。通过具体的代码实现,详细解释了这两种方法的具体操作步骤。

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

问题一
问题描述:定义一个函数,输入一个链表的头结点,反转该链表并输出反转后链表的头结点。
考虑:1只有一个结点。2、链表为空
//思路:定义三个指针,改变链表结点的指向
//考虑 1一个结点,没有及诶单
Node *ReverseList(Node* pHead)
{
    Node* ReverseHead = NULL;
    Node* pNode = pHead;
    Node* pPrev = NULL;
    while (pNode != NULL)
    {
        Node *pNext = pNode->_next;
        if (pNext == NULL)
            ReverseHead = pNode;
        pNode->_next = pPrev;
        pPrev = pNode;
        pNode = pNext;
    }
    return ReverseHead;
}
问题二:升级版

链表翻转。给出一个链表和一个数k,比如链表1→2→3→4→5→6,k=2,翻转后2→1→4→3→6→5,若k=3,翻转后3→2→1→6→5→4,若k=4,翻转后4→3→2→1→5→6,用程序实现Node* RotateList(Node* list, size_t k). 提示:这个题是链表逆置的升级变型。

分析问题

思路:链表中长度为k的一段从链表中摘除,翻转之后在将其衔接回链表。
步骤:1、找到k长的链表
2、从原来链表上摘取下来
3、逆置新的链表
4、连接到原来的链表上
循环上面的四个步骤,直到链表的长度不够k。

Node* GetTail(Node *pHead)
{
    assert(pHead);
    Node* pNode = pHead;
    while (pNode->_next != NULL)
    {
        pNode = pNode->_next;
    }
    return pNode;
}
Node* RotateList(Node* pHead, size_t k)
{   
    if (k <= 1)
        return pHead;
    Node *pNewList = NULL;
    Node *pLastNode = NULL;//记录上一段链表的末尾
    Node *pNextNode = NULL;//k链表的下一个节点
    Node *pNewHead = NULL; //新链表的头
    Node *pNode = pHead;
    while (pNode)
    {
        //找出长度为k的一段链表
        pNewHead = pNode;
        size_t pos = 1;
        while (pNode && pos < k)
        {
            pNode = pNode->_next;
            pos++;
        }       
        if (pos == k && pNode != NULL)
        {
            //找到的长度k的一段链表,逆置这段链表
            pNextNode = pNode->_next;
            pNode->_next = NULL;
            //断开新链表与原来的链表
            if (NULL != pLastNode)
                pLastNode->_next = NULL;

            pNewHead = ReverseList(pNewHead);
            //将这段链表连接到原来的链表上 1和2
            //1、将新链表的头 链到原来的链表
            if (pLastNode == NULL)
            {
                pNewList = pNewHead;
            }           
            else
            {
                pLastNode->_next = pNewHead;
            }
            //2、将新链表的尾 连接到原来的链表上
            //找新链表的尾
            pNode = GetTail(pNewHead);
            pNode->_next = pNextNode;
            pLastNode = pNode;
            pNode = pNextNode;//开始下一轮找k长链表
        }
        else
            break;
    }
    return pNewList;
}
#include <stdio.h> #include <stdlib.h> //第一关代码 struct node {//此处填写代码,定义链表结点类型,包含一个存放整型数据的 data 成员,和一个指向下一个结点的next成员 }; struct node *mycreateList() {//此处填写代码,创建一个只有一个头结点的空链表,头节点的数据域赋值为0,并将表头结点的地址返回 } //第二关代码 void myinsertHead(struct node * head, int insData ) { /*在此处完成任务,实现在head为表头d 链表的头插数据元素insData的功能*/ //begin //end } void myinsertTail(struct node * head , int insData ) { /*在此处完成任务,在head为表头的单链表表尾插入数据元素insData*/ //begin //end } void myprintList(struct node *L) { /*在此处完成任务,输出L为表头链表中的数据,每输出一个数据换一行*/ //begin //end } //第三关代码 void reverseList_link( struct node *L) { //请在此处填入代码,实现链表功能 //begin //end } //第四关代码 int locateAndChange( struct node *L, int data) { //请在此处填入代码,在头结点为L的链表中查找 与data值相等的第一个结点,若能找到该结点,则将该结点的值与前驱结点的值交换 //若未找到与data值相等的结点,则返回值为-1,若找到的结点无前驱结点,则返回值为0,否则返回值为前驱结点的值 //begin //end } //第五关代码 int destroyList(struct node *L) { //请在此处填写代码,实现将链表L的结点空间回收 //返回值为回收结点的个数,含头结点在内 }
最新发布
03-24
#include <iostream> using namespace std; struct Node { int data; struct Node *next; }; //链表结点结构 void createlist_r(struct Node *&head)//尾插法建单链表,没有头结点,输入顺序就是结点顺序 { int n,i; struct Node *p,*tail; head=new Node; cin>>n; cin>>head->data; head->next=nullptr; tail=head; for(i=0; i<n-1; i++) { p=new Node; cin>>p->data; p->next=nullptr; tail->next=p; tail=p; } } void display(struct Node *head)//输出不带头结点的单链表 { struct Node *p; p=head; while(p!=nullptr) { cout<<p->data<<" "; p=p->next; } cout<<endl; } void deletelist(struct Node *&head) //删除单链表 { struct Node *p; while(head) { p=head; head=head->next; delete(p); } head=nullptr; //一定要赋值为空,否则容易造成野指针访问 } //请在以下空白处编写reverselit函数,完成原地转,即过程中不在分配新的结点也不撤销旧的结点 /********** Write your code here! **********/ /*******************************************/ int main() { int t; cin>>t; while(t--) { struct Node *head; createlist_r(head); display(head); reverselist(head); display(head); deletelist(head); } return 0; }【id:425】【34分】B. 链表原地转并输出(填空题) 时间限制 4s 内存限制 128MB 题目描述 按数字输入顺序创建单链表。不可借助数组、容器,不可开辟新结点空间。编写函数,在原链表上实现单链表反转。例如单链表10->20->30,反转后变为单链表30->20->10。补全代码
03-20
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值