图书链表

#include <iostream>
#include <string>
using namespace std;
class book
{
public:
	int num;
	float price;
	book*next;
};
bool check(string str)
{
	int i,j=0;
	if (str[0]=='.')       //假如字符串第一个元素为小数点返回假
		return false;
	for (i=0;i<str.length();i++)
	{
		if ((str[i]=='.'))        //验证字符串中有几个小数点
			j++;
	}
	if (j>1)
		return false;            //假如小数点多于一个返回假
	for (i=0;i<str.length();i++)
		if((str[i]>'9'||str[i]<'0')&&(str[i]!='.'))
			return false;      //假如字符串中不是0-9和小数点返回假
	return true;
}

book *head=NULL;     //全局头指针


//动态创建链表
book *creat()  
{  
    //p1作为下一个节点的指针,p2作为下个节点的指针   
    book *p1,*p2;  
    p1=new book;  
    head=p1;  
    p2=p1;  
    cout<<"请输入图书的编号,以0结束"<<endl;  
    string str;
	cin>>str;
	while(!check(str))
	{
		cout<<"输入的不是数字重新输入,按零返回"<<endl;
		cin>>str;
	}
	p1->num=atoi(str.c_str());        //atoi将字符串转换为整形变量
    if(p1->num!=0)  
    {  
        cout<<"请输入图书价格"<<endl;  
        cin>>str;
		while(!check(str))
		{
		    cout<<"输入的不是数字重新输入,按零返回"<<endl;
		    cin>>str;
		}
		p1->price=atof(str.c_str());           //atof将字符串转换为浮点型变量
    }  
    else  
    {  
        delete p1;p2=NULL;head=NULL;return head;  
    }  
    while(p1->num!=0)  
    {  
        p2=p1;                                   //p2保存的是当p1的指针,   
        p1=new book;                             //p1保存的是新开辟的空间   
        cout<<"请输入图书的编号,以0结束"<<endl;  
        string str;
	    cin>>str;
	    while(!check(str))
		{
		    cout<<"输入的不是数字重新输入,按零返回"<<endl;
		    cin>>str;
		}
		p1->num=atoi(str.c_str());
        if(p1->num!=0)  
        {    
            cout<<"请输入图书价格"<<endl;  
            cin>>str;
		    while(!check(str))
			{
		        cout<<"输入的不是数字重新输入,按零返回"<<endl;
		        cin>>str;
			}
		    p1->price=atof(str.c_str()); 
        }  
        p2->next=p1;                 //由于p保存的是p1的原来的指针,就等于旧的p1->next保存新的p1。   
    }  
    delete p1;           //最好一个保存的是0,所以删除掉   
    p2->next=NULL;       //最新的p1也就是链中最后变的p1的next成员指针保存的值为空   
    return head;                        //由于head指针和p2都是保存的p1最开始的指针,所以p2的作用是不断的给旧的p1保存新的p1,head的作用是利用最旧的p1查找p1保存的链式数据。   
}  


//动态链表删除
void Delete (book *head,int num)
{
	book *l;
	if(head->num==num)                    //假如head的头节点是所要删除的节点
	{
		l=head;                    //让i保存当前头指针
		head=head->next;           //然后当前节点指向它的后一个节点
		::head=head;               //把新的头节点赋给全局head
		delete l;                  //然后删除旧的节点
		cout<<"操作成功"<<endl;
		return;                     //返回   结束delete函数
	}
	while(head)
	{
		if (head->next==NULL)                //假如一直没有找到所要删除的编号的节点
		{
			cout<<"找不到的编号"<<endl;     //输出找不到编号
			return;                        //然后返回  结束函数
		}
		if (head->next->num==num)            //假如找到了所要删除的节点编号
		{
			l=head->next;                  //l节点保存所要删除的当前节点
			head->next=l->next;           //所要删除的节点指向它的后一个节点
			delete l;                     //然后删除当前节点    形成新的链
			cout<<"操作成功"<<endl;
			return;
		}
		head=head->next;
	}
	cout<<"找不到要删除的编号"<<endl;
}


//动态链表的显示
void Showbook(book *head)
{
	cout<<endl;
	cout<<"图书信息如下:"<<endl;
	while(head)
	{
		cout<<"图书编号:"<<head->num<<"\t";
		cout<<"图书价格:"<<head->price<<endl;
		head=head->next;
	}
}


//动态链表的插入
void insert(book*head,int num,int price)
{
	book*list=new book;
	list->num=num;
	list->price=price;
	if (num<=head->num) //判断新插入的节点的编号是否小于等于头节点的编号
	{
	    list->next=head;   //小于则插在头节点前面
	    ::head=list;
		return;          //新节点成为了头节点要退出insert函数
	}
	book*temp=NULL;
	while((num>head->num)&&(head->next!=NULL))
	{
		temp=head;
		head=head->next;     //head指向最后一个节点
	}
	if (num>head->num)       //判断新节点编号是否大于head的尾节点编号
	{
		head->next=list;       //list为尾节点
		list->next=NULL;    //注意 由于list节点是尾节点,所以它的next指针赋为空。
	}
	else
	{
		temp->next=list;     //temp保存了前一个节点的地址,head保存的下一个节点的地址
		//前一个节点就接上了list,然后list保存head节点,这样list就在中间插入了
		list->next=head;
	}
}




//返回图书编号
int getbooknum(book *head)
{
	int num=0;
	while(head)
	{
		num++;
		head=head->next;
	}
	return num;                  //返回有多少本书
}

//要用main()函数使用以上的功能组成一个图书管理系统
void main()
{
	string str;
begin:                              //goto标签begin
	cout<<"1->重建图书 2->显示图书 3->插入图书 4->删除图书 5->图书数目 Q->退出"<<endl;
	//↑提示信息
	cin>>str;
	if(str[0]=='1')       //假如选择了重建图书
	{
		creat();          //调用动态创建图书函数
		system("cls");    //清楚屏幕上所有的文字
		goto begin;       //无条件返回goto标签,执行goto标签后面的程序
	}
	else if(str[0]=='2')
	{
		if(head==NULL)
		{
			cout<<"你现在的图书是空的,请增加图书"<<endl<<"按回车返回主程序"<<endl;
			cin.get();    //cin.get()保存用户输入的字符,第一个cin.get()保存用户输入的回车键
			cin.get();    //第一个实现了暂停,提示按任意键继续,所以第二个cin.get()执行以后,就直接执行下一条语句了
			system("cls");  //清屏
			goto begin;     //返回begin标签
		}
		Showbook(head);
		cout<<"按回车返回主程序"<<endl;
		cin.get();
		cin.get();
		system("cls");
		goto begin;
	}
	else if(str[0]=='3')
	{
		if(head==NULL)
		{
			cout<<"你的图书现在是空的,请增加书"<<endl<<"按回车返回主程序"<<endl;
			cin.get();
			cin.get();
			system("cls");                  
			goto begin;              //假如没有书,返回begin标签
		}
		cout<<"请输入要插入的图书的编号:"<<endl;
		string str1;
	    cin>>str1;
		float price;
		int num;
	    while(!check(str1))
		{
		    cout<<"输入的不是数字重新输入,按零返回"<<endl;
		    cin>>str1;
		}
		
		num=atoi(str1.c_str());
        if (num!=0)
		{
            cout<<"请输入图书价格"<<endl;  
            string str2;
		    cin>>str2;
	        while(!check(str2))
			{
		        cout<<"输入的不是数字重新输入,按零返回"<<endl;
		        cin>>str2;
			}
			
			price=atof(str2.c_str());
		}
		else
		{
			system("cls");
			goto begin;
		}
		
		insert(head,num,price);
		cout<<"操作完毕,按回车返回主程序"<<endl;
		cin.get();
		cin.get();
		system("cls");
		goto begin;
	}
	else if(str[0]=='4')
	{
		if (head==NULL)
		{
			cout<<"你现在的图书是空的,请增加书"<<endl<<"按回车返回主程序"<<endl;
			cin.get();
			cin.get();
			system("cls");
			goto begin;
		}
		int num;
		cout<<"请输入要删除的图书编号:"<<endl;
		string str3;
		cin>>str3;
		while(!check(str3))
		{
			cout<<"输入的不是数字,请重新输入,按0返回!!"<<endl;
			cin>>str3;
		}
		num = atoi(str3.c_str());
		Delete(head,num);
		cout<<"操作成功按回车返回主程序"<<endl;
		cin.get();
		cin.get();
		system("cls");
		goto begin;
	}
	else if(str[0]=='5')
	{
		cout<<"图书数目是:"<<getbooknum(head)<<endl<<"按回车返回主程序"<<endl;
		cin.get();
		cin.get();
		system("cls");
		goto begin;
	}
	else
	{
		if(str[0]!='Q'&&str[0]!='q')
		{
			cout<<"请输入数字!按回车继续操作";
		}
		if(str[0]!='Q'&&str[0]!='q')
		{
			cin.get();
			cin.get();
			system("cls");
			goto begin;
		}
		system("pause");
	}

}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值