鱼C论坛

 找回密码
 立即注册
查看: 2341|回复: 6

链表查询问题,懂得帮我看下。

[复制链接]
发表于 2014-9-14 14:15:24 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 acreil 于 2014-9-16 20:44 编辑

写的一个链表,比较复杂。
有个检查序列是不是重复的函数,当链表有两条以上的记录的时候,在检查到重复,退出的时候,程序会崩溃。。。
附上代码图。
QQ图片20140914140606.png


QQ图片20140914141226.png


这个是查询函数

QQ图片20140914141240.png

调用代码。

QQ图片20140914141244.png
把网盘地址附上。。只有一个main.cpp文件,,应用台程序。。。麻烦大家看下。
http://pan.baidu.com/s/1bnvTgf1

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2014-9-14 15:15:26 | 显示全部楼层
代码多的话就把工程整个发过来,网盘或者附件什么的都可以。你发的这些代码看不出有什么逻辑错误。不调试很难找出错误。尤其是你那个退出代码,只给一部分,很难理解你是打算做什么。。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-9-14 21:44:59 | 显示全部楼层
重新把文件附上了,大家帮忙看下。。。有不足的地方也请指出。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-9-15 09:37:37 | 显示全部楼层
本帖最后由 musilintan 于 2014-9-15 09:40 编辑
book* insert(book* head)
{
        string num;
    string price;
    book *temp = head;
        if (head != NULL)
        {
                while (temp->next)
                {
                        temp = temp->next;
                }
        }
    book *temp_next = NULL;
    do
    {
        cout << "请输入书籍的编号:";
        cin >> num;
        while (check_int(num))
        {
            
            cout << "你输入的格式有错误,请重新输入."<<endl;
            cout << "请输入书籍的编号:";
            cin >> num;
        }
                while (find_num(head, num))
                {

                        cout << "已存在编号,请重新输入." << endl;
                        cout << "请输入书籍的编号:";
                        cin >> num;
                }
        if (num == "0")
        {
                        if (temp)
                        {
                                return head;
                        }
                        else if (temp->next==NULL)
                        {
                                return head;
                        }
                        else
                        {
                                temp_next->next = NULL;
                                return head;
                        }
        }
        cout << "请输入书籍的价格:";
        cin >> price;
        while (check_float(price))
        {
            cout << "你输入的格式有错误,请重新输入."<<endl;
            cout << "请输入书籍的价格:";
            cin >> price;
        }
        if (num == "0")
        {
                        if (temp == NULL)
                        {
                                return head;
                        }
                        else if (temp_next == NULL)
                        {
                                return head;
                        }
                        else
                        {
                                temp_next->next = NULL;
                                return head;
                        }
                }
        temp_next = new book;
        temp_next->num = atoi(num.c_str());
        temp_next->price = (float)atof(price.c_str());
                temp_next->next = NULL;                        //这里
                if (head == NULL)
                {
                        temp = temp_next;
                        head = temp;
                }
                else if (temp->next == NULL)
                {
                        temp->next = temp_next;
                }
                else
                {
                        temp = temp->next;
                        temp->next = temp_next;
                }
    } while (true);
}

你的思路没问题,引起错误的原因是再查询函数里面。而最终的病因是因为创建的新节点的next指针没有制NULL导致的。所以在查询的时候会出现无限查询,直到差出链表的范围,最终报错。
程序本身的整体思路很好,只是链表方面的思路比较乱,多看看别人的代码,提高空间很大。
创建节点时需要注意2点:
1.当前节点和上一个节点的联系有没有建立。
2.当前节点的next指针有没有为NULL。
上面的注意事项针对的是链表尾插法。
不过,要是养成下面这个习惯,就会在以后编程中,为你减少很多不必要麻烦。
这是你的代码:
class book
{
public:
    int num;
    float price;
    book *next;
};
改进后:
class book
{
public:
    int num;
    float price;
    book *next;
        
public:
        book()
        {
                num = -1;
                price = 0.0;
                next = NULL;
        }
};
加一个初始化进去,这样做以后就不用考虑next指针是否为NULL了。在创建链表的时候,会自动将next制空。结构体同样可以这样做。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-9-15 10:36:18 | 显示全部楼层
        if (num == "0")
                {
                        if (temp)
                        {
                                return head;
                        }
                        else if (temp->next == NULL)
                        {
                                return head;
                        }
                        else
.....
这段代码你想做什么?输入0则返回head么??


我看了一下你的程序,修改了一些,,如下:
//  main.cpp
//  ConsoleApplication
//
//  Created by 廖庆飞 on 14/9/9.
//  Copyright (c) 2014年 廖庆飞. All rights reserved.
//

#include<iostream>
#include<string>

using namespace std;

class book
{
public:
    int num;
    float price;
    book *next;
};

book* creat();
book* delete_node(book*);
int delete_all(book*);
void find(book*);
bool find_num(book*,string);
book* insert(book*);
book* sort(book*);
bool check_int(string);
bool check_float(string);
int showbook(book*);

int main(int argc, const char * argv[])
{
        string str;
        int i;
        book *head = NULL;
        while (true)
        {
                cout << "1.重建图书2.添加图书3.删除图书4.图书排序5.图书查找6.显示图书7.屏幕清除0.程序退出" << endl;
                cin >> str;
                while (check_int(str))
                {

                        cout << "你输入的格式有错误,请重新输入." << endl;;
                        cout << "请输入选项编号:";
                        cin >> str;
                }
                
                if (str == "0")
                {
                        delete_all(head);
                        return 0;
                }
                
                i = atoi(str.c_str());
                
                switch (i)
                {
                case 1:
                        if (head == NULL)
                        {
                                head = creat();
                        }
                        else
                        {
                                delete_all(head);
                                head = creat();
                        }
                        break;
                case 2:
                        head = insert(head);
                        break;
                case 3:
                        head = delete_node(head);
                        break;
                case 4:
                        head = sort(head);
                        break;
                case 5:
                        find(head);
                        break;
                case 6:
                        showbook(head);
                        break;
                case 7:
                        system("cls");
                        break;
                default:
                        cout << "对不起,没有这个选项." << endl;
                        break;
                }
        }
        
    return 0;
}
//--------------------create---------------------------------
book *creat()
{
    string num;
    string price;
    book *head = NULL;
        book *temp = NULL;
    book *tail = head;
    while(tail!=NULL && tail->next !=NULL) //找到链表的尾 
        {
            tail = tail->next;
    }
    
    do
    {
        cout << "请输入书籍的编号:";
        cin >> num;
        while (check_int(num))
        {
            
                        cout << "你输入的格式有错误,请重新输入." << endl;;
            cout << "请输入书籍的编号:";
            cin >> num;                          //输入格式错误后重新输入 
        }
        
                while (find_num(head,num))
                {

                        cout << "已存在编号,请重新输入." << endl;
                        cout << "请输入书籍的编号:";
                        cin >> num;
                }
                
                if (num == "0")
                {
                        if(head)
                        {
                                return head;
                        }
                        cout<<"没有创建新图书"<<endl; 
                        return NULL;                
                }
        cout << "请输入书籍的价格:";
        cin >> price;
        while (check_float(price))
        {
                        cout << "你输入的格式有错误,请重新输入." << endl;
            cout << "请输入书籍的价格:";
            cin >> price;
        }
                if (price == "0")
                {
                        if(head)
                        {
                                return head;
                        }
                        cout<<"没有创建新图书"<<endl; 
                        return NULL;                
                }
        temp=new book;
        temp->num = atoi(num.c_str());
        temp->price = (float)atof(price.c_str());
        temp->next = NULL;
        if (head == NULL)
        {
                head=temp;
                tail=head;
        }
                        
        else
        {
            tail->next=temp;
            tail=temp;
        }
    } while (true);
}

//---------------------------------------------check_int

//检测输入的字符是否为数字字符
//若是返回false,否则返回true 
bool check_int(string str)
{
    for (unsigned i = 0; i < str.length();i++)
    {
                if (str[i] > '9' || str[i] < '0')
        {
            return true;
        }
    }
    return false;
}

///--------------------------------------------check_float
bool check_float(string str)
{
    int ax = 0;//用来控制小数点的个数
    for (unsigned i = 0; i < str.length(); i++)
    {
        if (str[i] == '.')
        {
            ax += 1;
        }
        if (ax > 1)
        {
            return true;
        }
        if (str[i] > '9' || str[i] < '.' || str[i] == '/')//由于0到.之间的ASSCII只有一个'/'所把'/'字符排除
        {
            return true;
        }
    }
    return false;
}

//-----------------------------------------------showbook
int showbook(book *head)
{
    if (head == NULL)
    {
        cout << "没有图书信息." << endl;
        return 0;
    }
    while (head)
    {
                cout << "编号:\t" << head->num << "\t" << "价格:\t" << head->price << endl;
        head = head->next;
    }
    return 0;
}
//-------------------------------------------delete_node 
book *delete_node(book* head)
{
    if (head == NULL)
    {
        cout << "没有数据." << endl;
        return head;
    }
    string str;
    cout << "请输入查找的编号:";
    cin >> str;
    while (check_int(str))
    {
        
                cout << "你输入的格式有错误,请重新输入." << endl;
        cout << "请输入查找的编号:";
        cin >> str;
    }
    if (str == "0")
    {
        return head;
    }
    int num = atoi(str.c_str());
    book* temp = head;
    book*temp_two = NULL;
    if (head->num == num)
    {
        temp = head->next;
        delete head;
        head = temp;
        cout << "删除完成";
        return head;
    }
    else
    {
        while (head)
        {
            temp_two = temp->next;
            if (temp_two->num == num)
            {
                if (temp_two->next == NULL)
                {
                    delete temp_two;
                    temp->next = NULL;
                    return head;
                }
                temp->next = temp_two->next;
                delete temp_two;
                cout << "删除完成." << endl;
                return head;
            }
            else
            {
                temp = temp_two->next;
            }
        }
    }
    cout << "没有查找到输入的相关数据." << endl;
    return head;
}
//======---------------------------------------delete_all 0
int delete_all(book* head) 
{
    if (head == NULL)
    {
        cout << "没有数据." << endl;
        return 0;
    }
    else
    {
        book *temp = NULL;
        while (head)
        {
            temp = head->next;
            delete head;
            head = temp;
        }
    }
    if(head == NULL)
            cout << "删除成功." << endl;
           else
                   cout<<"删除失败"<<endl; 
    return 0;
}
///------------------------------------------------find
void find(book* head)
{
    if (head == NULL)
    {
        cout << "没有数据." << endl;
        return;
    }
    string str;
    cout << "请输入查找的编号:";
    cin >> str;
    while (check_int(str))
    {
        
                cout << "你输入的格式有错误,请重新输入." << endl;
        cout << "请输入查找的编号:";
        cin >> str;
    }
    if (str == "0")
    {
        return;
    }
    int num = atoi(str.c_str());
    while (head)
    {
        if (head->num == num)
        {
            cout << "图书编号:" << head->num << endl;
            cout << "图书价格:" << head->price << endl;
            return;
        }
        else
        {
            head = head->next;
        }
    }
    cout << "没有查找到相关数据." << endl;
    return;
}

//=--------------------------------------------find_num
//寻找链表中是否存在输入序列
//若是返回true,否则false 
bool find_num(book* head,string str)
{
        if (head == NULL)
        {
                return false;
        }
        
        int num=atoi(str.c_str());
        book *temp = head;
        while (temp)
        {
                if (temp->num == num)
                {
                        return true;
                }
                temp = temp->next;
        }
        return false;
}
//----------------------------------------insert  这里和create内部实现基本一样,是否考虑封装一下 
book* insert(book* head)
{
        string num;
    string price;
    book *temp=NULL;
    book *tail = head;
        if (head != NULL)
        {
                while (tail->next)
                {
                        tail = tail->next;  //寻找链表尾 
                }
        }
        
   do
    {
        cout << "请输入书籍的编号:";
        cin >> num;
        while (check_int(num))
        {
            
                        cout << "你输入的格式有错误,请重新输入." << endl;;
            cout << "请输入书籍的编号:";
            cin >> num;                          //输入格式错误后重新输入 
        }
        
                while (find_num(head,num))
                {

                        cout << "已存在编号,请重新输入." << endl;
                        cout << "请输入书籍的编号:";
                        cin >> num;
                }
                
                if (num == "0")
                {
                        if(head)
                        {
                                return head;
                        }
                        cout<<"没有创建新图书"<<endl; 
                        return NULL;                
                }
        cout << "请输入书籍的价格:";
        cin >> price;
        while (check_float(price))
        {
                        cout << "你输入的格式有错误,请重新输入." << endl;
            cout << "请输入书籍的价格:";
            cin >> price;
        }
                if (price == "0")
                {
                        if(head)
                        {
                                return head;
                        }
                        cout<<"没有创建新图书"<<endl; 
                        return NULL;                
                }
        temp=new book;
        temp->num = atoi(num.c_str());
        temp->price = (float)atof(price.c_str());
        temp->next = NULL;
        if (head == NULL)
        {
                head=temp;
                tail=head;
        }
                        
        else
        {
            tail->next=temp;
            tail=temp;
        }
    } while (true);
}

///----------------------------------------------------------sort  4
book* sort(book* head)
{
    if (head == NULL)
    {
                cout << "没有数据" << endl;
        return NULL;
    }
        /*
    book *p=head, *p1=NULL, *p2=NULL, *p3=NULL,*temp;
        p1 = p->next;
        p2 = p1->next;
        if (p > p1)   //这个地址有什么可排列的。。。 
        {
                temp = p;
                p = p1;
                p = temp;
                head = p;
                if (p2 == NULL)
                {
                        return head;
                }
                p = p->next;
                p1 = p1->next;
                p2 = p2->next;
        }
        do
        {
                if (p1 > p2)
                {
                        p3 = p2->next;
                        temp = p1;
                        p1 = p2;
                        p2 = temp;
                        p->next = p1;
                        p1->next = p2;
                        p2->next = p3;
                }
                p = p->next;
                p1 = p1->next;
                p2 = p2->next;
        } while (p3);
        */
        //实现一个按序号排列  冒泡
        
        book * tempf = head; //链表前面节点 
        book * tempb = head; //链表 后面节点 
        int temp;
        while(tempb=tempf){
                while(tempb){
                        if(tempf->num > tempb->num)
                        {
                                temp =  tempb->num;
                                tempb->num = tempf->num;
                                tempf->num = temp;
                        }
                        tempb=tempb->next;    //指向下一个节点 
                }
                tempf=tempf->next;
        }        
        cout<<"结束排列!"<<endl;
    return head;
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-9-16 20:28:39 | 显示全部楼层
musilintan 发表于 2014-9-15 09:37
你的思路没问题,引起错误的原因是再查询函数里面。而最终的病因是因为创建的新节点的next指针没有制NU ...

嗯,看明白了,是在插入方法里面忘记对next赋NULL,导致在下一次的输入,在检查重复,调用了未知指针。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-9-16 20:42:55 | 显示全部楼层
elvo 发表于 2014-9-15 10:36
if (num == "0")
                {
                        if (temp)

刚开始写链表,有些方法确实用得比较笨。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-25 02:01

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表