第十五章 链表(三) 链表使用 简单

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

  

原文地址:https://www.cnblogs.com/xiangxiaodong/p/2587290.html