链表的反转—c++版本

一、迭代反转法

过程分析: 链表的反转—c++版本_第1张图片

代码实现: 

#include 

struct LinkNode{ //创建一个结构体做为链表的结点
    int data;           //数据域
    LinkNode* next;  //指针域
};

void Print_Link(LinkNode* phead)     //打印链表
{
    while (phead != nullptr)
    {
        std::cout << phead->data << " ";
        phead = phead->next;
    }
    std::cout << std::endl;
}

LinkNode* inverse(LinkNode* phead)      //链表反转函数
{
    if (phead == nullptr || phead->next == nullptr)   //判断头指针是否指向链表头结点,或者链表是否存在
        return phead;

    LinkNode* pre_current = nullptr;
    LinkNode* current = phead;
    LinkNode* next_current = phead->next;

    while (1)            //遍历链表
    {
        current->next = pre_current;        //修改current指向的结点的指针域,令其指向pre_current所指的结点
        if (next_current == nullptr)         //判断next_current是否为空,如果为空表示链表已经遍历完毕
            break;
        pre_current = current;          //整体偏移三个指针
        current = next_current;
        next_current = next_current->next;
    }
    phead = current;        //遍历结束后,链表完成反转,修改头指针指向新的链表头结点

    return phead;
}

int main()
{
    LinkNode t6 = { 6,nullptr };
    LinkNode t5 = { 5,&t6 };      //只为做验证,用了静态创建链表的方式,实际中一般不会用这种方式
    LinkNode t4 = { 4,&t5 };
    LinkNode t3 = { 3,&t4 };
    LinkNode t2 = { 2,&t3 };
    LinkNode t1 = { 1,&t2 };

    LinkNode* head = &t1;        //创建头指针,用此方法反转链表可以不需要用到头指针,后面的函数的形参可以直接使用&t1,结果是一样的

    std::cout << "链表反转前元素为:\n";
    Print_Link(head);
    std::cout << "链表反转后元素为:\n";
    head = inverse(head);
    Print_Link(head);

    return 0;
}

运行结果:

链表的反转—c++版本_第2张图片

 错误代码示例1:

LinkNode* inverse(LinkNode* phead)      //链表反转函数
{
    if (phead == nullptr || phead->next == nullptr)   //判断头指针是否指向链表头结点,或者链表是否存在
        return phead;

    LinkNode* pre_current = nullptr;
    LinkNode* current = phead;
    LinkNode* next_current = phead->next;

    while (current != nullptr)            //遍历链表
    {
        current->next = pre_current;        //修改current指向的结点的指针域,令其指向pre_current所指的结点
        pre_current = current;          //整体偏移三个指针
        current = next_current;
        next_current = next_current->next;
    }
    return current;
}

错误出处:while循环中的第四行代码报错,该行代码引发了异常:读取访问权限冲突。next_current 是 nullptr。

错误分析:(以6个不带头节点的元素的链表为例)

链表的反转—c++版本_第3张图片

错误代码示例2: 

LinkNode* inverse(LinkNode* phead)      //链表反转函数
{
    if (phead == nullptr || phead->next == nullptr)   //判断头指针是否指向链表头结点,或者链表是否存在
        return phead;

    LinkNode* pre_current = nullptr;
    LinkNode* current = phead;
    LinkNode* next_current = phead->next;

    while (next_current != nullptr)            //遍历链表
    {
        current->next = pre_current;        //修改current指向的结点的指针域,令其指向pre_current所指的结点
        pre_current = current;          //整体偏移三个指针
        current = next_current;
        next_current = next_current->next;
    }
    return current;
}

 错误出处:while循环判断条件有误。
错误运行结果如下:

链表的反转—c++版本_第4张图片

        我们可以看到,反转前的链表元素为1 2 3 4 5 6,但执行上述代码之后,反转后的链表却只有一个元素。

错误原因:

链表的反转—c++版本_第5张图片

        我们可以检验6这个节点之前的子链表是否正确,我们可以将上述代码段返回语句return current;改写成return pre_current;运行修改后的程序,得到如下结果: 

 

后续方法待更新!!! 

你可能感兴趣的:(C++,链表,c++,数据结构)