// 6 解决输入字符造成死循环的情况
/*
#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] > '9' || str[i] < '0') && str[i] !='.')
{
return false;
}
}
return true;
}
book *create()
{
//我们选建一个新的节点
book *p1, *p2; //p1做为下一个节点的指针,p2做为结构本的指针
p1 = new book;
p2 = p1;
head = p2;
cout<<"请输入图书的编号,退出请输入0"<<endl;
string str;
cin>>str;
while(!check(str)){
cout<<"输入的不是数字,请重新输入,按0返回"<<endl;
cin>>str;
}
p1->num = atoi(str.c_str());
//cin>>p1->num;
if(p1->num != 0)
{
cout<<"请输入图书的价格:"<<endl;
//做同样的处理
cin>>str;
while(!check(str)){
cout<<"您输入的不是数字,请重新输出,按0退出!";
cin>>str;
}
//转换格式,将str转换为float,然后将string转换为char
p1->price = atof(str.c_str());
//cin>>p1->price;
}else{
//如果是退出的话
delete p1;
p2 = NULL;
p2->next = NULL;
head = NULL;
return head;
}
//cout<<"num:"<<head->num<<endl;
//cout<<"price:"<<head->price<<endl;
//如果不为0那么就循环让用户输入图书信息
while(p1->num != 0)
{
p2 = p1; //p1做为当前输入的指针,p2为结构本指针
//重新构造一个新的p1指针,如果这里不重新构造的话,那么这里一直就是在操作head跟p1 p2指针的同一个地址
//这里刚才少写了一句
p1 = new book;
cout<<"请输入图书的编号,退出请输入0"<<endl;
cin>>str;
while(!check(str)){
cout<<"输入的不是数字,请重新输入,按0返回"<<endl;
cin>>str;
}
p1->num = atoi(str.c_str());
//cin>>p1->num;
if(p1->num != 0)
{
cout<<"请输入图书的价格:"<<endl;
cin>>str;
while(!check(str)){
cout<<"您输入的不是数字,请重新输出,按0退出!";
cin>>str;
}
p1->price =atof(str.c_str());
//cin>>p1->price;
}
p2->next = p1;
//cout<<"num:"<<head->num<<endl;
//cout<<"price:"<<head->price<<endl;
}
//这里还多少一个中间的转换节点p1,我们在这里删除
delete p1;
p2->next = NULL;
return head;
}
int main()
{
book *s = create();
//cout<<"s:"<<s<<endl;
//cout<<"main s:"<<s->num<<endl;
//cout<<"main s:"<<s->price<<endl;
//我这里来读取一下*p这个链表的信息
while(s)
{
cout<<"图书的编号是:"<<s->num<<", 图书的价格是:"<<s->price<<endl;
if(s->next == NULL){
s = NULL;
}else{
s = s->next;
}
}
return 0;
return 0;
}*/
// 7 显示列表信息
/*
#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] > '9' || str[i] < '0') && str[i] !='.')
{
return false;
}
}
return true;
}
book *create()
{
//我们选建一个新的节点
book *p1, *p2; //p1做为下一个节点的指针,p2做为结构本的指针
p1 = new book;
p2 = p1;
head = p2;
cout<<"请输入图书的编号,退出请输入0"<<endl;
string str;
cin>>str;
while(!check(str)){
cout<<"输入的不是数字,请重新输入,按0返回"<<endl;
cin>>str;
}
p1->num = atoi(str.c_str());
if(p1->num != 0)
{
cout<<"请输入图书的价格:"<<endl;
//做同样的处理
cin>>str;
while(!check(str)){
cout<<"您输入的不是数字,请重新输出,按0退出!";
cin>>str;
}
//转换格式,将str转换为float,然后将string转换为char
p1->price = atof(str.c_str());
//cin>>p1->price;
}else{
//如果是退出的话
delete p1;
p2 = NULL;
p2->next = NULL;
head = NULL;
return head;
}
//如果不为0那么就循环让用户输入图书信息
while(p1->num != 0)
{
p2 = p1; //p1做为当前输入的指针,p2为结构本指针
//重新构造一个新的p1指针,如果这里不重新构造的话,那么这里一直就是在操作head跟p1 p2指针的同一个地址
//这里刚才少写了一句
p1 = new book;
cout<<"请输入图书的编号,退出请输入0"<<endl;
cin>>str;
while(!check(str)){
cout<<"输入的不是数字,请重新输入,按0返回"<<endl;
cin>>str;
}
p1->num = atoi(str.c_str());
//cin>>p1->num;
if(p1->num != 0)
{
cout<<"请输入图书的价格:"<<endl;
cin>>str;
while(!check(str)){
cout<<"您输入的不是数字,请重新输出,按0退出!";
cin>>str;
}
p1->price =atof(str.c_str());
}
p2->next = p1;
}
//这里还多少一个中间的转换节点p1,我们在这里删除
delete p1;
p2->next = NULL;
return head;
}
void showbook(book *head)
{
while(head){
cout<<"图书的编号是:"<<head->num<<", 图书的价格是:"<<head->price<<endl;
if(head->next == NULL){
head = NULL;
}else{
head = head->next;
}
}
}
void Delete(book *head, int num)
{
//这里的删除有三种可能,一是删除的是头节点,
//二是删除是尾节点,三是删除的是中间节点
book *l = NULL; //用于保存当前要被删除的指针
if(head){ //当head指针不为空时
if(head->num == num){ //删除第一个指针
//::head = head->next; //将第一个指针的下一个元素设置为头指针,这里的头指是赋给全局的head指针
//delete head; //然后删除头元素
l = head; //因为head将要被删除,先将其赋值给l
head = head->next; //重新设置head的值
::head = head;
delete l;
}
//当head为真实一直执行
while(head){
if(head->next == NULL){
cout<<"找不到要删除的编号"<<endl;
return;
}
if(head->next->num == num)
{
l = head->next;
head->next = l->next;
delete l;
return;
}
head = head->next;
}
}
cout<<"找不到要删除的编号"<<endl;
}
int main()
{
//创建链表
book *s = create();
//显示链表
showbook(s);
cout<<"请输入你要删除的图书编号:";
int num=0;
cin>>num;
Delete(s,num);
cout<<"删除后的链表信息为:"<<endl;
showbook(s);
return 0;
}*/
//8 链表的插入
// 7 显示列表信息
#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] > '9' || str[i] < '0') && str[i] !='.')
{
return false;
}
}
return true;
}
book *create()
{
//我们选建一个新的节点
book *p1, *p2; //p1做为下一个节点的指针,p2做为结构本的指针
p1 = new book;
p2 = p1;
head = p2;
cout<<"请输入图书的编号,退出请输入0"<<endl;
string str;
cin>>str;
while(!check(str)){
cout<<"输入的不是数字,请重新输入,按0返回"<<endl;
cin>>str;
}
p1->num = atoi(str.c_str());
if(p1->num != 0)
{
cout<<"请输入图书的价格:"<<endl;
//做同样的处理
cin>>str;
while(!check(str)){
cout<<"您输入的不是数字,请重新输出,按0退出!";
cin>>str;
}
//转换格式,将str转换为float,然后将string转换为char
p1->price = atof(str.c_str());
//cin>>p1->price;
}else{
//如果是退出的话
delete p1;
p2 = NULL;
p2->next = NULL;
head = NULL;
return head;
}
//如果不为0那么就循环让用户输入图书信息
while(p1->num != 0)
{
p2 = p1; //p1做为当前输入的指针,p2为结构本指针
//重新构造一个新的p1指针,如果这里不重新构造的话,那么这里一直就是在操作head跟p1 p2指针的同一个地址
//这里刚才少写了一句
p1 = new book;
cout<<"请输入图书的编号,退出请输入0"<<endl;
cin>>str;
while(!check(str)){
cout<<"输入的不是数字,请重新输入,按0返回"<<endl;
cin>>str;
}
p1->num = atoi(str.c_str());
//cin>>p1->num;
if(p1->num != 0)
{
cout<<"请输入图书的价格:"<<endl;
cin>>str;
while(!check(str)){
cout<<"您输入的不是数字,请重新输出,按0退出!";
cin>>str;
}
p1->price =atof(str.c_str());
}
p2->next = p1;
}
//这里还多少一个中间的转换节点p1,我们在这里删除
delete p1;
p2->next = NULL;
return head;
}
void showbook(book *head)
{
while(head){
cout<<"图书的编号是:"<<head->num<<", 图书的价格是:"<<head->price<<endl;
if(head->next == NULL){
head = NULL;
}else{
head = head->next;
}
}
}
void Delete(book *head, int num)
{
//这里的删除有三种可能,一是删除的是头节点,
//二是删除是尾节点,三是删除的是中间节点
book *l = new book; //用于保存当前要被删除的指针
//唉,这里new book,不行,只能用
//book *l; //这里只是定义了一个book类型的*l,并没有实例化和赋值等操作
if(head){ //当head指针不为空时
cout<<"head->num:"<<head->num<<", num:"<<num<<endl;
if(head->num == num){ //删除第一个指针
//::head = head->next; //将第一个指针的下一个元素设置为头指针,这里的头指是赋给全局的head指针
//delete head; //然后删除头元素
l = head; //因为head将要被删除,先将其赋值给l
cout<<"l:"<<l<<endl;
cout<<"head:"<<head<<endl;
//走到这块,赋值是正确的
head=head->next; //重新设置head的值
::head=head;
delete l;
cout<<"删除成功!"<<endl;
return;
}
//当head为真实一直执行
while(head){
if(head->next == NULL){
cout<<"找不到要删除的编号"<<endl;
return;
}
if(head->next->num == num)
{
l = head->next;
head->next = l->next;
delete l;
return;
}
head = head->next;
}
}
cout<<"找不到要删除的编号"<<endl;
}
void insert(book *head, book *addbook)
{
//book *list = new book; //该指针用于记录当前的最后一个节点
if(head){
//这种方法是在链表的结尾处进行链表插入
//book *l; //用于保存取后一个节点
//while(head){
//l = head;
//head = head->next;
//}
//l->next = addbook;
//
//在链表的最前面进行插入
//addbook->next = head;
//::head = addbook;
//return;
//中间插入法
//这里将顺序进行插入
book *l; //用于找到当前的上一个节点
if(head->num > addbook->num)
{
addbook->next = head;
::head = addbook;
return;
}else{
//这里的l是指定上一个节点,这里的head是指定下一个节点
while(head->num < addbook->num && head->next !=NULL){
l = head;
head = head->next;
}
if(addbook->num > head->num){
head->next = addbook; //这里表示如果num已经大于了最后一个指针head的值时,进行尾插入法
}else{
l->next = addbook;
addbook->next = head;
}
}
}else{
head = addbook;
::head = addbook;
}
}
int main()
{
//创建链表
book *s = create();
//显示链表
showbook(s);
cout<<"请输入你要删除的图书编号:";
int num=0;
cin>>num;
Delete(s,num);
cout<<"删除后的链表信息为:"<<endl;
//showbook(s); //这里的读取是错误的,这个s指针早已经错了,所以要读取只能用全局的head指针,不过这个head也有可能是空的
//因为当只输入一条记录时,然后我在删除一条,看会发生什么情况
showbook(head);
cout<<"请输入你要添加的图书编号:"<<endl;
cin>>num;
cout<<"请输入你要添加的图书价格:"<<endl;
float price;
cin>>price;
book *addbook = new book();
addbook->num = num;
addbook->price = price;
insert(head,addbook);
cout<<"添加以后的链表为:"<<endl;
showbook(head);
return 0;
}