// 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; }