循环链表示例:求解约瑟夫问题

本文介绍了在解决约瑟夫问题时遇到的Debug Assertion Failed错误,该错误源于在循环链表操作中直接连接节点并删除中间节点,导致循环链表的last指针指向已被释放的节点。作者分析了错误原因,并提供了完整的约瑟夫问题解决方案,包括循环单链表模板类和主函数。最后强调了数据结构学习的重要性,鼓励读者多加实践。
摘要由CSDN通过智能技术生成

错误:Debug Assertion Failed!
这里写图片描述
今天花了好久才解决了本篇文章中的一个错误,代码bug当然是不可避免的,但是我们可以尽可能的优化他,减少他。
错误分析:主要原因是求解约瑟夫环的问题时,使用了我上一篇文章的循环单链表的模板类,但是我在实际求解中并没有用模板类中的Remove(删除)这个成员函数(不用是因为我定义的删除函数本身的局限性造成的),直接是
preNode = currNode;
 currNode =currNode->link;
 也就是直接把前后两个节点建立连接,再释放要删除的节点,那么问题来了,这个时候私有成员last(即始终指向循环单链表尾节点的指针)并没有得到更新,也就是说last指向的节点在早已经被delete(释放)了,在主函数main返回的时候,系统调用析构函数的时候会对last指向的节点再一次释放,图中错误就应运而生了!(这是我一个多小时的分析结果,如有不当,希望大牛指正!)。下面贴出错误处的代码:
 析构函数
 约瑟夫处理函数中的错误
好了,现在贴出整个约瑟夫问题的处理(包括循环单链表的模板类和主函数),约瑟夫环是循环单链表的一个重要应用,也是一个很实用的问题,希望大家都能够掌握,如有不当,万望指正、批评!
//模板类

//循环链表模板class
#include <iostream>
using namespace std;

template<class T>
struct CircleLinkNode {
    T data;
    CircleLinkNode<T> *link;
    //构造函数
    CircleLinkNode(CircleLinkNode<T> * next = NULL) : link(next) {}
    CircleLinkNode(T d, CircleLinkNode<T> * next = NULL) : data(d), link(next) {}
};

template<class T>
class CircleList {
public:
    CircleList(const T & x);                        //构造函数
    CircleList(CircleList<T> & L);                  //复制构造函数
    ~CircleList();                                 //析构函数
    int Length() const;                             //计算循环链表的长度
    bool IsEmpty()
    {
        return first->link == first ? true : false; //判断是否是空表
    }
    CircleLinkNode<T> * getHead() const;            //返回附加头节点的地址
    void setHead(CircleLinkNode<T> * p);            //设置附加头节点的地址
    CircleLinkNode<T> * Search(T x);                //搜索含数据x的节点
    CircleLinkNode<T> * Locate(int i);              //搜索第i个元素的地址
    T getData(int i);                               //取出第i个元素的值
    void setData(int i, T & x);        
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值