反转链表

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

思路:

假设有链表A->B->C->D->E->F->G。在反转链表过程中的某一阶段,其链表指针指向为:A<-B<-C<-D  E->F->G。也就是说在结点D之前的所有结点都已经反转,而结点D后面的结点E开始的所有结点都没有反转。这样D跟E之间存在了断裂,所以不仅需要保存当前结点和它的前一个结点,还需要保存当前结点的下一个结点,一共需要3个指针来操作

第一个指针pre用来保存当前结点的前一个结点

第二个指针now用来指向当前结点

第三个指针用来保存当前结点的下一个指针,因为反转当前结点的指针时:now->next=pre,会丢失now->next

代码如下:

struct listnode
{
    int data;
    listnode *next;
};
//下面所用的链表头结点都是空的
//尾插法创建链表
listnode *init()
{
    listnode *head=(listnode *)malloc(sizeof(listnode));
    head->next=NULL;
    listnode *p=head;
    cout<<"please input a number(按-1结束)"<<endl;
    int data;
    cin>>data;
    while(data!=-1)
    {
        listnode *temp=(listnode *)malloc(sizeof(listnode));
        temp->data=data;
        temp->next=p->next;
        p->next=temp;
        p=temp;
        cout<<"please input a number(按-1结束)"<<endl;
        cin>>data;
    }
    return head;
}
//打印链表
void print(listnode *head)
{
    listnode *p=head->next;
    while(p)
    {
        cout<<p->data<<"    ";
        p=p->next;
    }
    cout<<endl;
}
//反转链表(使用三个指针分别指向当前结点,当前结点的前一个结点和当前结点的下一个结点)
listnode *reverselist(listnode *head)
{
    if(head==NULL)
        return NULL;
    listnode *now=head->next;//当前结点
    listnode *newhead=(listnode *)malloc(sizeof(listnode));//新结点的头指针
    newhead->next=NULL;
    //只有一个结点,头结点(空)
    if(now==NULL)
        return head;
    listnode *pre=NULL;//当前结点的前一个结点
    while(now !=NULL)
    {
        listnode *pnext=now->next;        //保存当前结点的下一个结点
        //如果当前结点的下一个结点为空,则构建新的头结点
        if(now->next==NULL)
        {
            newhead->next=now;
        }
        //将当前结点的next指向它的前一个结点
        now->next=pre;
        //pre和now指针都后移
        pre=now;
        now=pnext;
        
    }
    return newhead;
}

测试代码以及运行结果:

int main()
{
    listnode *head=init();
    print(head);
    head=reverselist(head);
    print(head);
    return 0;
}

原文地址:https://www.cnblogs.com/runninglzw/p/4530273.html