哈希表实现电话号码查询系统

list.h

#pragma once	//预防头文件重复引用

#include <stdio.h>
#include<stdlib.h>
#include<string.h>
#include <windows.h>
#include<assert.h>

#define MAX_N 30  //姓名最大长度
#define MAX_T 15  //电话号码最大长度
#define MAX_A 100 //地址最大长度

//用户信息结构体
typedef struct InfoNode
{
	char _name[MAX_N];		//姓名
	char _telephone[MAX_T];	//电话号码
	char _address[MAX_A];	//地址
}InfoNode;

//输入时以循环双链表存储
typedef struct InfoNode_List
{
	InfoNode* _ListInfo;			//结构体指针来存放用户信息
	struct InfoNode_List* _next;	//指向下一个节点
	struct InfoNode_List* _pre;		//指向上一个节点
}InfoNode_List;

//初始化链表
void InitList(InfoNode_List* pl);

//输入用户信息节点
void ScanfNode(InfoNode* pnode);

//增加链表节点
void AddList(InfoNode_List* pl);

//修改用户信息
void ChangeNode(InfoNode* pnode);

//删除节点
void DeleteListNode(InfoNode_List* pl);

//姓名查找
InfoNode_List* FindName(InfoNode_List* phead, char* name);

//电话号码查找
InfoNode_List* FindTelephone(InfoNode_List* phead, char* telephone);

//打印信息
void ShowInfo(InfoNode_List* phead);

//打印一个用户的信息
void ShowOnce(InfoNode* pi);

//按字符ASCLL比较两个用户信息的大小
int CompareInfo(InfoNode* pi1, InfoNode* pi2);

//排序   --> 插入排序法
void InsertSort(InfoNode_List* phead);

//当前信息写入文件
void WriteFileInfo(InfoNode_List* phead);

//读取把文件信息插入链表 (头插法)
void ReadFileInfo(InfoNode_List* phead);

//模拟加载页面
void my_loading(const int time);

//0.5秒睡眠加清屏
void SleepCls();

//模拟进度条
void ProgressBar();

 list.c

#include "list.h"

//睡眠加清屏
void SleepCls()
{
	Sleep(500);//程序在这里暂停0.5秒
	system("cls");//清屏操作
}

//模拟进度条
void ProgressBar()
{
	int i = 0;
	char arr[51] = { 0 };	//存放进度的"#"
	char* brr = "|/-\\";	//模拟转圈圈
	printf("\n");
	for (i = 0; i < 50; i++)
	{
		arr[i] = '#';
		printf("[%-50s][%d%%][%c]\r", arr, (i + 1) * 2, brr[i % 4]);	
		Sleep(50);
	}
	printf("\n");	//退格后的光标向下一行移动
}


//初始化链表
void InitList(InfoNode_List* phead)
{
	assert(phead);

	phead->_next = phead;	//头结点的下一个节点指向自己
	phead->_pre = phead;	//头结点的上一个节点指向自己
}

//节点输入用户信息
void ScanfNode(InfoNode* pnode)
{
	char name[MAX_N] = { '\0' }, telephone[MAX_T] = { '\0' }, address[MAX_A] = { '\0' };
	printf("_______________________________________\n");
	printf("|\n");
	printf("|请输入用户姓名-->");
	scanf("%s", name);
	strcpy(pnode->_name, name);
	printf("|请输入用户电话号码-->");
	scanf("%s",telephone);
	strcpy(pnode->_telephone, telephone);
	printf("|请输入用户地址-->");
	scanf("%s",address);
	strcpy(pnode->_address, address);
	printf("|______________________________________\n");
}

//修改用户信息
void ChangeNode(InfoNode* pnode)
{
	char choose_C;
	char name[MAX_N] = { '\0' }, telephone[MAX_T] = { '\0' }, address[MAX_A] = { '\0' };
	printf("_______________________________________\n");
	printf("|\n");
	printf("|请输入修改后用户姓名-->");
	scanf("%s", name);
	strcpy(pnode->_name, name);
	printf("|请输入修改后用户电话号码-->");
	scanf("%s", telephone);
	strcpy(pnode->_telephone, telephone);
	printf("|是否修改用户的地址(Y或者y)-->");
	getchar();			//吸收电话号码输入后的回车字符
	scanf("%c", &choose_C);
	if (choose_C == 'y' || choose_C == 'Y')
	{
		printf("|请输入用户地址-->");
		scanf("%s", address);
		strcpy(pnode->_address, address);
	}
	else
	{
		printf("|用户地址  -->%s\n", pnode->_address);
	}
	printf("|______________________________________\n");
}

//增加用户信息
void AddList(InfoNode_List* phead)		//采用头插法
{
	assert(phead);						//防止传入野指针

	InfoNode_List* node;
	node = (InfoNode_List*)malloc(sizeof(InfoNode_List));	
	node->_ListInfo = (InfoNode*)malloc(sizeof(InfoNode));	//为用户信息结构体开辟空间
	ScanfNode(node->_ListInfo);			//输入用户信息

	//头插法进行节点的插入
	node->_next = phead->_next;
	phead->_next->_pre = node;

	node->_pre = phead;
	phead->_next = node;

	printf("----------------------------------\n");
	printf("%s的信息增加完毕\n\n", node->_ListInfo->_name);
}

//删除节点
void DeleteListNode(InfoNode_List* phead)
{
	assert(phead);

	InfoNode_List* pre = (InfoNode_List*)malloc(sizeof(InfoNode_List));
	char sure='\0';
	int option=0;

	//打印内部菜单
	printf("-----------------------------------------\n");
	printf("|\t按用户姓名删除(系统默认)-->1\t|\n");
	printf("-----------------------------------------\n");
	printf("|\t按用户电话号码查找并删除-->0\t|\n");
	printf("-----------------------------------------\n");
	printf("您的选择-->");
	scanf("%d", &option);
	if (option != 0)	//默认按照姓名查询删除
	{
		option = 1;
	}
	getchar();			//吸收scanf函数输入停止时的回车字符
	switch (option)
	{
		case 1:
		{
			  char name[MAX_N] = { '\0' };
			  printf("请输入想要删除联系人的姓名-->");
			  gets(name);
			  pre = FindName(phead, name);			//返回要删除节点
			  break;
		}
		case 0:
		{
			char telephone[MAX_T] = { '\0' };
			printf("请输入想要删除用户的电话号码-->");
			gets(telephone);
			pre = FindTelephone(phead, telephone);	//返回要删除节点
			break; 
		}
	}
	if (pre)			//如果找到该节点,最后确认一次是否删除
	{
		printf("确认删除?y/Y -->");
		scanf("%c", &sure);
		if (sure == 'y' || sure == 'Y')			//确认删除进行链表删除操作
		{
			InfoNode_List* cur = pre;
			cur->_pre->_next = cur->_next;
			cur->_next->_pre = cur->_pre;
			free(cur);							//释放掉要删除的节点空间
			printf("删除成功\n");
		}
		else
		{
			printf("取消删除,返回主页面\n");	//不想删除则返回主页面
		}
	}
}

//姓名查找(删除函数中调用)
InfoNode_List* FindName(InfoNode_List* phead, char* name)
{
	assert(phead  && name);				//防止传入野指针

	InfoNode_List* node = phead->_next;	//保留头结点位置

	//寻找该用户
	//循环结束的条件  链表指针node指向头结点  或  node节点为要删除的节点
	while (node!=phead  &&  strcmp(node->_ListInfo->_name, name) != 0)
	{
		node = node->_next;				//移动指针
	}
	if (node!=phead)
	{
		//找到后进行打印
		printf("该用户已经找到\n");
		ShowOnce(node->_ListInfo);
		return node;		//返回要删除节点
	}
	else
	{
		printf("没有找到该用户,将返回主页面\n");
		return NULL;		//返回为NULL
	}
}

//打印链表中的用户信息
void ShowInfo(InfoNode_List* phead)
{
	assert(phead);

	InfoNode_List* node = phead->_next;
	if (node==phead)			//防止链表中没有用户信息
	{
		printf("没有用户信息可以打印\n");
		return;
	}
	printf("_________________________________________________________\n");
	printf("\t姓名\t   电话号码\t   地址\n");
	printf("_________________________________________________________\n");
	while (node!=phead)
	{
		printf("%12s\t%11s\t%s\n",	node->_ListInfo->_name, \
									node->_ListInfo->_telephone, \
									node->_ListInfo->_address);
		printf("---------------------------------------------------------\n");
		node = node->_next;
	}
}

//打印一个节点的信息
void ShowOnce(InfoNode* pi)
{
	assert(pi);

	printf(" _________________________________________________\n");
	printf("|\n");
	printf("|姓名:	   %s\n", pi->_name);
	printf("|电话号码:%s\n", pi->_telephone);
	printf("|地址:    %s\n", pi->_address);
	printf("|_________________________________________________\n");
}


//电话号码查找(删除函数中调用)
InfoNode_List* FindTelephone(InfoNode_List* phead, char* telephone)
{
	assert(phead  && telephone);		//防止传入野指针

	InfoNode_List* node = phead->_next;	//保留头结点位置

	//寻找该用户
	//循环结束的条件  链表指针node指向phead  或  node为要删除的节点
	while (node!=phead  &&  strcmp(node->_ListInfo->_telephone, telephone) != 0)
	{
		node = node->_next;				//移动节点
	}
	if (node!=phead)					//如果找到,对要删除节点进行打印
	{
		printf("该用户已经找到\n");
		ShowOnce(node->_ListInfo);
		return node;					//函数返回要删除节点
	}
	else
	{
		printf("没有找到该用户,将返回主页面\n");
		return NULL;					//没有找到则返回NULL
	}
}

//按字符ASCLL比较两个用户信息的大小
int CompareInfo(InfoNode* pi1, InfoNode* pi2)
{
	assert(pi1 && pi2);

	int ans=0;				//记录比较后的结果
	/*ans = strcmp(pi1->_name, pi2->_name);		//先按照姓名比较
	if (ans == 0)			//结果为0,表示名字相等  再比较电话号码
	{
		//电话号码不可能相等,返回比较后的结果
		ans = strcmp(pi1->_telephone, pi2->_telephone);
	}
	return ans;*/

	return (ans = strcmp(pi1->_name, pi2->_name)) != 0 ? \
					ans : strcmp(pi1->_telephone, pi2->_telephone);
}

//排序   --> 循环双链表的插入排序法
void InsertSort(InfoNode_List* phead)
{
	assert(phead);

	InfoNode_List* cur = phead->_next;	//cur 指针记录当前被比较的节点
	InfoNode_List* node = cur->_next;   //node 指针记录需要比较的节点
	InfoNode_List* nodenext;            //nodenext 指针记录下一个需要比较的节点
	
	while (node!=phead)					//循环退出的条件  node节点不是头结点
	{
		cur = phead->_next;				//每次比较都从头结点的下一个节点开始

		//找到第一个比node节点信息大的节点,这个节点记录为cur
		while (cur != node && \
			CompareInfo(cur->_ListInfo, node->_ListInfo) <= 0)
		{
			cur = cur->_next;
		}

		nodenext = node->_next;			//保存需要比较节点的下一个节点
		//如果cur==node  表示该节点就是前面节点中最大的,不做处理,跳出循环
		if (cur != node)
		{
			//先连接node节点的前后两个节点
			nodenext->_pre = node->_pre;  
			node->_pre->_next = nodenext;

			//再连接node节点和cur节点的前一个节点
			cur->_pre->_next = node;
			node->_pre = cur->_pre;

			//最后把node节点和cur连接,完成在cur节点的前面插入
			node->_next = cur;
			cur->_pre = node;
		}

		//把下一个需要比较的节点给node
		node = nodenext;
		nodenext = node->_next;
	}
	
	char choose_s='\0';
	my_loading(3);
	printf("链表信息的排序已完成\n");
	printf("是否显示排序后的链表(y或Y)-->");
	
	scanf("%c", &choose_s);
	if (choose_s == 'y' || choose_s == 'Y')
	{
		SleepCls();			//睡眠加清屏
		ShowInfo(phead);	//打印信息
	}
}

//模拟加载界面
void my_loading(const int time)
{
	int i = 0;
	for (i = 1; i < time; i++)
	{
		printf("\t%d......\n",i);
		Sleep(500);
	}
}

//将链表的信息写入文件
void WriteFileInfo(InfoNode_List* phead)
{
	assert(phead);

	InfoNode_List* node = phead->_next;
	if (node==phead)				//防止链表中没有用户信息
	{
		printf("没有需要储存的用户信息\n");
		return;
	}
	int num = 0;					//记录用户数量
	FILE* fp;						//文件指针
	fp = fopen("text.txt", "w");	// 打开写入的文件 
	//文件指针完成的功能是写,打开的文件是 text.txt

	while (node!=phead)
	{
		fprintf(fp, "-%s\t\t%s\t\t%s\n", node->_ListInfo->_name, \
										node->_ListInfo->_telephone,\
										node->_ListInfo->_address);
		node = node->_next;
		num++;			//记录载入用户的数量
	}
	fprintf(fp, "|\t\t共%d个用户信息\t\t|\n",num);
	fclose(fp);			//关闭文件
	my_loading(4);		//模拟加载界面
	printf("用户信息已保存\n");
}

//读取文件中的信息
void ReadFileInfo(InfoNode_List* phead)
{
	assert(phead);

	FILE* fp;			//建立文件指针
	char flag='\0';		//判断文件读取结束的标志
	fp = fopen("text.txt", "r");	//打开文件
	while ((flag = fgetc(fp)) != '|')
	{
		//创建一个节点来存储文件中的用户信息
		InfoNode_List* node;
		node = (InfoNode_List*)malloc(sizeof(InfoNode_List));
		//为用户信息结构体开辟空间
		node->_ListInfo = (InfoNode*)malloc(sizeof(InfoNode));
		fscanf(fp, "%s%s%s", node->_ListInfo->_name, \
							node->_ListInfo->_telephone, \
							node->_ListInfo->_address);
		flag = fgetc(fp);	//处理掉当前行末的换行符

		//节点插入(尾插法)
		//先把node节点和链表的尾连起来
		node->_pre = phead->_pre->_next;
		phead->_pre->_next = node;

		//再把node节点和链表的头连接起来
		node->_next = phead;
		phead->_pre = node;
	}
	fclose(fp);				//关闭文件
	my_loading(4);			//模拟加载界面
	printf("用户电话号码信息载入完毕\n");
}

hashname.h

#include"list.h"

//用姓名为关键字建立哈希表
//取权值的公式  姓名的首尾字符相加再对50取余
//处理冲突的方法 再散列法

#define DIV (50)			//除留余数法的除数

typedef struct HTName	
{
	InfoNode* _NameInfo;	//用户信息
	int _key;				//建表后的权值
	int _ishave;			//判断该位置有没有填入用户
}HTName;

typedef struct NameTableH
{
	HTName* _NameArr;	//动态开辟数组来存放用户信息
	int _psize;			//当前存放信息的用户数量
	int _capacity;		//数组当前的容量
}NameTableH;


//初始化哈希表
void InitNameTableH(NameTableH* pn);

//哈希表扩容
void AddCapacity(NameTableH* pn,const int key);

//建立哈希表
void SetNameTableH(NameTableH* pn, InfoNode_List* phead);

//查找用户信息
int FindNameTableH(NameTableH* pn, const char* name);

//修改用户信息
void ChangeNameTableH(NameTableH* pn);

 hashname.c

#include "hashname.h"

//初始化哈希表
void InitNameTableH(NameTableH* pn)
{
	assert(pn);

	pn->_psize = 0;			//数组中没有成员
	pn->_capacity = DIV;	//数组当前的容量为除留余数法的除数
	pn->_NameArr = (HTName*)malloc(sizeof(HTName)*pn->_capacity);
	//为数组开辟当前容量的空间

	int i = 0;
	for (i = 0; i < pn->_capacity; i++)
	{
		//将数组每个位置初始化为0
		//0表示该位置没有存放成员信息
		pn->_NameArr[i]._ishave = 0;	
	}
}

//哈希表扩容
void AddCapacity(NameTableH* pn, const int key)
{
	assert(pn && key < pn->_capacity);

	pn->_capacity *= 2;
	pn->_NameArr = (HTName*)realloc(pn->_NameArr, sizeof(HTName)*pn->_capacity);
	//realloc函数进行扩容,不会改变数组原来空间内容的信息
	//每次扩容的大小为当前容量的2倍

	int i = 0;
	for (i = pn->_psize;i< pn->_capacity; i++)
	{
		pn->_NameArr[i]._ishave = 0;					//初始化新增加的空间有无用户的情况
	}

	//为了不改变哈希表查找时候的顺序
	//扩容完毕后,将数组中当前权值前面的信息都依次移动到新开辟的地方后面
	for (i = 0; i < key; i++)
	{
		pn->_NameArr[i + pn->_psize]._NameInfo = pn->_NameArr[i]._NameInfo;	//用户信息移动
		pn->_NameArr[i + pn->_psize]._key = pn->_NameArr[i]._key;			//权值移动
		pn->_NameArr[i]._ishave = 0;					//当前位置置为无值
		pn->_NameArr[i + pn->_psize]._ishave = 1;		//移动后的位置置为有值
	}
}

//建立哈希表
void SetNameTableH(NameTableH* pn, InfoNode_List* phead)
{
	assert(pn && phead);

	if (phead==phead->_next)
	{
		printf("没有用户的信息!\n");
		return;
	}
	InfoNode_List* node = phead->_next;
	char Fname, Lname;	//一个表示姓名的首字符,一个表示尾字符
	int len;			//表示姓名的长度
	int key;			//表示计算后的权值
	while (node!=phead)
	{
		Fname = node->_ListInfo->_name[0];
		len = strlen(node->_ListInfo->_name);
		Lname = node->_ListInfo->_name[len-1];
		key = (int)(Fname + Lname) % DIV;	//计算权值

		if (pn->_psize == pn->_capacity)	//判断是否需要扩容
		{
			AddCapacity(pn,key);
		}

		if (!pn->_NameArr[key]._ishave)//该位置没有出现冲突
		{
			//将该节点中用户信息节点 赋值给 哈希表中该位置用户信息节点
			pn->_NameArr[key]._NameInfo = node->_ListInfo;
			//记录该位置权值
			pn->_NameArr[key]._key = key;
			//修改该位置为有值
			pn->_NameArr[key]._ishave = 1;
		}
		else //出现冲突,用再散列法解决冲突
		{
			int i = key+1;
			while (pn->_NameArr[i]._ishave)//找到第一个不冲突的节点
			{
				i = (i + 1) % pn->_capacity;//让该位置在逻辑上动态连接起来
			}

			//将该节点中用户信息节点 赋值给 哈希表中该位置用户信息节点
			pn->_NameArr[i]._NameInfo = node->_ListInfo;
			//记录该位置权值
			pn->_NameArr[i]._key = key;
			//修改该位置为有值
			pn->_NameArr[i]._ishave = 1;
		}

		node = node->_next;
		pn->_psize++;
	}

	ProgressBar();	//模拟进度条
	printf("\t姓名哈希表建立完毕\n");
	SleepCls();		//0.5秒睡眠+清屏
}

//查找用户信息
int FindNameTableH(NameTableH* pn, const char* name)
{
	assert(pn && name);

	char Fname, Lname;
	Fname = name[0];
	int len = strlen(name);
	Lname = name[len - 1];  //取首字符和尾字符

	int key = (int)(Fname + Lname) % DIV;	//计算权值
	int i = key;
	int count = 0;
	//查找时循环跳出的条件
	//1.当前位置没有存放用户信息
	//2.如果数组可以存放的用户已经满了,并且没有需要查找的人
	//即循环走了当前容量的步骤  ---> count==pn->_capacity
	//3.权值相同
	while (		pn->_NameArr[i]._ishave  \
			&& (count++)<pn->_capacity	 \
		   &&   pn->_NameArr[i]._key != key)
	{
		i = (i + 1) % pn->_capacity;
	}
	//判断是哪种条件跳出循环
	//如果是1 2 ,则表示没有找到,退出函数
	if (pn->_capacity == count || !pn->_NameArr[i]._ishave)
	{
		printf("没有找到该用户\n");
		return -1;
	}
	//3 表示找到,进行打印
	ShowOnce(pn->_NameArr[i]._NameInfo);
	return i;
}

//修改用户信息
void ChangeNameTableH(NameTableH* pn)
{
	assert(pn);

	char name[MAX_N] = { '\0' };
	printf("请输入需要修改的用户的姓名-->");
	scanf("%s", name);
	int i = FindNameTableH(pn,name);	//调用函数先来查找用户
	system("pause");					//程序暂停,按任意键继续
	if (i != -1)						//表示找到该用户
	{
		SleepCls();
		printf("请重新输入该用户的信息:\n");
		ChangeNode(pn->_NameArr[i]._NameInfo);//重新输入该用户的信息,选择性输入地址
	}
}

hashtele.h

#include "list.h"

//以用户的电话号码为关键字建立散列表
//取权值的公式  电话号码每个数字字符相加 对50取余
//处理冲突的方法 链地址法

#define MAX_TELEARR 50	 //链的最大高度

typedef struct HTTele	 //链地址法每个节点
{
	InfoNode* _TeleInfo; //用户信息
	struct HTTele* next; //逻辑上连接下一个同权值的节点
}HTTele;

typedef struct TeleListH
{
	HTTele* _TeleArr;	 //链的头
}TeleListH;

//初始化哈希链
void InitTeleListH(TeleListH* pt);

//建立哈希链
void SetTeleListH(TeleListH* pt, InfoNode_List* phead);

//电话号码查找用户
InfoNode* FindTeleListH(TeleListH* pt, const char* telephone);

//修改用户信息
void ChangeTeleListH(TeleListH* pt);

hashtele.c

#include "list.h"
#include "hashtele.h"

//初始化哈希链
void InitTeleListH(TeleListH* pt)
{
	assert(pt);

	pt->_TeleArr = (HTTele*)malloc(sizeof(HTTele)*MAX_TELEARR);	//开辟存储信息的空间
	int i = 0;
	for (i = 0; i < MAX_TELEARR; i++)
	{
		pt->_TeleArr[i].next = NULL;	//每一层的链头的next指针初始化为NULL
	}
}

//建立哈希链
void SetTeleListH(TeleListH* pt, InfoNode_List* phead)
{
	assert(pt && phead);

	if (phead==phead->_next)					//判断有没有用户信息可以查找
	{
		printf("没有用户的信息!\n");
		return;
	}
	InfoNode_List* node = phead->_next;
	int len = 0;
	while (node!=phead)
	{
		int key = 0;
		len = strlen(node->_ListInfo->_telephone);
		while (len)								//计算权值
		{
			key += (int)node->_ListInfo->_telephone[len - 1];
			key %=MAX_TELEARR;					//除留余数法  除数为链的高度
			len--;
		}

		//建立一个新的链节点
		HTTele* Newnode = (HTTele*)malloc(sizeof(HTTele));
		Newnode->_TeleInfo = node->_ListInfo;	 //用户信息的复制
		Newnode->next = NULL;

		if (!pt->_TeleArr[key].next)			//如果该位置的头没有地址
		{
			pt->_TeleArr[key].next = Newnode;
		}
		else
		{
			//在当前链的头进行插入
			Newnode->next=pt->_TeleArr[key].next;
			pt->_TeleArr[key].next = Newnode;
		}
		node = node->_next;
	}
	
	ProgressBar();	//模拟进度条
	printf("电话号码哈希链建立完毕\n");
	SleepCls();		//0.5秒睡眠+清屏
}

//电话号码查找用户
InfoNode* FindTeleListH(TeleListH* pt, const char* telephone)
{
	assert(pt);

	int key = 0;
	int len = strlen(telephone);
	while (len)				//计算权值
	{
		key += (int)telephone[len - 1];
		key %= MAX_TELEARR; //除留余数法  除数为链的高度
		len--;
	}

	if (!pt->_TeleArr[key].next)
	{
		printf("没有找到该用户\n");
		return NULL;
	}
	else
	{
		HTTele* Newnode = pt->_TeleArr[key].next;
		while (Newnode)
		{
			if (strcmp(Newnode->_TeleInfo->_telephone, telephone) == 0)
			{
				ShowOnce(Newnode->_TeleInfo);	//打印要查找的该用户信息
				return Newnode->_TeleInfo;		//函数返回该用户的信息节点
			}
			Newnode = Newnode->next;
		}
	}
	printf("没有找到该用户\n");
	return NULL;
}

//修改用户信息
void ChangeTeleListH(TeleListH* pt)
{
	assert(pt);

	printf("请输入要修改用户的电话号码-->");
	char tele[MAX_T];
	scanf("%s", tele);
	InfoNode* Newnode=FindTeleListH(pt, tele);
	system("pause");					//程序暂停,按任意键继续
	if (!Newnode)			//如果查找函数返回值为NULL,表示未找到,直接返回
	{
		return;
	}
	SleepCls();
	printf("请重新输入该用户的信息:\n");
	ChangeNode(Newnode);	//重新输入该用户的新的所有信息
}

text.c

#include "list.h"
#include"hashname.h"
#include "hashtele.h"

void menuFind()
{
	printf("-----------------------------------------\n");
	printf("|\t查找用户信息-->1\t\t|\n");
	printf("-----------------------------------------\n");
	printf("|\t修改用户信息-->2\t\t|\n");
	printf("-----------------------------------------\n");
	printf("您的选择-->");
}

void menu()
{
	system("color 3");
	printf("\t _______________________________________\n");
	printf("\t|\t散列表电话号码查询系统\t\t|\n");
	printf("\t|\t  1.增加用户信息\t\t|\n");
	printf("\t|\t  2.删除用户信息\t\t|\n");
	printf("\t|\t  3.用户名查找和修改用户信息    |\n");
	printf("\t|\t  4.电话号码查找和修改用户信息\t|\n");
	printf("\t|\t  5.用户信息载入文件\t\t|\n");
	printf("\t|\t  6.从文件中读取用户信息\t|\n");
	printf("\t|\t  7.对用户信息进行排序\t\t|\n");
	printf("\t|\t  8.打印所有用户信息\t\t|\n");
	printf("\t|\t  0.退出\t\t\t|\n");
	printf("\t|_______________________________________|\n\n");
}

int main()
{
	int input=1;
	int choose;
	InfoNode_List* head;		 //建立双向循环链表的头结点
	head = (InfoNode_List*)malloc(sizeof(InfoNode_List));
	InitList(head);				//初始化链表
	ReadFileInfo(head);			//读取文件信息  系统开始时自动读取文件中的信息
	printf("\n信息读取完毕,即将进入主页面\n");
	ProgressBar();				//模拟进度条载入
	SleepCls();					//0.5秒睡眠加清屏
	
	while (1)
	{
		menu();
		printf("请输入您的选择:--> ");
		scanf("%d", &choose);	//choose表示外部菜单的选项
		getchar();				//处理掉用户输入后的回车字符
		printf("\n即将执行您的选择");
		SleepCls();				//0.5秒睡眠加清屏
		switch (choose)
		{
		case 1:
		{
				 char isagain = 'y';
				 while (isagain == 'y' || isagain == 'Y')
				 {
					 printf("请输入需要增加的用户信息:\n");
					 printf("----------------------------------\n");
					 AddList(head);		 //增加用户信息
					 printf("是否继续输入用户信息(y或者Y)-->"); 
					 getchar();			//处理掉用户输入后的回车字符
					 scanf("%c", &isagain);
					 SleepCls();
				 }
				 break;
		}
		case 2:
			DeleteListNode(head);	//删除用户信息
			break;
		case 3:						//用户名查找和修改用户信息
		{
				  NameTableH* HTname;
				  HTname = (NameTableH*)malloc(sizeof(NameTableH));
				  InitNameTableH(HTname);		//初始化姓名散列表
				  SetNameTableH(HTname, head);	//建立散列表
				  menuFind();					//打印查找菜单
				  scanf("%d", &input);			//input 内部菜单的选项
				  switch (input)
				  {
					case 1:						//查找
					 {
						 printf("请输入要查寻用户的姓名:");
						 char name[MAX_N] = "\0";
						 scanf("%s", name);
						 FindNameTableH(HTname, name);//姓名查找函数
						 break; 
					 }  
				  case 2:						//修改
					  ChangeNameTableH(HTname);	//先查找再修改
					  break;
				  }
				  break;
		}	
		case 4:							//电话号码查找和修改用户信息
		{
				  TeleListH* HTTele;			//电话号码哈希表的结构体
				  HTTele = (TeleListH*)malloc(sizeof(TeleListH));
				  InitTeleListH(HTTele);		//初始化
				  SetTeleListH(HTTele, head);	//建立电话号码哈希表
				  menuFind();					//打印查找菜单
				  scanf("%d", &input);			//input 内部菜单的选项
				  switch (input)
				  {
				  case 1:						//查找
					  printf("请输入要查寻用户的电话号码:");
					  char telephone[MAX_T] = { '\0' };
					  scanf("%s", telephone);
					  FindTeleListH(HTTele, telephone);	//电话号码查找
					  break;
				  case 2:						//修改
					  ChangeTeleListH(HTTele);	//先查找再修改
					  break;
				  }
				  break;
		}
		case 5:
			WriteFileInfo(head);	//写入文件
			break;
		case 6:
			ReadFileInfo(head);		//读取文件信息
			break;
		case 7:
			InsertSort(head);		//插入排序
			break;
		case 8:
			ShowInfo(head);			//打印所有信息
			break;
		default:
			WriteFileInfo(head);	//写入文件  程序结束对输入的信息进行文件保护
			printf("\n感谢使用~\n");
			return 0;
		}
		if (choose != 1)
		{
			system("pause");
			SleepCls();
		}
	}
}

//void text1(InfoNode_List* phead)
//{
//	InitList(phead);	//初始化
//	ReadFileInfo(phead);
//	AddList(phead);   //增加用户信息
//	DeleteListNode(phead);	//删除用户信息
//	BubbleSort(phead);
//	WriteFileInfo(phead);
//	ShowInfo(phead);
//}
//
//void text2(InfoNode_List* phead)
//{
//	NameTableH* HTname;
//	HTname = (NameTableH*)malloc(sizeof(NameTableH));
//
//	InitNameTableH(HTname);//初始化姓名哈希表
//	SetNameTableH(HTname, phead);
//	char name[MAX_N] = "duchenlong";
//	FindNameTableH(HTname, name);
//	ChangeNameTableH(HTname);
//}
//
//void text3(InfoNode_List* phead)
//{
//	TeleListH* HTTele;
//	HTTele = (TeleListH*)malloc(sizeof(TeleListH));
//	InitTeleListH(HTTele);
//	SetTeleListH(HTTele,phead);
//	char telephone[MAX_T] = "13325430774";
//	FindTeleListH(HTTele,telephone);
//	ChangeTeleListH(HTTele);
//}
//int main()
//{
//	InfoNode_List* head;
//	head = (InfoNode_List*)malloc(sizeof(InfoNode_List));
//	text1(head);	//链表调试测试接口
//	//text2(head);	//姓名为关键字哈希表的测试接口
//	text3(head);
//	return 0;
//}

模拟进度条和加载

开始界面

 

  • 29
    点赞
  • 210
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值