Bootstrap

C/C++结构体|单链表|影院售票系统|含注释|数据结构基础小作业

学了数据结构后,试着用简单的结构体和链表写了个影院售票系统。

代码上可能还有些BUG和逻辑错误,希望大家能够评论出来。

如果有些有趣的想法也请写在留言里,我会认真查看的。

#include <iostream>
#include <assert.h>
#include <cstdlib>

using namespace std;

 typedef struct Session								/*定义电影场次*/
{
	int sid;
	int seat[4][5];							/*设定有30个座位,且有座为0,无座为1*/
	struct Session* next= (struct Session*)malloc(sizeof(struct Session));
};

typedef struct Node
{
	int id = 0;
	char name[20];
	struct Node* next=(struct Node*)malloc(sizeof(struct Node));				/*结构体成员指针需要初始化*/  
	Session* session;
}Node, * List;

void InitList(List p)								/*初始化链表*/	
{
	assert(p!= NULL);								/*如果不存在链表p就结束程序*/
	if (p->next == NULL)							/*让p的next指向空*/
	{
		return;
	}
	p->next = NULL;
}

static Node* GetNode(int id, char name[])			/*设置新结点*/
{
	Node* pGet = new Node();
	pGet = (Node*)malloc(sizeof(Node));				/*结构体成员指针需要初始化*/  
	//assert(pGet == NULL);							/*如果新结点存在其他数值就结束程序*/
	pGet->id = id;
	//pGet->name = tname;							/*无法实现消除自动填充的屯屯屯*/
	//memcpy(pGet->name, name, strlen(name));		/*同上*/
	strcpy_s(pGet->name, name);						/*调用strcpy_s可以使结点中的name不会被屯屯屯填充*/
	pGet->session = new Session();
	pGet->session->sid = 0;
	pGet->session->next = NULL;
	memset(pGet->session->seat, 0, sizeof(int) * 16);	/*seat二维数组初始化*/
	return pGet;									/*返回这个新结点*/
}

bool Insert_head(List p, int id, char name[])		/*头插*/
{
	assert(p != NULL);								/*若不存在链表p,则结束程序*/
	Node* pcur = new Node();
	pcur = GetNode(id, name);
	pcur->next = p->next;
	p->next = pcur;
	return true;
}

Node* Search_pre(List p, int id)					/*查找目标结点的前一个结点,之所以这样查找是为了后面操作方便*/
{
	Node* pcur = p;
	for (; pcur->next != NULL; pcur = pcur->next)
	{
		if (pcur->next->id == id)
		{
			return pcur;
		}
	}
	return NULL;
}

bool Delete(List p, int id)							/*删除*/
{
	Node* p1 = Search_pre(p, id);
	if (p1 == NULL)
	{
		cout << "[反馈信息]无此id" << endl;
		return false;
	}
	Node* pDel = new Node();
	pDel = p1->next;							/*开始进行删除操作,交换next*/
	cout << "[反馈信息]您所删除的电影名为:《" << pDel->name << "》" << endl;
	p1->next = pDel->next;
	free(pDel);
	pDel->next = NULL;
	cout << "[反馈信息]删除成功" << endl;
	return true;
}

bool IsEmpty(List p)								/*判断链表是否为空*/
{
	if (p->next == NULL)
	{
		return true;
	}
	return false;
}

void show(List p)									/*打印链表p*/
{
	Node* pcur = new Node();
	pcur = p->next; 
	cout << "┏━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━┓\n";
	cout << "┃ID " << "\t\t" << "┃NAME\t\t┃" << endl;
	while (pcur != NULL)
	{
		cout << "┣━━━━━━━━━━━━━━━┿━━━━━━━━━━━━━━━┫\n";
		cout << "┃"<<pcur->id << "\t\t┃" << pcur->name << "\t\t┃"<<endl;
		pcur = pcur->next;
	}
	cout << "┗━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━┛\n";
	cout << endl;
}

static Session* GetSession(int sid)
{
	Session *ses = new Session();
	ses = (Session*)malloc(sizeof(Session));
	
	ses->sid = sid;
	ses->next = NULL;
	memset(ses->seat, 0, sizeof(int) * 20);				/*让Session->seat初始化*/
	return ses;
}

bool InsertSession_tail(List p, int id , int sid)
{
	Node* tmovie = new Node();
	tmovie = Search_pre(p, id);
	Session* tses = new Session();

	if (tmovie == NULL)											/*若电影链表不存在,则无法添加场次结点*/
	{
		cout << "[反馈信息]无电影信息,无法添加场次信息" << endl;
		return false;
	}
	else 
	{
//		cout << tmovie->next->id << "\t" <<tmovie->next->name<<endl;
		/*for (; tses != NULL; tses = tses->next) {}
		Session* sGet = GetSession(sid);
		tses->next = sGet;*/
																
		Session* sGet = GetSession(sid);
		sGet->next = tmovie->next->session;
		tmovie->next->session = sGet;
		cout << "[反馈信息]已为ID为[" << tmovie->next->id << "]的电影添加了第[" << tmovie->next->session->sid << "]场次" << endl;
		return true;
	}

}

void showSession(List p,int id)									/*打印某一电影的场次信息*/
{
	Node* pre_movie = new Node();									/*创建个电影结点*/
	pre_movie = Search_pre(p, id);								/*查找到想要查看的电影结点*/
	Session* pses = new Session();								/*创建个用于遍历场次的结点*/
	pses = pre_movie->next->session;
	cout << "┏━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━┓\n";
	cout << "┃场次" << "\t\t" << "┃余位\t\t┃" << endl;
	while (pses != NULL)
	{
		if (pses->sid != NULL) {
			cout << "┣━━━━━━━━━━━━━━━┿━━━━━━━━━━━━━━━┫\n";
			cout << "┃第" << pses->sid << "场\t\t┃";
			int count = 0;
			for (int i = 0; i < 4; i++) {
				for (int j = 0; j < 5; j++) {
					if (pses->seat[i][j] == 0)
						count++;
				}
			}
			cout<< count << "位\t\t┃" << endl;
		}
		pses = pses->next;
	}
	cout << "┗━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━┛\n";
}

bool repetitionNode(List p,int key)
{
	Node* tmovie = new Node();
	tmovie = p->next;
	while (tmovie != NULL)
	{
		if (tmovie->id == key)
			return true;
		tmovie = tmovie->next;
	}
	return false;
}

int repetitionSession(List p, int id,int key)
{
	Node* tmovie = new Node();
	tmovie = p->next;
	Session* tsession = new Session();
	if ((tmovie == NULL)||(Search_pre(p, id)==NULL)) {
		return -1;
	}
	tsession = tmovie->session;
	while (tsession != NULL)
	{
		if (tsession->sid == key) {
			return 1;
		}
		tsession = tsession->next;
	}
	return 2;
}

bool showSeat(List p, int id, int key)
{
	Node* tmovie = new Node();
	tmovie = Search_pre(p, id);
	Session* tsession = new Session();
	tsession = tmovie->next->session;
	while (tsession!=NULL) 
	{
		if (tsession->sid == key) {
			cout << "[提示信息]0表示空座位,1表示已售出" << endl;
			cout << "┏━━━━━━━┯━━━━━━━┯━━━━━━━┯━━━━━━━┯━━━━━━━┯━━━━━━━┓\n";
			cout << "┃\t┃第1列\t┃第2列\t┃第3列\t┃第4列\t┃第5列\t┃\n";
			for (int i = 0; i < 4; i++) {
				cout << "┣━━━━━━━┿━━━━━━━┿━━━━━━━┿━━━━━━━┿━━━━━━━┿━━━━━━━┫\n";
				cout<< "┃第" << i+1 << "行\t┃";
				for (int j = 0; j < 5; j++) {
					cout <<tsession->seat[i][j] << "\t┃";
				}
				cout << endl;
			}
			cout << "┗━━━━━━━┷━━━━━━━┷━━━━━━━┷━━━━━━━┷━━━━━━━┷━━━━━━━┛\n";
			return true;
		}
		tsession = tsession->next;
	}
	return false;
}

bool reserve(List p, int id, int sid)
{
	Node* tmovie = new Node();
	Session* tsession = new Session();
	tmovie = Search_pre(p, id)->next;
	tsession = tmovie->session;
	int hang;
	int lie;
	cout << "请选择行数: ";
	cin >> hang;
	cout << "请选择列数: ";
	cin >> lie;
	while (tsession != NULL)
	{
		if (tsession->sid == sid)
		{
			if ((hang > 4) || (hang < 1) || (lie > 5) || (lie < 1))
			{
				cout << "[反馈信息]选座范围有误" << endl;
				return false;
			}
			else if (tsession->seat[hang - 1][lie - 1] == 1)
			{
				cout << "[反馈信息]该座位已被售出,无法购买" << endl;
				return false;
			}
			else
			{
				tsession->seat[hang - 1][lie - 1] = 1;
				return true;
			}
		}
		else
		{
			cout << "[反馈信息]无此场次" << endl;
			return false;
		}
	}
	
	
	return false;
}

void welcomePanel()
{
	cout << "                                 ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\n";
	cout << "                                 ┃            电影院售票系统            ┃\t\n";
	cout << "                                 ┃            1.初始化电影信息(重置)    ┃\t\n";//初始化,顾名思义会清空可能之前存在的链表并重新创建
	cout << "                                 ┃            2.添加电影信息            ┃\t\n";
	cout << "                                 ┃            3.查找电影信息            ┃\t\n";
	cout << "                                 ┃            4.删除电影信息            ┃\t\n";
	cout << "                                 ┃            5.打印所有电影信息        ┃\t\n";
	cout << "                                 ┃            6.添加电影的场次信息      ┃\t\n";
	cout << "                                 ┃            7.查看电影场次信息        ┃\t\n";
	cout << "                                 ┃            8.查看电影座位信息        ┃\t\n";
	cout << "                                 ┃            9.订票                    ┃\t\n";
	cout << "                                 ┃            0.退出本系统              ┃\t\n";
	cout << "                                 ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛\n";
	cout << "请输入操作数: ";
}

void operation(Node *p,int x)
{
	switch (x)
	{
		case 1: {
			InitList(p);
			cout << "[反馈信息]:初始化成功" << endl;;
			break;
		}
		case 2: {
			int id;
			char name[20];
			cout << "请输入电影ID: ";
			cin >> id;
			cout << "请输入电影名称: ";
			cin >> name;
			cout << "[反馈信息]您所输入的电影名称为: 《";
			cout << name << "》"<<endl;
			if (repetitionNode(p, id))
			{
				cout << "[反馈信息]ID为:" << id << "的电影已存在,无法继续添加信息" << endl;
				break;
			}
			else {
				if (Insert_head(p, id, name))
					cout << "[反馈信息]电影ID为"<<id<<",名为:《"<<name<<"》的电影添加成功" << endl;
				cout << "[反馈信息]已执行完添加电影信息" << endl;
				break;
			}
		}
		case 3: {
			Node* preNode = new Node();
			int id;
			cout << "请输入要查找的电影ID: ";
			cin >> id;
			preNode = Search_pre(p, id);
			if (preNode == NULL)
			{
				cout << "[反馈信息]抱歉,查无此电影" << endl;
			}
			else {
				cout << "在ID为:" << id << " 上的电影名为:《" << preNode->next->name << "》"<<endl;
			}
			cout << "[反馈信息]已执行完查询电影" << endl;
			break;
		}
		case 4: {
			int id;
			cout << "请输入要删除电影的ID: ";
			cin >> id;
			Delete(p, id);
			cout << "[反馈信息]已执行完根据ID删除电影" << endl;
			break;
		}
		case 5: {
			show(p);
			cout << "[反馈信息]已执行完打印电影信息" << endl;
			break;
		}
		case 6: {
			int id, sid;
			cout << "请输入需要添加场次的电影ID:";
			cin >> id;
			cout << "请输入场次的序号(int型):";
			cin >> sid;
			if (repetitionSession(p, id,sid)==1)
			{
				cout << "[反馈信息]ID为 " << id << " 的电影已有场次 " << sid << " ,请勿重新添加" << endl;
				break;
			}
			else if (repetitionSession(p, id,sid) == -1)
			{
				cout << "[反馈信息]查询不到电影ID,无法添加" << endl;
				break;
			}
			else
			{
				if (InsertSession_tail(p, id, sid))
					cout << "[反馈信息]添加成功" << endl;
				cout << "[反馈信息]已执行完添加场次" << endl;
				break;
			}

		}
		case 7: {
			int id;
			cout << "请输入电影ID: ";
			cin >> id;
			Node* preNode = new Node();
			preNode = Search_pre(p, id);
			if (preNode == NULL)
			{
				cout << "抱歉,查无此电影" << endl;
			}
			else {
				showSession(p, id);
				cout << "[反馈信息]已执行完打印特定电影场次信息" << endl;
				break;
			}
		}
		case 8: {
			int id;
			cout << "请输入电影ID: ";
			cin >> id;
			int key;
			cout << "请选择场次: ";
			cin >> key;
			if (showSeat(p, id, key) == false) {
				cout << "[反馈信息]查询不到座位信息" << endl;
			}
			break;
		}
		case 9: {
			int id;
			cout << "请输入想要观看电影的ID: "  ;
			cin >> id;
			int sid;
			cout << "请输入想要观看的场次: ";
			cin >> sid;

			if (reserve(p, id, sid)) {
				cout << "[反馈信息]订票成功" << endl;
				break;
			}
			else {
				cout << "[反馈信息]订票失败" << endl;
				break;
			}
		}
		case 0: {
			break;
		}
		default: {
			cout << "[反馈信息]错误操作数" << endl;
			break;
		}
	}
}

int main()
{
	Node* p = new Node();
	InitList(p);
	int x;
	while (true)
	{
		welcomePanel();
		x = (int)getchar() - 48;			/*通过getchar读取用户输入的第一个字符,并把它转换成int类型,-48是为了控制范围在0-9之间*/
		operation(p, x);
		if (x == 0) {						/*退出判定*/
			exit(1);
		}
		while (getchar() != '\n');			/*读取用户输入的多余的回车*/
	}
}
;