链表查询问题,懂得帮我看下。
本帖最后由 acreil 于 2014-9-16 20:44 编辑写的一个链表,比较复杂。
有个检查序列是不是重复的函数,当链表有两条以上的记录的时候,在检查到重复,退出的时候,程序会崩溃。。。
附上代码图。
这个是查询函数
调用代码。
把网盘地址附上。。只有一个main.cpp文件,,应用台程序。。。麻烦大家看下。
http://pan.baidu.com/s/1bnvTgf1
代码多的话就把工程整个发过来,网盘或者附件什么的都可以。你发的这些代码看不出有什么逻辑错误。不调试很难找出错误。尤其是你那个退出代码,只给一部分,很难理解你是打算做什么。。。 重新把文件附上了,大家帮忙看下。。。有不足的地方也请指出。 本帖最后由 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制空。结构体同样可以这样做。 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 > '9' || str < '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 == '.')
{
ax += 1;
}
if (ax > 1)
{
return true;
}
if (str > '9' || str < '.' || str == '/')//由于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);
}
///----------------------------------------------------------sort4
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;
}
musilintan 发表于 2014-9-15 09:37
你的思路没问题,引起错误的原因是再查询函数里面。而最终的病因是因为创建的新节点的next指针没有制NU ...
嗯,看明白了,是在插入方法里面忘记对next赋NULL,导致在下一次的输入,在检查重复,调用了未知指针。 elvo 发表于 2014-9-15 10:36
if (num == "0")
{
if (temp)
刚开始写链表,有些方法确实用得比较笨。。
页:
[1]