//14 使用链表
#include <iostream>
#include <string>
using namespace std;
//定义一个结构体
class book
{
public:
int num;
float price;
book *next;
};
//定义一个全局的头指针
book *head=NULL;
//定认一个判断用户是否是输入的数字字符
bool check(string str)
{
for(int i=0; i<str.length(); i++)
{
if((str[i] >= '0' && str[i] <= '9') || str[i] == '.')
{
return true;
}else{
return false;
}
}
return false;
}
book *create()
{
book *p1, *p2; //定义两个book指针
p1 = new book; //实例化p1指针
head = p1; //将p1指针赋值给head
p2 = p1;
//到现在,p1 p2 head都是指向对一个地址
cout<<"输入图书的编号,以0结束"<<endl;
string str;
cin>>str;
while(!check(str)){
cout<<"输入的不是数字,请重新输入,按0返回!!!"<<endl;
cin>>str;
}
p1->num= atoi(str.c_str()); //atoi是将一个string型转换成int型的函数
//str.c_str(); atoi函数接收的是一个char型,str.c_str()将string型转换为char型
if(p1->num != 0)
{
cout<<"请输入图书价格"<<endl;
cin>>str;
while(!check(str)){
cout<<"输入的不是数字,请重新输入,按0返回!!!"<<endl;
cin>>str;
}
p1->price = atof(str.c_str()); //这里的atof,是将string型转换为float型
}else{
//如果用户退出,那么这里要清理变量
delete p1;
p2 = NULL;
head = NULL;
p2->next = NULL;
return head;
//唉这里还是不够细心,逻辑还是不行啊
}
//如果p1的num不为0就一直循环
while(p1->num != 0)
{
p2 = p1; //将上一次的指针给p2来保存
p1 = new book; //重新new p1,上次就是这里出错了,查了很久哦
cout<<"输入图书的编号,以0结束"<<endl;
string str;
cin>>str;
while(!check(str)){
cout<<"输入的不是数字,请重新输入,按0返回!!!"<<endl;
cin>>str;
}
p1->num= atoi(str.c_str()); //atoi是将一个string型转换成int型的函数
if(p1->num != 0)
{
cout<<"请输入图书价格"<<endl;
cin>>str;
while(!check(str)){
cout<<"输入的不是数字,请重新输入,按0返回!!!"<<endl;
cin>>str;
}
p1->price = atof(str.c_str()); //这里的atof,是将string型转换为float型
}
p2->next = p1;
}
delete p1;
//p1->next = NULL;
p2->next = NULL; //p1都已经被删除了,不知道还next设置为null干嘛
return head;
}
void showbook(book *head)
{
cout<<endl;
cout<<"图书信息如下:"<<endl;
while(head)
{
cout<<"图书的编号是:"<<head->num<<", 图书的价格是:"<<head->price<<endl;
head = head->next;
}
}
void insert(book *head, int num, float price)
{
book *newbook = new book;
newbook->num = num;
newbook->price = price;
//现在的插入是按num的顺序进行插入
if(head->num > num){
newbook->next = head; //那将newbook放在第一个节点前面,然后将地址赋值给全局的head指针
::head = newbook;
return;
}else{
book *list = NULL;
while(head->num < num && head->next != NULL)
{
list = head;
head = head->next;
}
//现在的list是上一个值,head是最后一个值
if(head->num < num) //现在只有插入的节点的最后了
{
head->next = newbook;
newbook->next = NULL;
}else{
//这里进行中间插入法
list->next = newbook;
newbook->next = head;
}
}
}
//删除成功返回true, 失败返回false
bool Delete(book *head, int num)
{
//删除有以下几处情况,如果删除的是第一个节点
if(head->num == num)
{
::head = head->next;
delete head;
return true;
}else{
book *tmp = NULL;
while(head)
{
if(head->next == NULL)
{
return false;
}
if(head->next->num == num)
{
tmp = head->next;
head->next = tmp->next;
delete tmp;
return true;
}
head = head->next;
}
}
}
int getBookNum(book* head)
{
int num=0;
if(head == NULL)
{
return 0;
}else{
while(head){
head = head->next;
num++;
}
return num;
}
}
int main()
{
//create(); //创建对像测试一下, 基本正常
string str;
begin:
cout<<"1->重建图书 2->显示图书 3->插入图书 4->删除图书 5->图书数目 Q->退出"<<endl;
cin>>str;
if(str[0] == '1')//这里单个字符是不能用双引号的,只能用单引号
{
::head =create(); //创建图书,将head指针保存到全局的head里面去
system("cls"); //好像是刷屏的意思
goto begin; //goto 很老的条件语句,不过在这里一样好用
}else if(str[0] == '2'){
if(head == NULL){
cout<<"您的图书现在还是空的,请增加图书"<<endl<<"按回车键返回主程序"<<endl;
cin.get();
cin.get();
system("cls");
goto begin;
}else{
showbook(head);
}
//这里进行图书的插入
}else if(str[0] == '3'){
if(head==NULL){
cout<<"您的图书现在还是空的,请增加图书"<<endl<<"按回车键返回主程序"<<endl;
cin.get();
cin.get();
system("cls");
goto begin;
}else{
cout<<"请输入图书的编号, 以0结束"<<endl;
string _str;
int num;
float price;
cin>>_str;
while(!check(_str)){
cout<<"您输入的不是一个数字,请重新输入,按0结束"<<endl;
cin>>_str;
}
num = atoi(_str.c_str());
if(num != 0){
cout<<"请输入图书的价格"<<endl;
cin>>_str;
while(!check(_str)){
cout<<"您输入的不是一个数字,请重新输入,按0结束"<<endl;
cin>>_str;
}
price = atof(_str.c_str());
}else{
system("cls");
goto begin;
}
insert(head,num,price);
cout<<"操作完毕,按回车键返回主程序"<<endl;
}
}else if(str[0] == '4')
{
if(head == NULL)
{
cout<<"您的图书现在还是空的,请增加图书"<<endl<<"按回车键返回主程序"<<endl;
cin.get();
cin.get();
system("cls");
goto begin;
}else{
cout<<"请输入要删除图书编号:"<<endl;
string _str;
int num;
cin>>_str;
while(!check(_str))
{
cout<<"您输入的不是一个数字,请重新输入,按0返回"<<endl;
cin>>_str;
}
num = atoi(_str.c_str());
if(num != 0)
{
bool isok = Delete(head,num);
if(isok == true){
cout<<"删除成功!";
}else{
cout<<"没有找到相应的图书编号!";
}
}else{
system("cls");
goto begin;
}
}
}else if(str[0] == '5')
{
cout<<"图书数目是:"<<getBookNum(head)<<endl<<"按回车键返回主程序"<<endl;
cin.get();
cin.get();
system("cls");
goto begin;
}
if(str[0] !='Q' && str[0] !='q')
{
cin.get();
cin.get();
system("cls");
goto begin;
}
return 0;
}