数据结构实验:单链表的基本操作&&基于线性表的图书管理系统

目录

实验名称

实验目的

实验内容

实验具体内容:

实验需求分析:

预期结果:

实验方法

1. 单链表的存储结构和操作接口

2. 单链表操作的实现

3. 调试运行

实验结论

实验最终成果截图

实验体会和收获

附:程序代码

附加实验一:基于线性表的图书管理系统

(一)实验名称

(二)实验目的

(三)实验内容

(四)程序源代码


  • 实验名称

实验一  单链表的基本操作

  • 实验目的

1.理解线性表的逻辑结构;

2.理解单链表的存储结构特点,掌握单链表的存储分配要点;

3.掌握单链表的基本操作及实现,并能正确分析其时间复杂度。

  • 实验内容

实验具体内容:

1.  定义单链表的存储结构;

2.  单链表的基本操作

(1)初始化单链表(无参和有参);

(2)求单链表长度;

(3)按位置查找;

(4)按值查找;

(5)在位置i插入一个数据元素;

(6)删除位置i的数据元素;

(7)遍历单链表;

(8)销毁单链表。

实验需求分析:

在理解线性表逻辑结构,和单链表的储存特点的基础上,设计、编写一段完整代码,该代码能够详细定义单链表的储存结构,同时完成实验具体内容中所要求的单链表基本操作。在此基础上,从算法思想及时间、空间复杂度的角度对代码进行优化,并获得关于“单链表的基本操作”的最优化代码。

预期结果:

   完成实验指导书中所要求的具体实验内容,并对其进行优化。

  • 实验方法

说明:该部分是以直接初始化单链表为例,对相关实验方法及相关操作的实现从理论和算法的角度进行说明,和最终实现的该实验题目的源代码相比较有一定的差异。

1. 单链表的存储结构和操作接口

//LinkList.h  声明类LinkList

#ifndef LinkList_H

#define LinkList_H

template

struct Node

{

  T data;

  Node *next;  //此处也可以省略

};

template

class LinkList

{

  public:

    LinkList( );           //建立只有头结点的空链表

    LinkList(T a[ ], int n);  //建立有n个元素的单链表

    ~LinkList();           //析构函数

    int Length();          //求单链表的长度

    T Get(int i);           //取单链表中第i个结点的元素值

    int Locate(T x);       //求单链表中值为x的元素序号

    void Insert(int i, T x);   //在单链表中第i个位置插入元素值为x的结点

    T Delete(int i);        //在单链表中删除第i个结点

    void PrintList( );       //遍历单链表,按序号依次输出各元素

 private:

   Node *first;  //单链表的头指针

};

#endif

2. 单链表操作的实现

//LinkList.cpp

#include "LinkList.h"

/*

*前置条件:单链表不存在

*输    入:无

*功    能:构建一个单链表

*输    出:无

*后置条件:构建一个单链表

*/

template

LinkList:: LinkList( )

{

 first=new Node; first->next=NULL;

}

/*

*前置条件:单链表不存在

*输    入:顺序表信息的数组形式a[],单链表长度n

*功    能:将数组a[]中元素建为长度为n的单链表

*输    出:无

*后置条件:构建一个单链表

*/

template  

LinkList:: LinkList(T a[ ], int n)

 {

    first=new Node;   //生成头结点

Node *r,*s;

     r=first;          //尾指针初始化

    for (int i=0; i

{

      s=new Node; s->data=a[i];  //为每个数组元素建立一个结点

      r->next=s; r=s;      //插入到终端结点之后

}

    r->next=NULL;    //单链表建立完毕,将终端结点的指针域置空

 }

/*

*前置条件:无

*输    入:无

*功    能:无

*输    出:无

*后置条件:无

*/

template

LinkList:: ~LinkList()

{

}

/*

*前置条件:单链表存在

*输    入:查询元素位置i

*功    能:按位查找位置为i的元素并输出值

*输    出:查询元素的值

*后置条件:单链表不变

*/

template

T LinkList::Get(int i)

{   

  Node *p; int j;

  p=first->next;  j=1;  //或p=first;  j=0;

  while (p && j

  {

    p=p->next;       //工作指针p后移

    j++;

  }

  if (!p) throw "位置";

  else return p->data;

}

/*

*前置条件:单链表存在

*输    入:查询元素值x

*功    能:按值查找值的元素并输出位置

*输    出:查询元素的位置

*后置条件:单链表不变

*/

template

int LinkList::Locate(T x)

{

Node *p; int j;

p=first->next; j=1;

if(p&&p->next){

  while(p->data!=x)

  {

 p=p->next;

     j++;

  }

return j;

}

else throw "位置";

}

/*

*前置条件:单链表存在

*输    入:插入元素x,插入位置i

*功    能:将元素x插入到单链表中位置i处

*输    出:无

*后置条件:单链表插入新元素

*/

template  

void LinkList::Insert(int i, T x)

{  

   Node *p; int j;

   p=first ; j=0;    //工作指针p初始化

   while (p && j

   {

     p=p->next;   //工作指针p后移

     j++;

   }

   if (!p) throw "位置";

    else {

  Node *s;

      s=new Node;

  s->data=x;  //向内存申请一个结点s,其数据域为x

      s->next=p->next;       //将结点s插入到结点p之后

      p->next=s;

}

}

/*

*前置条件:单链表存在

*输    入:无

*功    能:输出单链表长度

*输    出:单链表长度

*后置条件:单链表不变

*/

template

int LinkList::Length( )

{

  Node *p = first->next;

  int i = 0;

  while(p)

  {

    p = p->next;

    i++;

  }

  return i;

}

/*

*前置条件:单链表存在

*输    入:要删除元素位置i

*功    能:删除单链表中位置为i的元素

*输    出:无

*后置条件:单链表删除元素

*/

template  

T LinkList::Delete(int i)

{

  Node *p; int j;

  p=first ; j=0;  //工作指针p初始化

  while (p && j

  {

    p=p->next;

    j++;

  }

  if (!p || !p->next) throw "位置";  

//结点p不存在或结点p的后继结点不存在

    else {

  Node *q; int x;

          q=p->next; x=q->data;  //暂存被删结点

          p->next=q->next;  //摘链

          delete q;

          return x;

}

}

/*

*前置条件:单链表存在

*输    入:无

*功    能:单链表遍历

*输    出:输出所有元素

*后置条件:单链表不变

*/

template

void LinkList::PrintList( )

{

Node *p;

p=first->next;

while (p)

{

  cout<data<

  p=p->next;

}

}

3. 调试运行

//LinkListMain.cpp

#include  //引用输入输出流库函数的头文件

#include "LinkList.cpp"  //引用单链表的类

void main( )

{

 LinkList a;

 cout<<"执行插入操作:"<

 try

 {

  a.Insert(1,4);

  a.Insert(2,5);

  a.Insert(3,6);

 }

 catch(char* wrong)

 {

   cout << wrong;     //如失败提示失败信息

 }

 cout<<"已经插入“4,5,6”"<

 cout<<"单链表a的长度为:"<

 cout<

 cout<

 cout<<"单链表a的元素为:"<

 a.PrintList();                  //显示链表中所有元素

 cout<

 cout<<"按位查找第二个元素:"<

 cout<<"第二个元素为:";

 cout<

 cout<

 cout<<"按值查找5"<

 cout<<"值为5的元素位置为:";

 cout<

 cout<

 cout<<"执行删除4的操作"<

 a.Delete(1);                    //删除元素4

 cout<<"已删除成功,单链表a的长度为";

 cout<

 cout<

 cout<<"链表a中的元素为:"<

 a.PrintList();

 int r[ ]={1,2,3,4,5};

 LinkList b(r,5);     //根据数组创建单链表

 cout<<"执行插入操作前单链表b为:"<

 b.PrintList();            //输出单链表所有元素

 cout<<"插入前单链表b的长度为:";    

 cout<

 try

 {

   b.Insert(3,8);

 }

 catch(char* wrong)

 {

   cout << wrong;     //如失败提示失败信息

 }

 cout<<"执行插入操作后单链表b为:"<

 b.PrintList();            //输出单链表b所有元素

 cout<<"插入后单链表b的长度为:";    

 cout<

 cout<

 try

 {

   if(a.Length()){

  cout<<"执行删除第一个元素操作:"<

  cout<

  b.Delete(1);                //删除b中第一个元素

      cout<<"已删除成功,单链表b的长度为:";    

      cout<

   }

   else{

  cout<<"顺序表b长度为0"<

   }

 }

 catch(char* wrong)

 {

   cout << wrong;     //如失败提示失败信息

 }

 cout<<"执行插入操作后单链表b为:"<

 b.PrintList();            //输出单链表所有元素

}

  • 实验结论

实验最终成果截图

数据结构实验:单链表的基本操作&&基于线性表的图书管理系统_第1张图片

  • 实验体会和收获

通过这次实验,我掌握了单链表的结构特点和基本操作,巩固了C++相关的程序设计方法与技术,并且意识到,熟练掌握课本知识是实验的基础,不把课本上的相关知识学深学透, 实验便无从着手, 另外,在做实验的过程锻炼思考问题并动手解决的能力很重要。

  • 附:程序代码

#include
using namespace std;

typedef int DataType;
#define Node ElemType
#define ERROR NULL

//构建一个节点类
class Node
{
public:
	int data;     //数据域
	Node* next;  //指针域
};

//构建一个单链表类
class LinkList
{
public:
	LinkList();					  //构建一个单链表;
	~LinkList();                  //销毁一个单链表;
	void CreateLinkList(int n);   //创建一个单链表
	void TravalLinkList();        //遍历线性表
	int GetLength();              //获取线性表长度
	bool IsEmpty();               //判断单链表是否为空
	ElemType* Find(DataType data); //查找节点
	void InsertElemAtEnd(DataType data);            //在尾部插入指定的元素
	void InsertElemAtIndex(DataType data, int n);    //在指定位置插入指定元素
	void InsertElemAtHead(DataType data);           //在头部插入指定元素
	void DeleteElemAtEnd();       //在尾部删除元素
	void DeleteAll();             //删除所有数据
	void DeleteElemAtPoint(DataType data);     //删除指定的数据
	void DeleteElemAtHead();      //在头部删除节点
private:
	ElemType* head;              //头结点
};

//初始化单链表
LinkList::LinkList()
{
	head = new ElemType;
	head->data = 0;               //将头结点的数据域定义为0
	head->next = NULL;            //头结点的下一个定义为NULL
}

//销毁单链表
LinkList::~LinkList()
{
	delete head;                 //删除头结点
}

//创建一个单链表
void LinkList::CreateLinkList(int n)
{
	ElemType* pnew, * ptemp;
	ptemp = head;
	if (n < 0) {       //当输入的值有误时,处理异常
		cout << "输入的节点个数有误" << endl;
		exit(EXIT_FAILURE);
	}
	for (int i = 0; i < n; i++) {        //将值一个一个插入单链表中
		pnew = new ElemType;
		cout << "请输入第" << i + 1 << "个值: ";
		cin >> pnew->data;
		pnew->next = NULL;          //新节点的下一个地址为NULL
		ptemp->next = pnew;         //当前结点的下一个地址设为新节点
		ptemp = pnew;               //将当前结点设为新节点
	}
}

//遍历单链表
void LinkList::TravalLinkList()
{
	if (head == NULL || head->next == NULL) {
		cout << "链表为空表" << endl;
	}
	ElemType* p = head;                 //另指针指向头结点
	while (p->next != NULL)        //当指针的下一个地址不为空时,循环输出p的数据域
	{
		p = p->next;               //p指向p的下一个地址
		cout << p->data << " ";
	}
}

//获取单链表的长度
int LinkList::GetLength()
{
	int count = 0;                  //定义count计数
	ElemType* p = head->next;           //定义p指向头结点
	while (p != NULL)                //当指针的下一个地址不为空时,count+1
	{
		count++;
		p = p->next;                //p指向p的下一个地址
	}
	return count;                   //返回count的数据
}

//判断单链表是否为空
bool LinkList::IsEmpty()
{
	if (head->next == NULL) {
		return true;
	}
	return false;
}

//查找节点
ElemType* LinkList::Find(DataType data)
{
	ElemType* p = head;
	if (p == NULL) {                           //当为空表时,报异常
		cout << "此链表为空链表" << endl;
		return ERROR;
	}
	else
	{
		while (p->next != NULL)               //循环每一个节点
		{
			if (p->data == data) {
				return p;                     //返回指针域
			}
			p = p->next;
		}
		if (p->data == data)
		{
			return p;
		}
		return NULL;                           //未查询到结果
	}
}

//在尾部插入指定的元素
void LinkList::InsertElemAtEnd(DataType data)
{
	ElemType* newNode = new ElemType;    //定义一个Node结点指针newNode
	newNode->next = NULL;         //定义newNode的数据域和指针域
	newNode->data = data;
	ElemType* p = head;              //定义指针p指向头结点
	if (head == NULL) {           //当头结点为空时,设置newNode为头结点
		head = newNode;
	}
	else                          //循环知道最后一个节点,将newNode放置在最后
	{
		while (p->next != NULL)
		{
			p = p->next;
		}
		p->next = newNode;
	}
}

//在指定位置插入指定元素
void LinkList::InsertElemAtIndex(DataType data, int n)
{
	if (n<1 || n>GetLength())                   //输入有误报异常
		cout << "输入的值错误" << endl;
	else
	{
		ElemType* ptemp = new ElemType;        //创建一个新的节点
		ptemp->data = data;                     //定义数据域
		ElemType* p = head;                    //创建一个指针指向头结点
		int i = 1;
		while (n > i)                           //遍历到指定的位置
		{
			p = p->next;
			i++;
		}
		ptemp->next = p->next;                 //将新节点插入到指定位置
		p->next = ptemp;
	}
}

//在头部插入指定元素
void LinkList::InsertElemAtHead(DataType data)
{
	ElemType* newNode = new ElemType;    //定义一个Node结点指针newNode
	newNode->data = data;
	ElemType* p = head;              //定义指针p指向头结点
	if (head == NULL) {           //当头结点为空时,设置newNode为头结点
		head = newNode;
	}
	newNode->next = p->next;          //将新节点插入到指定位置
	p->next = newNode;
}

//在尾部删除元素
void LinkList::DeleteElemAtEnd()
{
	ElemType* p = head;          //创建一个指针指向头结点
	ElemType* ptemp = NULL;      //创建一个占位节点
	if (p->next == NULL) {        //判断链表是否为空
		cout << "单链表空" << endl;
	}
	else
	{
		while (p->next != NULL)   //循环到尾部的前一个
		{
			ptemp = p;            //将ptemp指向尾部的前一个节点
			p = p->next;          //p指向最后一个节点
		}
		delete p;                //删除尾部节点
		p = NULL;
		ptemp->next = NULL;
	}
}

//删除所有数据
void LinkList::DeleteAll()
{
	ElemType* p = head->next;
	ElemType* ptemp = new ElemType;
	while (p != NULL)                    //在头结点的下一个节点逐个删除节点
	{
		ptemp = p;
		p = p->next;
		head->next = p;
		ptemp->next = NULL;
		delete ptemp;
	}
	head->next = NULL;                 //头结点的下一个节点指向NULL
}

//删除指定的数据
void LinkList::DeleteElemAtPoint(DataType data)
{
	ElemType* ptemp = Find(data);    //查找到指定数据的节点位置
	if (ptemp == head->next) {        //判断是不是头结点的下一个节点,如果是就从头部删了它
		DeleteElemAtHead();
	}
	else
	{
		ElemType* p = head;          //p指向头结点
		while (p->next != ptemp)      //p循环到指定位置的前一个节点
		{
			p = p->next;
		}
		p->next = ptemp->next;         //删除指定位置的节点
		delete ptemp;
		ptemp = NULL;
	}

}

//在头部删除节点
void LinkList::DeleteElemAtHead()
{
	ElemType* p = head;
	if (p == NULL || p->next == NULL) {   //判断是否为空表,报异常
		cout << "该链表为空表" << endl;
	}
	else
	{
		ElemType* ptemp = NULL;      //创建一个占位节点
		p = p->next;
		ptemp = p->next;              //将头结点的下下个节点指向占位节点
		delete p;                     //删除头结点的下一个节点
		p = NULL;
		head->next = ptemp;           //头结点的指针更换
	}
}

//测试函数
int main()
{
	LinkList l;
	int i;
	cout << "1.创建单链表   2.遍历单链表   3.获取单链表的长度   4.判断单链表是否为空   5.获取节点\n";
	cout << "6.在尾部插入指定元素   7.在指定位置插入指定元素   8.在头部插入指定元素\n";
	cout << "9.在尾部删除元素   10.删除所有元素   11.删除指定元素   12.在头部删除元素   0.退出" << endl;
	do
	{
		cout << "请输入要执行的操作: ";
		cin >> i;
		switch (i)
		{
		case 1:
			int n;
			cout << "请输入单链表的长度: ";
			cin >> n;
			l.CreateLinkList(n);
			break;
		case 2:
			l.TravalLinkList();
			break;
		case 3:
			cout << "该单链表的长度为" << l.GetLength() << endl;
			break;
		case 4:
			if (l.IsEmpty() == 1)
				cout << "该单链表是空表" << endl;
			else
			{
				cout << "该单链表不是空表" << endl;
			}
			break;
		case 5:
			DataType data;
			cout << "请输入要获取节点的值: ";
			cin >> data;
			cout << "该节点的值为" << l.Find(data)->data << endl;
			break;
		case 6:
			DataType endData;
			cout << "请输入要在尾部插入的值: ";
			cin >> endData;
			l.InsertElemAtEnd(endData);
			break;
		case 7:
			DataType pointData;
			int index;
			cout << "请输入要插入的数据: ";
			cin >> pointData;
			cout << "请输入要插入数据的位置: ";
			cin >> index;
			l.InsertElemAtIndex(pointData, index);
			break;
		case 8:
			DataType headData;
			cout << "请输入要在头部插入的值: ";
			cin >> headData;
			l.InsertElemAtHead(headData);
			break;
		case 9:
			l.DeleteElemAtEnd();
			break;
		case 10:
			l.DeleteAll();
			break;
		case 11:
			DataType pointDeleteData;
			cout << "请输入要删除的数据: ";
			cin >> pointDeleteData;
			l.DeleteElemAtPoint(pointDeleteData);
			break;
		case 12:
			l.DeleteElemAtHead();
			break;
		default:
			break;
		}
	} while (i != 0);

	system("pause");
	return 0;
}
  • 附加实验一:基于线性表的图书管理系统

(一)实验名称

基于线性表的图书管理系统

(二)实验目的

1.掌握线性表的顺序存储表示和链式存储表示;
2.掌握顺序表和链表的基本操作,包括建、查找、插入和删除等算法。

(三)实验内容

实验具体内容:

图书信息表包括以下10项基本操作:图书信息表的创建和输出、排序、修改、逆序存储、最贵图书查找、最爱图书查找、最佳位置图书查找、新图书入库、旧图书出库、图书去重。实验要求用顺序表实现以上的10项基本操作以实现一个图书馆管理系统的基本功能。

实验需求分析:

在理解线性表逻辑结构,和顺序表的储存特点的基础上,设计、编写一段完整代码,该代码能够实现图书管理系统包括以下的10项基本操作:图书信息表的创建和输出、排序、修改、逆序存储、最贵图书查找、最爱图书查找、最佳位置图书查找、新图书入库、旧图书出库、图书去重。在此基础上,从算法思想及时间、空间复杂度的角度对代码进行优化,并获得关于“基于顺序表的图书管理系统”的最优化代码。

预期结果:

    设计一个“基于顺序表的图书管理系统”,实现该系统中所需要的全部功能,并从其他各角度优化该系统。

(四)程序源代码

#include 
#include 
#include 
#define MAXSIZE 1000000

using namespace std;

char s0[10], s1[10], s2[10];     //存放3个标题性信息
int flag = 0;   //图书信息读取标记
int num;     //记录图书个数 
float ave;     //记录所有书平均价格 

typedef struct Book {
	char no[20];
	char name[50];
	float price;
}Book;

typedef struct SqList {
	Book* elem;
	int length;
}Sqlist;

SqList book;


void CreatSqList(SqList& book) {
	book.elem = new Book[MAXSIZE];
	book.length = 0;
}


void Input() {
	int i = 0;

	ifstream inFile("book.txt");
	if (!inFile) {
		cout << "Can't open this file!!" << endl;
		exit(1);
	}

	else {
		inFile >> s0 >> s1 >> s2;     //ISBN 书名 定价
		while (!inFile.eof()) {
			inFile >> book.elem[i].no >> book.elem[i].name >> book.elem[i].price;
			i++;
			num = i;
		}
		inFile.close();
		flag = 1;
		cout << "读取完毕!" << endl;
	}
}


void Output() {
	int i = 0;

	if (flag == 0) {
		cout << "还未读取图书!!!" << endl;
	}
	else {
		cout << "书号                 书名               价格:" << '\n';
		while (i < num) {
			cout << book.elem[i].no << "\t" << book.elem[i].name << "\t" << book.elem[i].price << endl;
			i++;
		}
		cout << endl << "信息显示完毕!" << endl;
	}
}

void OutputN() {
	cout << "图书个数为:" << num << endl;
}


void OutputM() {
	int i;
	Book b;

	if (flag == 0) {
		cout << "还未读取图书!!!" << endl;
	}

	cout << "价格最高图书信息为:" << endl;
	cout << "书号                 书名               价格:" << '\n';
	for (i = 0; i < num - 1; i++) {
		if (book.elem[i].price > book.elem[i + 1].price) {
			b = book.elem[i];
			book.elem[i] = book.elem[i + 1];
			book.elem[i + 1] = b;
		}
	}

	for (i = 0; i < num; i++) {
		if (book.elem[i].price == book.elem[num - 1].price) {
			cout << book.elem[i].no << "\t" << book.elem[i].name << "\t" << book.elem[i].price << endl;
		}
	}
}


void Average() {
	int i;
	float sum = 0;

	if (flag == 0) {
		cout << "还未读取图书!!!" << endl;
	}

	for (i = 0; i < num; i++) {
		sum = sum + book.elem[i].price;
	}

	ave = sum / num;

	cout << "平均价格为:" << ave << endl;
}


void SearchN() {
	int i;
	int n = 0;     //记录相同书名图书个数
	char NAME[20];

	if (flag == 0) {
		cout << "还未读取图书!!!" << endl;
	}

	cout << "请输入需要查找的书名:";
	cin >> NAME;
	cout << endl;

	for (i = 0; i < num; i++) {     //字符串比较函数strcmp
		if (strcmp(book.elem[i].name, NAME) == 0) {
			cout << "书名            书号             价格:" << endl;
			cout << book.elem[i].name << "\t" << book.elem[i].no << "\t" << book.elem[i].price << endl;
			n = n + 1;
		}
	}
	if (n == 0) {
		cout << "没有您需要的图书!" << endl;
	}
	while (i < num) {
		cout << book.elem[i].no << "\t" << book.elem[i].name << "\t" << book.elem[i].price << endl;
		i++;
	}
}


void SearchP() {
	int p;

	if (flag == 0) {
		cout << "还未读取图书!!!" << endl;
	}

	cout << "请输入需要查找图书的位置:";
	cin >> p;
	cout << endl;

	ifstream inFile("book.txt");
	inFile >> s0 >> s1 >> s2;     //ISBN 书名 定价
	for (int i = 0; !inFile.eof(); i++) {
		inFile >> book.elem[i].no >> book.elem[i].name >> book.elem[i].price;
		num = i;
	}
	inFile.close();

	if (p<1 || p>num) {
		cout << "位置输入错误!" << endl;
	}
	else {
		cout << "该图书信息为:" << "书号          书名          价格:" << endl;
		cout << book.elem[p - 1].no << "\t" << book.elem[p - 1].name << "\t" << book.elem[p - 1].price << endl;
	}
}


void Insert() {
	int i;  //位置
	int j;
	Book bk;  //插入的图书

	if (flag == 0) {
		cout << "还未读取图书!!!" << endl;
	}

	cout << "请输入插入位置:";
	cin >> i;
	cout << endl;
	cout << "请输入书号:";
	cin >> bk.no;
	cout << "请输入书名:";
	cin >> bk.name;
	cout << "请输入价格:";
	cin >> bk.price;

	ifstream inFile("book.txt");
	inFile >> s0 >> s1 >> s2;     //ISBN 书名 定价
	for (i = 0; !inFile.eof(); i++) {
		inFile >> book.elem[i].no >> book.elem[i].name >> book.elem[i].price;
		num = i;
	}
	inFile.close();

	if (i<1 || i>num + 1) {
		cout << "插入位置错误!" << endl;
	}
	if (num == MAXSIZE) {
		cout << "没有位置可以插入!" << endl;
	}
	if (1 < i && i <= num + 1 && num != MAXSIZE) {
		for (j = num - 1; j >= i - 1; j--) {
			book.elem[j + 1] = book.elem[j];
		}
		book.elem[i - 1] = bk;
		++num;
		++book.length;
	}

	ofstream outFile("book.txt");
	outFile << s0 << "\t" << s1 << "\t" << s2 << endl;
	for (j = 0; j < num; j++) {
		outFile << book.elem[j].no << "\t" << book.elem[j].name << "\t" << book.elem[j].price << endl;
	}
}


void Delete() {
	int i;  //位置
	int j;

	if (flag == 0) {
		cout << "还未读取图书!!!" << endl;
	}

	ifstream inFile("book.txt");
	inFile >> s0 >> s1 >> s2;     //ISBN 书名 定价
	for (j = 0; !inFile.eof(); j++) {
		inFile >> book.elem[j].no >> book.elem[j].name >> book.elem[j].price;
		num = j;
	}
	inFile.close();

	cout << "请输入将要删除图书的位置:";
	cin >> i;

	if (i<1 || i>num) {
		cout << "位置输入错误!" << endl;
	}
	else {
		for (j = i; j <= num - 1; j++) {
			book.elem[j - 1] = book.elem[j];
		}
		--num;
		--book.length;

		ofstream outFile("book.txt");
		outFile << s0 << "\t" << s1 << "\t" << s2 << endl;
		for (j = 0; j < num; j++) {
			outFile << book.elem[j].no << "\t" << book.elem[j].name << "\t" << book.elem[j].price << endl;
		}
	}
}


void Reverse() {   //逆序输出
	int i, j;
	Book bk;

	if (flag == 0) {
		cout << "还未读取图书!!!" << endl;
	}

	ifstream inFile("book.txt");
	inFile >> s0 >> s1 >> s2;     //ISBN 书名 定价
	for (j = 0; !inFile.eof(); j++) {
		inFile >> book.elem[j].no >> book.elem[j].name >> book.elem[j].price;
		num = j + 1;
	}
	inFile.close();

	for (i = 0; i < num / 2; i++) {
		bk = book.elem[i];
		book.elem[i] = book.elem[num - i - 1];
		book.elem[num - i - 1] = bk;
	}

	ofstream outFile("book_inverser.txt");
	outFile << s0 << "\t" << s1 << "\t" << s2 << endl;
	for (i = 0; i < num; i++) {
		outFile << book.elem[i].no << "\t" << book.elem[i].name << "\t" << book.elem[i].price << endl;
	}

	cout << "完毕!请输入数字继续:" << endl;
}


void Ascende() {   //升序输出
	int i, j;
	Book bk;

	if (flag == 0) {
		cout << "还未读取图书!!!" << endl;
	}

	ifstream inFile("book.txt");
	inFile >> s0 >> s1 >> s2;     //ISBN 书名 定价
	for (j = 0; !inFile.eof(); j++) {
		inFile >> book.elem[j].no >> book.elem[j].name >> book.elem[j].price;
		num = j + 1;
	}
	inFile.close();

	for (i = 0; i < num; i++) {
		for (j = 0; j < num - i - 1; j++) {
			if (book.elem[j].price > book.elem[j + 1].price) {
				bk = book.elem[j];
				book.elem[j] = book.elem[j + 1];
				book.elem[j + 1] = bk;
			}
		}
	}

	ofstream outFile("book_sort.txt");
	outFile << s0 << "\t" << s1 << "\t" << s2 << endl;
	for (i = 0; i < num; i++) {
		outFile << book.elem[i].no << "\t" << book.elem[i].name << "\t" << book.elem[i].price << endl;
	}

	cout << "完毕!请输入数字继续:" << endl;
}


int main() {
	int n;
	CreatSqList(book);

	while (1) {
		cout << "************************************************************************" << endl;
		cout << "            |     欢迎进入Liocricの图书管理系统~           |" << endl;
		cout << "            |                                             |" << endl;
		cout << "            |            请输入数字选择服务:             |" << endl;
		cout << "            |            1.读入图书信息                   |" << endl;
		cout << "            |            2.显示图书信息                   |" << endl;
		cout << "            |            3.输出表中图书个数               |" << endl;
		cout << "            |            4.输出价格最高图书               |" << endl;
		cout << "            |            5.输出图书的平均价格             |" << endl;
		cout << "            |            6.根据书名查找图书               |" << endl;
		cout << "            |            7.根据位置查找图书               |" << endl;
		cout << "            |            8.插入图书                       |" << endl;
		cout << "            |            9.删除指定图书                   |" << endl;
		cout << "            |            10.逆序输出图书                  |" << endl;
		cout << "            |            11.升序输出图书                  |" << endl;
		cout << "            |            0.退出系统                       |" << endl;
		cout << "***********************************************************************" << endl << endl;

		cin >> n;

		switch (n) {
		case 1:Input(); break;
		case 2:Output(); break;
		case 3:OutputN(); break;
		case 4:OutputM(); break;
		case 5:Average(); break;
		case 6:SearchN(); break;
		case 7:SearchP(); break;
		case 8:Insert(); break;
		case 9:Delete(); break;
		case 10:Reverse(); break;
		case 11:Ascende(); break;
		case 0:cout << "欢迎再次使用~" << endl;
			exit(0);
		default:
			cout << "请选择正确的操作!!!" << endl;
			break;
		}
	}

	return 0;
}

如有错误欢迎大家批评指正,同时也会根据大家的意见及时对文章进行改正!

你可能感兴趣的:(数据结构与算法设计,数据结构,算法)