火车票订票系统(哈希表实现,代码+注释)

#ifndef _SYSTEM_H_
#define _SYSTEM_H_
#include<stdio.h>
#include<stdlib.h>
#include<string>
#define SIZE 20000
using namespace std;
enum bugvalue
{
	NULL_ERROR = -4,
	MALLOC_ERROR,
	NOT_FOUND,
	ERROR,
	TRUE,
};

typedef struct train
{
	char trainNumber[50];
	char departureStation[50];
	char arrivalStation[50];
	char departureTime[10];
	char arrivalTime[10];
	double price;
	int seatCount;
}data_type;

typedef struct hash_node
{
	data_type data;//数据
	struct hash_node* next;//结点,相同键用链式存储
}hashnode, * hashnodep;

typedef struct Hash
{
	hashnode* hash[SIZE];//哈希表的大小或者槽位数量
}Hash, * Hashp;

Hashp creat(void);
void menu(void);
int addp(Hashp p, data_type a);
int find(Hashp p, data_type* pdata);
int outt(Hashp p);
int del(Hashp p, data_type* pdata);
int destory(Hashp* p);
int hashcul(int hdata);
int save(Hashp p);
hashnodep savecreat(void);
int change(Hashp p, data_type pdata);
int login(void);
#endif

如何解决下标冲突:

写结构体时加入next指针,相同key值进行横向链表式存储

.cpp代码:

#define _CRT_SECURE_NO_WARNINGS
#include"t.h"
#include"string.h"
#include<iostream>
#include<cstdlib>
#include<time.h>
using namespace std;
Hashp creat(void)
{
	Hashp p = (Hashp)malloc(sizeof(Hash));//为新的哈希表分配空间
	if (NULL == p)//分析是否成功分配
	{
		printf("malloc error\n");
		return NULL;
	}
	memset(p, 0, sizeof(Hash));//新分配的内存块设置为0,所有字段初始化
	return p;
}
int hashcul(int hdata)//将给定的整数转化为哈希值,将键转换为哈希值索引
{
	return hdata / 1000 + hdata % 1000 - 20221;
}//key函数
int time(Hashp p, data_type pdata)
{
	int i;
	clock_t start, end;
	double duration;

	start = clock();

	for (i = 0; i < 10000; i++) {
		sprintf(pdata.trainNumber, "%d", i + 1); 
		sprintf(pdata.departureStation, "Departure%d", i + 1); 
		sprintf(pdata.arrivalStation, "Arrival%d", i + 1); 
		sprintf(pdata.departureTime, "09:00"); 
		sprintf(pdata.arrivalTime, "11:00"); 
		pdata.price = 100.0; 
		pdata.seatCount = 100; 

		addp(p, pdata);
	}

	end = clock();
	duration = (double)(end - start) / CLOCKS_PER_SEC;
	printf("一共进行了10000次数据添加,运行时间:%f秒\n", duration);

	return 0;
}

int addp(Hashp p, data_type a)
{
	if (NULL == p)//判断传入的哈希表是否有效
	{
		printf("NULL_ERROR\n");
		return NULL_ERROR;
	}
	
	hashnodep pnode = (hashnodep)malloc(sizeof(hashnode));//为新的哈希节点动态分配内存
	if (NULL == pnode)
	{
		printf("MALLOC_ERROR\n");
		return MALLOC_ERROR;
	}
	pnode->data = a;//将传入的数据a赋值给新节点的数据字段

	int id = atoi(pnode->data.trainNumber);//车次号转化为整数,确定结点存放在哈希表的位置
	pnode->next = p->hash[id];//新节点的next指针设置为当前哈希表中相同索引的位置
	p->hash[id] = pnode;
	return TRUE;
}
int del(Hashp p, data_type* pdata)
{
	if (NULL == p)
	{
		printf("NULL_ERROR\n");
		return NULL_ERROR;
	}

	int id = atoi(pdata->trainNumber);
	hashnodep pt = p->hash[id];//根据索引找到相应的结点
	if (NULL == pt)
	{
		return NOT_FOUND;
	}
	if (0 == strcmp(pdata->trainNumber, pt->data.trainNumber))//再次对比找到的结点和要删除的索引是否相同
	{
		
		p->hash[id] = pt->next;//对应索引的结点设置为下一个结点,达到删除效果
		strcpy(pdata->departureStation, pt->data.departureStation);
//将删除节点数据保存到pdata中
		strcpy(pdata->arrivalStation, pt->data.arrivalStation);
		strcpy(pdata->departureTime, pt->data.departureTime);
		strcpy(pdata->arrivalTime, pt->data.arrivalTime);
		pdata->price = pt->data.price;
		pdata->seatCount = pt->data.seatCount;
		free(pt);//释放以删除结点内存
		pt = NULL;
	}
	return TRUE;
}
int change(Hashp p, data_type pdata)
{
	if (NULL == p)
	{
		printf("NULL_ERROR\n");
		return NULL_ERROR;
	}
	if (atoi(pdata.trainNumber) < 0)
	{
		printf("输入的车次不存在\n");
		return NOT_FOUND;
	}
	int id = atoi(pdata.trainNumber);
	hashnodep pt = p->hash[id];//通过索引找到对应结点,结点和车次代表不同,结点是哈希函数生成,然后通过结点遍历该节点的链表,找到匹配的车次
	if (NULL == pt)
	{
		printf("NOT_FOUND\n");
		return NOT_FOUND;
	}
	else
	{
		while (pt != NULL)
		{
			if (0 == strcmp(pt->data.trainNumber, pdata.trainNumber))
			{
				printf("要修改的车次信息为:起点:%s\t终点:%s\t出发时间:%s\t到达时间:%s\t价格:%.1f\t座位数量:%d\n",  pt->data.departureStation, pt->data.arrivalStation, pt->data.departureTime, pt->data.arrivalTime, pt->data.price, pt->data.seatCount);
				printf("修改新车次的 序号 起点 终点 出发时间 到达时间 价格 座位数量\n");
				int sca = scanf("%s %s %s %s %s %lf %d", &pdata.trainNumber, &pdata.departureStation, &pdata.arrivalStation, &pdata.departureTime, &pdata.arrivalTime, &pdata.price, &pdata.seatCount);
				if (sca != 7)
				{
					printf("输入格式错误!\n");
					return ERROR;
				}
				strcpy(pt->data.trainNumber, pdata.trainNumber);
				strcpy(pt->data.departureStation, pdata.departureStation);
				strcpy(pt->data.arrivalStation, pdata.arrivalStation);
				strcpy(pt->data.departureTime, pdata.departureTime);
				strcpy(pt->data.arrivalTime, pdata.arrivalTime);
				pt->data.price = pdata.price;
				pt->data.seatCount = pdata.seatCount;
			}
			pt = pt->next;//遍历该节点的链表
		}
	}
	return TRUE;
}
int find(Hashp p,string a1,string a2)
{
	int count = 0;
	if (NULL == p)
	{
		printf("NULL_ERROR\n");
		return NULL_ERROR;
	}
	for (int i = 0; i < SIZE; i++)
	{
		if (NULL == p->hash[i])
		{
			continue;
		}
		hashnodep pt = p->hash[i];
		while (NULL != pt)
		{
			if (0 == strcmp(pt->data.departureStation, a1.c_str()) && (0 == strcmp(pt->data.arrivalStation, a2.c_str())))
			{
				printf("车次:%s\t起点:%s\t终点:%s\t出发时间:%s\t到达时间:%s\t价格:%1f\t座位数量:%d\n", pt->data.trainNumber, pt->data.departureStation, pt->data.arrivalStation, pt->data.departureTime, pt->data.arrivalTime, pt->data.price, pt->data.seatCount);
				count++;
			}
			pt = pt->next;
		}

	}
	if (count == 0)
	{
		printf("未找到符合条件车次。");
	}
	printf("**************************************************\n");
	return TRUE;
}
//显示表
int outt(Hashp p)
{
	if (NULL == p)
	{
		printf("NULL_ERROR\n");
		return NULL_ERROR;
	}
	for (int i = 0; i < SIZE; i++)//这个循环是遍历哈希表的每个槽位
	{
		if (NULL == p->hash[i])
		{
			continue;
		}
		hashnodep pt = p->hash[i];//指向当前的第一个节点
		while (NULL != pt)//循环当前槽位中的链表
		{
			printf("车次:%s\t起点:%s\t终点:%s\t出发时间:%s\t到达时间:%s\t价格:%.1f\t座位数量:%d\n", pt->data.trainNumber, pt->data.departureStation, pt->data.arrivalStation, pt->data.departureTime, pt->data.arrivalTime, pt->data.price, pt->data.seatCount);
			pt = pt->next;
		}
		printf("*********************************************************\n");
	}
	return TRUE;
}
int destory(Hashp* p)
{
	if (NULL == *p)
	{
		printf("NULL_ERROR\n");
		return NULL_ERROR;
	}
	for (int i = 0; i < SIZE; i++)
	{
		if (NULL == (*p)->hash[i])
		{
			continue;
		}
		hashnodep pdel = (*p)->hash[i];
		while (pdel != NULL)
		{
			(*p)->hash[i] = pdel->next;
			free(pdel);//释放结点内存
			pdel = (*p)->hash[i];
		}
	}
	free(*p);//释放哈希表结构体
	*p = NULL;
	return 0;
}

void mainMenu() {
	std::cout << "===== 火车票订票管理系统菜单 =====\n";
	std::cout << "1. 添加车次(管理员)\n";
	std::cout << "2. 编辑已有车次(管理员)\n";
	std::cout << "3. 查询所有车次信息\n";
	std::cout << "4. 购票\n";
	std::cout << "5. 退票\n";
	std::cout << "6. 改签\n";
	std::cout << "7. 查询车票\n";
	std::cout << "8. 创建哈希表\n";
	std::cout << "9. 摧毁哈希表\n";
	std::cout << "10. 性能显示\n";
	std::cout << "请输入您的选择: ";
}
int login(void)
{
	printf("********火车票订票管理系统*******\n");
	printf("*********欢迎使用,请登录**********\n");
	printf("1*****************************登录\n");
	printf("2*****************************退出\n");
	printf("**********************************\n");
	printf("请选择功能:");
	int menu = 0;
	if (1 != scanf("%d", &menu))
	{
		printf("输入格式不正确 致命错误\n");
		return 0;
	}
	char s[10] = { 0 };
	char s1[10] = { 0 };
	switch (menu)
	{
		
	case 1:
		printf("输入用户名及密码\n");
		scanf("%s%*c%s", s, s1);
		if (!strcmp("admin", s) && !strcmp("123", s1))
		{
			printf("Welcome! administrator!\n");
			return 1;
		}
		else if (!strcmp("stu", s) && !strcmp("456", s1))
		{
			printf("Welcome! stu\n");
			return 2;
		}
		else
		{
			printf("用户名或密码错误 请重新输入\n\n");
			login();
			break;
		}
	default:
	{printf("程序已退出\n");
	return 0;
	}}
	return 0;
}
int exchange(Hashp p, string a, string b)
{
	int count = 0; double amount; double money;
	if (NULL == p)
	{
		printf("NULL_ERROR\n");
		return NULL_ERROR;
	}
	for (int i = 0; i < SIZE; i++)
	{
		if (NULL == p->hash[i])
		{
			continue;
		}
		hashnodep pt = p->hash[i];
		while (NULL != pt)
		{
			if (0 == strcmp(pt->data.trainNumber, a.c_str()))
			{
				pt->data.seatCount++;
				amount = pt->data.price;
				count++;
			}
			else if (0 == strcmp(pt->data.trainNumber, b.c_str()))
			{
				pt->data.seatCount--;
				money = pt->data.price;
				count++;
			}
			pt = pt->next;
		}
	}
	double a1 = money - amount; double x = 0;
	double a2 = amount - money;
	if (a1 > 0)
	{
		printf("请支付%lf元\n", a1);
		scanf("%lf", &x);
		if (a1 == x)
			printf("支付成功");
	}
	else
	{
		printf("已退回%lf元", a2);
	}

	printf("**************************************************\n");
	return TRUE;


}
int refund(Hashp p, string a)
{
	int count = 0; double amount; double money;
	if (NULL == p)
	{
		printf("NULL_ERROR\n");
		return NULL_ERROR;
	}
	for (int i = 0; i < SIZE; i++)
	{
		if (NULL == p->hash[i])
		{
			continue;
		}
		hashnodep pt = p->hash[i];
		while (NULL != pt)
		{
			if (0 == strcmp(pt->data.trainNumber, a.c_str()))
			{
				printf("已退回:%1f元\n", pt->data.price);
				pt->data.seatCount++;
				count++;
			}
			pt = pt->next;
		}
		if (count == 0)
		{
			printf("车次输入有误。");
		}
	}
	printf("**************************************************\n");
	return TRUE;
}
int payTicket(Hashp p,string a)
	{
	int count = 0; double amount; double money;
		if (NULL == p)
		{
			printf("NULL_ERROR\n");
			return NULL_ERROR;
		}
		for (int i = 0; i < SIZE; i++)
		{
			if (NULL == p->hash[i])
			{
				continue;
			}
			hashnodep pt = p->hash[i];
			while (NULL != pt)
			{
				if (0 == strcmp(pt->data.trainNumber, a.c_str()) )
				{
					printf("请支付:%1f\n",  pt->data.price);
					amount = pt->data.price;
					pt->data.seatCount--;
					count++;
				}
				pt = pt->next;
			}
		}
		if (count == 0)
		{
			printf("车次输入有误。");
		}
		scanf("%lf", &money);
		if (money == amount)
			printf("支付成功!");
		else
			printf("输入金额有误");

	printf("**************************************************\n");
	return TRUE;
}
int main()
{int user = login();
	int me = 0; int mod = 0; int ad = 0;
	char n[20];
	data_type cdata = {0};
	Hashp ph = NULL;
	char s1[20]; char s2[20];
	while (1)
	{
		mainMenu();
		printf("选择以上功能的一种:");
		scanf("%d", &me);
		switch (me)
		{case 1:
		{	printf("\n");
			printf("********Mode selection********\n");
			printf("1*********************输入车次\n");
			printf("2*************************取消\n");
			printf("******************************\n");
			printf("选择输入模式:");
			if (1 != scanf("%d", &mod))
			{
				printf("输入格式不正确\n");
				return ERROR;
			}
			switch (mod)
			{case 1:
			{if (2 == user)
			{printf("没有访问权限");break;
			}
			printf("输入添加车次的 序号 起点 终点 出发时间 到达时间 价格 座位数量\n");
			if (7 != scanf("%49s %49s %49s %49s %49s %lf %d", cdata.trainNumber, cdata.departureStation, cdata.arrivalStation, cdata.departureTime, cdata.arrivalTime, &cdata.price, &cdata.seatCount))
			{printf("车次信息不完整\n");
			}
			ad = addp(ph, cdata);
			if (ad < 0)
			{printf("ERROR\n\n");}
			else
			{printf("添加成功!\n\n");}
			case 3:
				printf("\n");
			}
			}
			break;
		case 2:
		{
			if (2 == user)
			{
				printf("你的权限不足 无法操作\n\n");
				break;
			}
			int mod = 0;
			printf("\n");
			printf("********Mode selection********\n");
			printf("1*********************修改车次信息\n");
			printf("2*********************删除车次信息\n");
			printf("3*************************取消\n");
			printf("******************************\n");
			printf("选择操作模式:");
			scanf("%d", &mod);
			switch (mod)
			{
			case 1:
			{printf("请输入需要修改的车次。");
			scanf("%s", cdata.trainNumber);
				int de = change(ph, cdata);
				
				if (de < 0)
				{
					printf("ERROR\n\n");
				}
				else if (de == NOT_FOUND)
				{
					printf("该车次不存在\n\n");
				}
				else
				{
					printf("修改成功\n\n");
				}
				break;
			}
			case 2:
			{
				int de = del(ph, &cdata);
				if (NOT_FOUND == de)
				{
					printf("该车次不存在\n\n");
				}
				else if (de < 0)
				{
					printf("ERROR\n\n");
				}
				else
				{

					printf("删除成功\n\n");
				}
				break;
			}
			case 3:
			{
				printf("\n");
			}
			}
			break;
		}
		case 3:
		{
			int out = outt(ph);
			if (out < 0)
			{
				printf("ERROR\n\n");
			}
			else
				printf("输出完成\n\n");
			break;
		}

		case 4: {
			printf("输入你所要支付的车次:");
			scanf("%s", &n);
			payTicket(ph,n); }
			break;
		case 5: {
			printf("请输入退订车次:");
			scanf("%s", s1);
			refund(ph, s1);
		}
			  break;

		case 6:
		{
			printf("请输入改签车次:");
			scanf("%s", s1);
			printf("请输入新车次:");
			scanf("%s", s2);
			exchange(ph, s1, s2);
		}
		break;

		case 7: {
			printf("请输入出发点:");scanf("%s", s1);
			printf("请输入终点:");scanf("%s", s2);
			find(ph,  s1, s2);
			
		}
			  break;
		case 9:
		{
		
			destory(&ph);
			printf("程序已退出\n");
			return TRUE;}
		case 8:
		{ph = creat();
		if (NULL == ph)
		{
			printf("NULL_ERROR\n");
		}
		else
		{
			printf("创建哈希表成功\n\n");
			
		}
		 }break;
		case 10:
			time(ph, cdata);
			break;
}}
       
		
	}return 0;
}

效果图:

 

  • 8
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值