1.单链表的逆序就是将所以节点逆序过来
解决思路:先遍历所有节点,然后将第一个节点的pNext指向NULL,将第二个节点的pNext指向原来的第一个节点,也就是pH的pNext,并把头节点的pNext指向头插入过来节点的首地址。

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

//构建链表节点
struct node
{
        int data;       //有效数据
        struct node *pNext;     //指向下一个节点的指针

};


//函数功能,创建链表节点
//返回值:指针,指向我们本函数新创建的一个节点的首地址
struct node *creat_node(int data)
{

        //创建一个链表节点
        struct node *p = (struct node *)malloc(sizeof(struct node));
        if(NULL == p)
        {
                printf("malloc error\n");
                return NULL;
        }


        //清理申请到的堆内存
        // void bzero(void *s, size_t n);
        bzero(p,sizeof(struct node));

        //填充节点
        p->data = data;
        p->pNext = NULL;       //将来要指向下一个节点的首地址

        return p;
}

/重头部加入新节点
void insert_head(struct node *pH,struct node *new)
{
         
        //第一步:新节点的pNext指向第一个节点
        new->pNext = pH->pNext;
        //第二部:头结点的pNext指向新节点
        pH->pNext = new;
        //第三部:头结点的计数加1
        pH->data += 1;

}

//单链表遍历函数,pH为单链表的头指针,遍历的节点数据打印出来(无头结点遍历)
void bianli(struct node *pH)
{
        //struct node *p = pH;  头指针后面是头节点这样初始化下面会打印头结点的数据
        struct node *p = pH->pNext;

        printf("开始遍历==================\n");

        //pH->data;     //头结点的数据,不算链表的常规数据
        while(NULL != p->pNext)
        {
                printf("node data = %d\n",p->data);
                p = p->pNext;
        }

        printf("node data = %d\n",p->data);     //这种方法解决了最后一个节点内内打印不出来的问题,但效果不好
        printf("遍历完成==================\n");


}

//有头节点遍历
void bianli2(struct node *pH)
{
        struct node *p = pH;  //头指针后面是头节点这样初始化下面会打印头结点的数据

        printf("开始遍历==================\n");

        while(NULL != p->pNext)
        {
                p = p->pNext;
                printf("node data = %d\n",p->data);
        }

        printf("遍历完成==================\n");
}

//将pH指向的链表逆序
void reverse_linklist(struct node *pH)
{
        struct node *p = pH->pNext;     //
        struct node *pBack;

        if((NULL == p) || (NULL == p->pNext))//当链表没有有效节点或只有一个有效节点直接返回
        {

                return;
        }

        while(NULL != p->pNext) //判断是不是最后一个节点
        {
                pBack = p->pNext;       //保存p节点后面一个节点的地址
                if(p == pH->pNext)      //判断是否为链表的第一个有效节点
                {
                        p->pNext = NULL;
                }
                else
                {
                        p->pNext = pH->pNext;
                }
                pH->pNext = p;
                //p=p->pNext;      这里不能这样写,因为p->pNext在前面已经改变,p和p->pNext已经失去联系
                p = pBack;
        }

                insert_head(pH,p);	//将最后一个节点打印出来


}

int main(void)
{
        //定义头指针
        //struct node *pHeader = NULL;  这里如果把pHeader赋值为NULL在加入节点这个函数内就会出现段错误
        struct node *pHeader = creat_node(0);

        insert_head(pHeader,creat_node(1));

        insert_head(pHeader,creat_node(2));

        insert_head(pHeader,creat_node(3));


        printf("header node data = %d\n",pHeader->data);        //打印有多少个节点

        //bianli(pHeader);
        printf("逆序前================\n");
        bianli2(pHeader);
        reverse_linklist(pHeader);
        printf("逆序后================\n");
        bianli2(pHeader);

        return 0;
}