文档库 最新最全的文档下载
当前位置:文档库 › 客房管理

客房管理

/*
《数据结构》实验题目
实验一 客房管理(链表)
l 实验目的:熟练掌握单循环链表操作的基本算法实现。
l 实现功能:以带表头结点的单链表为存储结构,实现如下客房管理的设计要求。
l 实验机时:8
l 设计要求:
(1)定义客房链表结点结构类型,以Hotel和*HLink命名,数据域:客房名称roomN、标准价格Price、入住价格PriceL(默认值=标准价格*80%)、床位数Beds、入住状态State(空闲、入住、预订,默认值为空闲),指针域:*next;
(2)实现创建客房基本情况链表函数void Build(HLink &H),输入客房名称、标准价格、床位数,将入住价格、入住状态修改为默认值,建议用文件操作来输入数据;
(3)实现函数void updateH(HLink &H, int beds, char *state),将床位数为beds的客房入住状态改为state;
(4)实现输出客房基本情况函数void Exp(HLink H),输出所有客房的客房名称、标准价格、入住价格、床位数、入住状态;
(5)函数void Add(HLink &H),将该链表中未入住的客房入住价格均加价20%;
(6)函数void upBed(HLink &H,int beds),将该链表床位数不超过beds的结点都放在床位数超过beds的结点后面;
(7)求出入住价格最高的客房函数HLink FirstH(HLink &H),该函数内return语句返回入住价格最高的客房结点指针,返回前将该结点在链表中删除;
(8) 函数void MoveK1(HLink &H, int k),将单链表中倒数第k个结点移到第一个结点位置,注意:严禁采用先计算链表长度n再减k(即n-k)的方法;
(9) 函数void ReverseN2(HLink &H),将单链表的正中间位置结点之后的全部结点倒置的功能,注意:严禁采用先计算链表长度n再除以2(即n/2)的方法;
(10)主控函数main()调用以上函数,输出(3)(beds=2,state="入住")、(5)、(6)、(7)、(8)、(9)处理后的链表内容、输出入住价格最高的客房基本情况。

可能用到的函数:
从文件中读取客房数据:fscanf(文件指针,"%s %f,%d",p->roomN,&p->Price,&p->Beds);
输出客房数据:printf("%s%8.1f%8.1f%6d%8s\n",p->roomN,p->Price,p->PriceL,p->Beds,p->State);
字符串赋值函数:char* strcpy(char *, const char *);
字符串比较函数:int strcmp(const char *, const char *)

#include
#include
#include

//定义客房链表结点结构
typedef struct HNode
{
char roomN[7]; //客房名称
float Price; //标准价格
float PriceL; //入住价格(默认值=标准价格*80%)
int Beds; //床位数Beds
char State[5]; //入住状态(值域:"空闲"、"入住"、"预订",默认值为"空闲"
struct HNode *next; //指针域
}Hotel, *HLink;
*/
//RoomData.txt文件内容
/*
101 200 160 1 入住
102 200 161 1 预定
103 200 162 2 空闲
104 200 16

3 1 空闲
105 200 164 1 入住
106 200 165 3 入住
107 200 166 1 预定
108 200 167 1 入住
201 200 168 4 入住
202 200 169 1 空闲
203 200 170 1 入住
204 200 171 4 入住
205 200 172 1 入住
206 200 173 1 入住
207 200 174 3 入住
208 200 175 1 入住
*/

#include
#include


//定义客房链表结点结构
typedef struct HNode
{
char roomN[7]; //客房名称
float Price; //标准价格
float PriceL; //入住价格(默认值=标准价格*80%)
int Beds; //床位数Beds
char State[5]; //入住状态(值域:"空闲"、"入住"、"预订",默认值为"空闲"
struct HNode *next; //指针域
}Hotel, *HLink;

FILE *stream;

/**
* @fun Build
*
* @brief 从文件中读取客房的数据,并建立链表
*
* @para [in] HLink &H 要创建链表的头结点
*
* @return void
*
* @date 2012/11/09
*/
void Build(HLink &H)
{
//定义缓冲变量,与客房结构体中的数据项对应
char roomN[7];//存储客房名称的临时数据
float Price;//存储标准价格的临时数据
float PriceL;//存储入住价格的临时数据
int Beds;//存储床位数Beds的临时数据
char State[5];//存储入住状态的临时数据

int NodeNumber = 0;//存储结点的个数,也就是房间的个数,本数据属于扩充部分,存储在头结点的床位中
HLink p, q;//定义两个链表指针


p = q = H;//为两个链表指针初始化

//打开文件,暂时是用固定的文件名,如果需要设计灵活的接口,本函数需要再增加一个文件指针的参数
stream = fopen( "RoomData.txt", "a+" );

if( stream == NULL )
printf( "The file RoomData.txt was not opened\n" );

//设置文件指针指向文件起始位置
fseek( stream, 0L, SEEK_SET );

//如果文件为空,输出提示并返回
if(fgetc(stream) == EOF)
{
printf("文件为空\n");
return ;
}
//设置文件指针指向文件起始位置
fseek( stream, 0L, SEEK_SET );
while(fscanf(stream, "%s %f %f %d %s", roomN, &Price, &PriceL, &Beds, State) != EOF)
{
NodeNumber++;//每创建一个结点,结点数就加1

//创建一个新结点,本出需要判断是否分配内存成功,增强程序的健壮性,有需要的请自己去扩充
p = (HLink)malloc(sizeof(Hotel));

strcpy(p->roomN, roomN);//为房间号赋值

p->Price = Price;//为房间标准价格赋值

if(PriceL == 0)//为入住价格赋值
{
p->PriceL = (float)(Price * 0.8);
}
else
{
p->PriceL = PriceL;
}

p->Beds = Beds;//为房间的床位数赋值

strcpy(p->State, State);//为房间的入住状态赋值

//将该条数据对应的结点加入到链表中
//将p临时结点加入链表尾
q->next = p;
p->next = NULL;
q = p; //q 永远指向量表尾
}
H->Beds = NodeNumber;
}


/**
* @fun UpdateH
*
* @brief 将床

位数为beds的房间的状态设置成state
*
* @para [in] H 链表头结点
beds 床位数
state 房间状态
*
* @return void
*
* @date 2012/11/09
*/

void UpdateH(HLink &H, int beds, char *state)
{
HLink p;

//如果链表为空,返回
if(H->next == NULL)
{
return ;
}
p = H->next;//指向第一个结点
while(p->next != NULL)
{
if(p->Beds == beds) //找到床位数符合条件的房间
{
strcpy(p->State, state);//设置房间状态
}
p = p->next;
}
}

/**
* @fun Exp
*
* @brief 输出所有客房的客房名称、标准价格、入住价格、床位数、入住状态;
*
* @para [in] H 链表头结点
*
* @return void
*
* @date 2012/11/09
*/
void Exp(HLink H)
{
HLink p;
//如果链表为空,返回
if(H->next == NULL)
{
printf("链表为空!");
return ;
}
printf("一共有%d个房间\n",H->Beds);
printf("%8s, %8s,%8s,%8s,%8s\n","roomN","Price","PriceL","Beds","State");

p = H->next;//指向第一个结点
while(p != NULL)
{
printf("%8s %.2f %.2f %6d %8s\n", p->roomN, p->Price, p->PriceL, p->Beds, p->State);
p = p->next;
}

}


/**
* @fun Add
*
* @brief 将该链表中未入住的客房入住价格均加价20%
*
* @para [in] H 链表头结点
*
* @return void
*
* @date 2012/11/09
*/
void Add(HLink &H)
{
HLink p;

//如果链表为空,返回
if(H->next == NULL)
{
return ;
}
p = H->next;//指向第一个结点
while(p != NULL)
{
if(0 != strcmp(p->State, "入住")) //找到非入住的房间
{
p->PriceL = (float)(p->PriceL * 1.2);
}
p = p->next;
}
}
/**
* @fun MoveK1
*
* @brief 将单链表中倒数第k个结点移到第一个结点位置,注意:严禁采用先计算链表长度n再减k(即n-k)的方法;
*
* @para [in] H 链表头结点
* k 第k个
* @return void
*
* @date 2012/11/09
*/
void MoveK1(HLink &H, int k)
{
HLink p, q;
int i;
//我们在建立链表的时候,已经记录了该链表的长度,现在拿出来用;如果链表总长度小于要倒数的数,这个种情况我们不去处理
if(H->Beds < k)
{
return;
}
p = q = H->next;//指向第一个结点
for(i = 0; i < k+1 ; i++)
{
q = q->next;
}//使两个指针之间的差为K+1
while(q != NULL)//找到倒数第K+1个结点,此时p指向要找的结点的前一个结点
{
p = p->next;
q = q->next;
}

//将该结点移动到第一个位置
//先将找到的结点从链表中取出
q = p->next;
p->next = q->next;//将断开的链表连接上
//将取出的结点插入到第一个结点前面
q->next = H->next;
H->next = q;
}

/**
* @fun upBed
*
* @brief 将该链表床位数不超过beds的结点都放在床位数超过beds的结点后面;
*
* @para [in] H 链表头结点
* beds 分界线
* @return void
*
* @date 2012/11/09
*/
void upBed(HLink &H, int beds)
{
//遍历这个

链表,将beds数小于给定参数beds的房间结点插入到链表尾部
HLink p, q, r;
p = q = H->next;
r = H;
int i = 0;
while(q->next != NULL)
{
q = q->next;
}//q指向链表尾

for(i = 0; i < H->Beds; i++)
{
if(p->Beds < beds) //如果小于给定参数,需要将其放在后面
{
r->next = p->next; //取出该结点
q->next = p;//放到尾部
p->next = NULL;
q = p; //保证q 指向尾结点
p = r->next;//
}
else
{
r = r->next;
p = p->next;
}
}

}

/**
* @fun FirstH
*
* @brief 该函数内return语句返回入住价格最高的客房结点指针,返回前将该结点在链表中删除;(如果有最高入住价格,只删除第一个找到的那个房间结点)
*
* @para [in] H 链表头结点
*
* @retval 入住价格最高的房客结点的指针(如果有最高入住价格)
*
* @date 2012/11/09
*/

HLink FirstH(HLink &H)
{
HLink p, q, r;
float maxPriceL;
//如果链表为空,返回
if(H->next == NULL)
{
return NULL;
}

p = H->next;//指向第一个结点
q = p->next;//q指向p的下一个结点
maxPriceL = p->PriceL;
while(q != NULL)
{
if(q->PriceL > maxPriceL) //如果比暂时的最大值大,更新最大值,并记录该结点的前一个结点
{
maxPriceL = q->PriceL;
r = p;
}
q = q->next;
p = p->next;
}

//删除该结点,并返回
p = r->next;
r->next = p->next;
H->Beds = H->Beds - 1;//此处注意更新链表中结点的数目
return p;
}


/**
* @fun ReverseN2
*
* @brief 将单链表的正中间位置结点之后的全部结点倒置的功能,注意:严禁采用先计算链表长度n再除以2(即n/2)的方法;
*
* @para [in] H 链表头结点
*
* @retval 入住价格最高的房客结点的指针(如果有最高入住价格)
*
* @date 2012/11/09
*/
void ReverseN2(HLink &H)
{
//正中间结点是在客房结点为奇数个的时候才会有
//如果客房的结点个数为偶数个的时候,将中间的两个结点中的第一个结点后的结点逆置
HLink p, q, r, h, midH;

//如果链表为空,返回
if(H->next == NULL)
{
return ;
}
if(H->Beds % 2 == 0)
{
p = q = H->next;

}
else
{
p = H->next;
q = p->next;
}

while(q != NULL)//
{
p = p->next;
q = q->next;
q = q->next;
}
// printf("%8s %.2f %.2f %6d %8s\n", p->roomN, p->Price, p->PriceL, p->Beds, p->State);

h = p->next;//要逆置的链表头

midH = p;//保存前半部分链表
//逆置算法,也是断开两个链表,然后将第三个结点插入到头结点
p=h;
q=p->next ;
while (q!=NULL)
{
r=q->next ;
q->next =p;
p=q;
q=r;
}
h->next =NULL;
h=p;
midH->next = p;//将逆置后半部分与前半部分连接到一起
}

void main(void)
{
//创建头结点
HLink headNode = (HLink)malloc(sizeof(Hotel));
HLink FirstPriceL = (HLink)malloc

(sizeof(Hotel));

//创建链表
printf("---------------------------Build------------------------------------\n");
Build(headNode);
//输出打印链表
Exp(headNode);
printf("---------------------------Build------------------------------------\n\n\n");


printf("---------------------------UpdateH------------------------------------\n");
//设置一张床的房间的入住状态为空闲
UpdateH(headNode, 2 ,"入住");
Exp(headNode);
printf("---------------------------UpdateH------------------------------------\n\n\n");


printf("---------------------------Add------------------------------------\n");
//加价
Add(headNode);
Exp(headNode);
printf("---------------------------Add------------------------------------\n\n\n");


printf("---------------------------MoveK1------------------------------------\n");
//移动倒数第四个结点
MoveK1(headNode, 4);
Exp(headNode);
printf("---------------------------MoveK1------------------------------------\n\n\n");


printf("---------------------------upBed------------------------------------\n");
//以两张床位分界线
upBed(headNode, 2);
Exp(headNode);
printf("---------------------------upBed------------------------------------\n\n\n");


printf("---------------------------FirstH------------------------------------\n");
//返回第一入住价格结点
FirstPriceL = FirstH(headNode);
printf("返回的第一入住价格结点的值:\n");
printf("%8s %.2f %.2f %6d %8s\n", FirstPriceL->roomN, FirstPriceL->Price, FirstPriceL->PriceL, FirstPriceL->Beds, FirstPriceL->State);
Exp(headNode);
printf("---------------------------FirstH------------------------------------\n\n\n");


printf("---------------------------ReverseN2------------------------------------\n");
//后半部分逆置
ReverseN2(headNode);
Exp(headNode);
printf("---------------------------ReverseN2------------------------------------\n\n\n");
}


相关文档