反转链表

【题目】

定义一个函数,输入一个链表的头结点,反转该链表并输出反转后的链表的头结点。


【分析】

单链表的延伸题,基本单链表如前面博客里所述方法创建,对于反转链表,实现的过程就是遍历一个结点,记录他的前一节点,让现在的结点的下一指针指向前一结点,但是为了保证可以继续遍历原下一节点,不造成断节,还需要注意保证结点的原下一个节点也被保存,同时要注意到检查到最后一个结点就是反转链表的头结点。基本过程如下所示:

这里写图片描述

先看pNode是否为空,为空说明遍历完毕(或者链表本来就是空的,但是不影响),否则循环下一过程:
1. 先把当前节点的下一节点存下来,判断当前节点是不是尾结点,尾结点就是反转链表头结点,否则,进入第2步;
2. 经过第1步,保证了待会可以沿着原链表继续遍历,所以放心的进行这步,让当前节点指向前一节点;
3. 进入第3步说明当前节点和前一节点关系已经反转完,所以当前节点将作为原链表中下一节点中的前一节点。


【测试代码】

#include<stdio.h>
#include<stdlib.h>

typedef int data_type;

typedef struct Node node_t;// 给struct Node取个别名node_t
typedef struct Node * node_ptr;//给struct Node*取个别名node_ptr

typedef struct Node
{
    data_type data;
    struct Node *node_next;//node_next是一个指向结构的指针,告诉指针要指向的地址就要付给它一个结构类型地址
};

//链表初始化
node_t * init()
{
    node_ptr p;
    p = (node_t *)malloc(sizeof(node_t));
    p->node_next = NULL;
    return p;
}
//在链表后面插入结点
node_t *insert_back(node_ptr p , data_type data)
{


    node_ptr pnew = (node_t *)malloc(sizeof(node_t));
    pnew ->node_next = NULL;
    pnew ->data = data;

    p->node_next = pnew;

    return pnew;
}


node_t * reverse(node_ptr p)
{
    node_ptr pReverseHead = NULL;
    node_ptr pNode = p;
    node_ptr pre = NULL;

    while(pNode != NULL)
    {
        node_ptr pnext = pNode->node_next;
        if(pNode->node_next == NULL)
            pReverseHead = pNode;

        pNode->node_next = pre;

        pre = pNode;
        pNode = pnext;
    }

    return pReverseHead;

}
//正常打印
void print(node_ptr p)
{
    if(!p)
    {
            printf("no data, you think too much");
            return ;
    }
    node_ptr list = p;
    while(list->node_next != NULL)
    {
        printf("%d ", list->data);
        list = list->node_next;
    }
    printf("%d ",list->data);
    printf("\n");

}



void main()
{
    node_ptr pnode, list;
    pnode = init();
    list = pnode;

    pnode = insert_back(pnode, 1);
    pnode = insert_back(pnode, 2);
    pnode = insert_back(pnode, 3);
    pnode = insert_back(pnode, 4);
    pnode = insert_back(pnode, 5);
    pnode = insert_back(pnode, 6);
    printf("正常单链表顺序为:");
    print(list->node_next);
    printf("头结点元素为:%d\n", list->node_next->data);
    printf("\n");
    node_t *reverse_list_head= reverse(list->node_next);
    printf("反转单链表顺序为:");
    print(reverse_list_head);
    printf("头结点元素为:%d\n",reverse_list_head->data);
    printf("\n");

}

【输出】
这里写图片描述


【递归实现】

#include<stdio.h>
#include<stdlib.h>

typedef int data_type;

typedef struct Node node_t;// 给struct Node取个别名node_t
typedef struct Node * node_ptr;//给struct Node*取个别名node_ptr

typedef struct Node
{
    data_type data;
    struct Node *node_next;//node_next是一个指向结构的指针,告诉指针要指向的地址就要付给它一个结构类型地址
};

//链表初始化
node_t * init()
{
    node_ptr p;
    p = (node_t *)malloc(sizeof(node_t));
    p->node_next = NULL;
    return p;
}
//在链表后面插入结点
node_t *insert_back(node_ptr p , data_type data)
{


    node_ptr pnew = (node_t *)malloc(sizeof(node_t));
    pnew ->node_next = NULL;
    pnew ->data = data;

    p->node_next = pnew;

    return pnew;
}

//递归反转单链表
void reverse_rec(node_ptr proot, node_t **head)
{
    if(proot == NULL)
        return ;
    if(proot->node_next == NULL)
    {
        *head = proot;
        return ;
    }
    reverse_rec(proot->node_next, head);

    proot->node_next ->node_next= proot;
    proot->node_next = NULL;    
}

//正常打印
void print(node_ptr p)
{
    if(!p)
    {
            printf("no data, you think too much");
            return ;
    }
    node_ptr list = p;
    while(list->node_next != NULL)
    {
        printf("%d ", list->data);
        list = list->node_next;
    }
    printf("%d ",list->data);
    printf("\n");

}



void main()
{
    node_ptr pnode, list;
    pnode = init();
    list = pnode;

    pnode = insert_back(pnode, 1);
    pnode = insert_back(pnode, 2);
    pnode = insert_back(pnode, 3);
    pnode = insert_back(pnode, 4);
    pnode = insert_back(pnode, 5);
    pnode = insert_back(pnode, 6);
    printf("正常单链表顺序为:");
    print(list->node_next);
    printf("头结点元素为:%d\n", list->node_next->data);
    printf("\n");
    reverse_rec(list->node_next, &list);
    printf("反转单链表顺序为:");
    print(list);
    printf("头结点元素为:%d\n",list->data);
    printf("\n");

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值