第十五章 链表(二) 链表的插入 删除 显示 简单

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

  

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