C语言程序设计整理(6)链表部分反转

文章介绍了如何使用C语言实现一个函数,对单链表的部分区域进行反转,仅允许使用malloc动态内存分配,并遵循特定输入输出格式。算法涉及链表的创建、插入以及反转部分结点的操作。

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

(一)问题描述:

        对一个单链表部分区域进行反转。要求编写函数输入链表;编写函数对链表部分区域进行反转;编写函数输出链表。【注意:仅允许使用malloc为n个结点指针分配内存以存储链表数据元素,其中n为第一行数据个数,不允许额外的malloc或者声明数组空间;仅允许操作结点指针,不允许更改结点数据元素如交换两个结点的数据元素;实现上述三个函数。】

(二)输入及输出要求和样例展示:

【输入形式】第一行若干个整数为链表数据元素,中间以空格隔开。第二行正整数 i 和 j ,表示将链表从第 i 个结点到第 j 个结点进行反转,中间以空格隔开。

【输出形式】若干个整数表示反转后的链表数据元素排列,中间以空格隔开。

【样例输入】

  1 2 3 4 5

  2 4
【样例输出】

  1 4 3 2 5

(三)算法分析:

       本题建立在对链表的建立、插入、删除等操作有了初步认识的基础上,进一步地训练对链表的综合运用能力。

      本题主要需要解决以下问题:

【以下为程序分解展示,完整程序在底部】

(1)定义链表的结点类型。链表的结点包括输入的整数值(number)、第几个数(count)、链接指针(struct reverse *next)。

struct reverse{
    int number;
    int count;
    struct reverse *next;
};

(2)利用尾插法,依次创建新的结点,并输入数字,得出是第几个数,存储到结构体中。

struct reverse *cre(void)
{
    struct reverse *head, *p, *rear;
    int number, cou = 1;
    head = NULL; 
    do{
        scanf("%d", &number);
        p = (struct reverse *) malloc (sizeof(struct reverse));
        p -> next = NULL;
        p -> number = number;
        p -> count = cou;
        if(!head){
            head = p;
        }
        else{
            rear -> next = p;
        }
        rear = p;
        cou += 1;
    } while(getchar() != '\n');
    return head;
}

(3)输入链表部分反转的范围,并按照算法【主体部分】将链表反转。

int main(void)
{
    struct reverse *head, *ps, *pe, *pp, *pss, *temp;//创建需要的结构体指针
    int start, end;
    head = cre(); //创建链表
    scanf("%d %d", &start, &end);
    if(head == NULL) return 0; //假如链表是空的,直接结束
    int volume = end - start; //用来判断需要处理几次
    if(start == 1){ //假如start是链表头,以特殊方式处理
        pp = head;
        do{ 
            temp = pp -> next; //temp为原本链表头的下一个结点
            pp -> next = temp -> next; //先将原本链表头与temp的下一个结点连接 
            temp -> next = head; //将temp与当前head相连接
            head = temp; //把链表头head变为temp
            volume -= 1; 
        } while(volume > 0);
    }
    else{ //假如start不是第一个,直接处理
        ps = head;
        while(ps -> count != start - 1) ps = ps -> next; //ps指向start的前一个
        pss = head;
        while(pss -> count != start) pss = pss -> next; //pss指向start
        pp = pss;
        do{
            temp = pss -> next; //与上述类似操作
            pss -> next = temp -> next;
            temp -> next = pp;
            ps -> next = temp; //但要注意与前面的链表相连接
            pp = temp; //pp移动到当前temp处
            volume -= 1;
        } while(volume > 0);
    }
    PrintList(head);
    system("pause");
    return 0;
}

(4)最终输出整个链表。

/*Traverse the linked list*/
void PrintList(struct reverse *head)
{
    struct reverse *p = head;
    while(p)
    {
        printf("%d ", p -> number);
        p = p -> next;
    }
}
(四)程序源码
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
struct reverse{
    int number;
    int count;
    struct reverse *next;
};
struct reverse *cre(void)
{
    struct reverse *head, *p, *rear;
    int number, cou = 1;
    head = NULL; 
    do{
        scanf("%d", &number);
        p = (struct reverse *) malloc (sizeof(struct reverse));
        p -> next = NULL;
        p -> number = number;
        p -> count = cou;
        if(!head){
            head = p;
        }
        else{
            rear -> next = p;
        }
        rear = p;
        cou += 1;
    } while(getchar() != '\n');
    return head;
}
/*Traverse the linked list*/
void PrintList(struct reverse *head)
{
    struct reverse *p = head;
    while(p)
    {
        printf("%d ", p -> number);
        p = p -> next;
    }
}
int main(void)
{
    struct reverse *head, *ps, *pe, *pp, *pss, *temp;//创建需要的结构体指针
    int start, end;
    head = cre(); //创建链表
    scanf("%d %d", &start, &end);
    if(head == NULL) return 0; //假如链表是空的,直接结束
    int volume = end - start; //用来判断需要处理几次
    if(start == 1){ //假如start是链表头,以特殊方式处理
        pp = head;
        do{ 
            temp = pp -> next; //temp为原本链表头的下一个结点
            pp -> next = temp -> next; //先将原本链表头与temp的下一个结点连接 
            temp -> next = head; //将temp与当前head相连接
            head = temp; //把链表头head变为temp
            volume -= 1; 
        } while(volume > 0);
    }
    else{ //假如start不是第一个,直接处理
        ps = head;
        while(ps -> count != start - 1) ps = ps -> next; //ps指向start的前一个
        pss = head;
        while(pss -> count != start) pss = pss -> next; //pss指向start
        pp = pss;
        do{
            temp = pss -> next; //与上述类似操作
            pss -> next = temp -> next;
            temp -> next = pp;
            ps -> next = temp; //但要注意与前面的链表相连接
            pp = temp; //pp移动到当前temp处
            volume -= 1;
        } while(volume > 0);
    }
    PrintList(head);
    system("pause");
    return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值