IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 数据结构链表4-5 -> 正文阅读

[数据结构与算法]数据结构链表4-5

4.已知一个单链表中的数据元素含有三类字符(即字母字符,数字字符和其它字符),试编写算法,构造三个循环链表,使每个循环链表中只含有同一类的字符,且利用原表中的结点空间作为这三个表的结点空间。

大概思路:只有字母,数字和其他字符,可以用char型存储单链表中的数据元素,最后根据ASCII码把元素分为字母,数字,其他三类。由于有三个类,循环链表,需要三个头指针,三个尾指针(尾指针可要可不要,此处是个人习惯),一个记录下一个结点地址的指针

难点:利用原表的结点空间作为三个表的结点空间

ASCII码:48~57表示0~9数字。10,11等两位数以上的数字ASCii码不能直接表示,不过由于该单链表是逐个字符存储的,所以不需要考虑检测两位数以上的数字和负数

65~90 表示A~Z,97~122表示a~z,0~127内的其他数字表示其他字符

template<class T>
bool List4<T>::divede_them_into_three(){
    List4_link<T> *p1;//用来判断当前结点数据类型
    if(first==NULL)
    {   cout<<"空表!";
        return false;}
    p1=first;
    while(p1!=NULL)
    {
        p=p1->next;//记录p1的下一个结点,防止地址丢失
        if(p1->data>=48&&p1->data<=57)
        {
            if(num_number==0)
            {
                first_number=p1;
                tail_number=first_number;
            }
            else
            {
                tail_number->next=p1;
                tail_number=p1;
            }
            num_number++;
        }
        else if((p1->data>=65&&p1->data<=90)||(p1->data>=97&&p1->data<=122))
        {
            if(num_number==0)
            {
                first_alpha=p1;
                tail_alpha=first_alpha;
            }
            else
            {
                tail_alpha->next=p1;
                tail_alpha=p1;
            }
            num_alpha++;
        }
        else{
            if(num_else==0)
            {
                first_else=p1;
                tail_else=first_else;
            }
            else
            {
                tail_else->next=p1;
                tail_else=p1;
            }
            num_else++;
        }
        p1=p;
    }
    tail_number->next=first_number;
    tail_alpha->next=first_alpha;
    tail_else->next=first_else;//形成循环链表
    return true;
}

没想到会这样报错:

这个文件我根本没创建过,莫名其妙地运行了?

难道是Xcode的缓存要清除?需要找到Library/Developer/Xcode/DerivedData,看来看去没有Library,被隐藏了,点开用户文件夹,选择显示‘资源库’文件夹,找到‘DerivedData’文件夹,文件夹内是模拟器运行每个APP生成的缓存文件,全都删了

没用,无奈重建了一个project

重建了一个project正常运行了一段时间,也出现了上述问题,瞎搞一通解决了,目前测试出来的原因是没有把测试用的cpp文件和头文件放在一个文件夹里

?这样放置文件问题解决

其他没什么问题,析构函数要重写,调用divide_them_into_three()前后的析构函数是不一样的

重写的析构函数出了大问题(加一个判断条件,再套三次模板):

template<class T>
List4<T>::~List4(){
    List4_link<T> *pr;
    if(first==NULL)
    {   exit(1);}//无论是否调用divide,first都不会为空
    if((first_number!=NULL)||(first_alpha!=NULL)||(first_else!=NULL))
    {
        if(num_number==1)
            {   delete first_number;
            }
            else
            {   pr=first_number->next;
                while(first_number!=NULL)
                {
                    delete first_number;
                    first_number=pr;
                    pr=pr->next;
                }
            }
        if(num_alpha==1)
            {   delete first_alpha;
            }
            else
            {   pr=first_alpha->next;
                while(first_alpha!=NULL)
                {
                    delete first_alpha;
                    first_alpha=pr;
                    pr=pr->next;
                }
            }
        if(num_else==1)
            {   delete first_else;
            }
            else
            {   pr=first_else->next;
                while(first_else!=NULL)
                {
                    delete first_else;
                    first_else=pr;
                    pr=pr->next;
                }
            }
    }
    else
    {   if(num==1)
        {   delete first;
        }
        else
        {   pr=first->next;
            while(first!=NULL)
            {
                delete first;
                first=pr;
                pr=pr->next;
            }
        }
    }
}

?

看来是释放了两次某空间

错因:忘了是个循环链表,析构函数判断条件不该是头结点为空

改成这样就好(以字母链表为例)

 while(num_alpha!=0)//num_alpha在类中用于记录字母链表结点数
     {
          delete first_alpha;
          first_alpha=pr;
          pr=pr->next;
          num_alpha--;
     }

?总结:析构函数和构造函数随着链表链接方式而改变
5.试编写一个算法,找出一个循环链表中的最小值并删除。

大概思路:弄两个变量AB,A记最小值,不断和下一个结点的数据比,B记录A当前数据是第几个结点的数据,还要考虑删除头结点尾结点中间结点

出现了一个很有意思的问题:在类的public成员函数中,cur_num赋值失败,为什么?

int min,cur_num,count=0;//min记最小数据,cur_num记min中记录的是第几个结点的数据,count记遍历了几个结点
    while(count!=num)
    {
        ++count;
        min=first->data;//min不能初始化为任何数字
        if(p->data<min)
        {
            min=p->data;
            cur_num=count;//cur_num不会被赋值,为什么?
        }
        cout<<min<<" "<<cur_num<<" ";
        p=p->next;
    }

?测试了一下,问题出在count,即使达到了count==num的条件,该循环也没有break,为什么?

输出语句改为

cout<<min<<" "<<cur_num<<" "<<count;

得到:

为什么count加了10?

再改一下循环,使count不进行任何运算,仅在循环前赋予初值0,得到:

?

说明赋值语句对count同样无效,why?

没想通,先睡觉?

酒醒了,是min的初始化语句有问题,要放在循环外,否则无论遍历几遍,min的值始终是头结点的值,所以不是不能给cur_num赋值,产生这种情况有两个原因:1??我测试的数据头结点即为最小,所以该循环不会进入if的判断语句中给cur_num赋值2??cur_num未初始化

正确的代码:

template<class T>
bool List5<T>::find_min()//注意是循环链表
{
    if(first==NULL)
    {
        cout<<"空表!";
        return false;
    }
    List5_link<T> *p,*p_mid,*p_last;
    p=first;
    min=first->data;//min不能初始化为任何数字,只能为第一个的值
    while(count1!=num)//count1用于记录遍历了几个结点
    {
        ++count1;
        if(p->data<min)
        {
            min=p->data;
            cur_num=count1;
        }
        p=p->next;
    }
    p=first;
    count1=0;
    if(cur_num==0)//删除头结点
    {
        p=first->next;
        delete first;
        first=p;
        tail->next=first;//循环链表
    }
    else
    {
        while(count1!=cur_num-2)//p停在要删除的结点前一位,p_mid要删除的结点,p_last要删除的结点后一位
        {//解释一下cur_num-2,因为cur_num最小值为0
            p=p->next;
            p_mid=p->next;
            p_last=p_mid->next;
            count1++;
        }
        if(cur_num==num)
        {
            delete tail;
            tail=p;
            tail->next=first;
        }
        else
        {
            delete p_mid;
            p->next=p_last;
        }
    }
    num--;
    return true;
    
}

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-10-08 21:07:03  更:2022-10-08 21:09:41 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 19:17:44-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码