数据结构实验大作业

实验一 客房管理(链表实验)

  1. 实现功能:采用结构化程序设计思想,编程实现客房管理程序的各个功能函数,从而熟练掌握单链表的创建、输出、查找、修改、插入、删除、排序和复杂综合应用等操作的算法实现。以带表头结点的单链表为存储结构,实现如下客房管理的设计要求。
  2. 实验机时:8
  3. 设计要求:

 (1)实现创建客房信息链表函数void Build(HLink &H),输入(客房名称、标准价格、床位数),同时修改入住价格、入住状态为默认值,即入住价格=标准价格*80%,入住状态为”空闲”(提示:用strcpy()字符串拷贝函数)。为了提高程序调试效率,要求:用文件操作来输入客房信息(客房名称、标准价格、床位数);

(2)实现输出客房信息函数void Exp(HLink H),输出所有客房的客房名称、标准价格、入住价格、床位数、入住状态;

(3)函数int Find(HLink &H, char *roomN),查找房间名称为roomN的客房。如果找到,则返回该客房在链表中的位置序号(>=1),否则返回0。提示:用strcmp()字符串比较函数;

(4)实现函数void updateH(HLink &H, int beds, char *state),将床位数为beds的客房入住状态改为state。提示:用strcpy()字符串拷贝函数;

(5)函数void Add(HLink &H),将该链表中未入住的客房入住价格均加价20%;

(6)求出入住价格最高的客房函数HLink FirstH(HLink &H),该函数内return语句返回入住价格最高的客房结点指针,返回前将该结点在链表中删除;

(7)函数void MoveK1(HLink &H, int k),将单链表中倒数第k个结点之后的所有结点移到头结点后面,注意:严禁采用先计算链表长度n再减k(即n-k)的方法;

(8)函数void ReverseN2(HLink &H),将单链表的正中间位置结点之后的全部结点倒置的功能,注意:严禁采用先计算链表长度n再除以2(即n/2)的方法;

(9)函数void SortPriceL(HLink &H),按照客房(入住价格,客房名称)升序排序;

(10)函数void upBed(HLink &H,int beds),创建一个【床位数为beds的新结点】(还需输入:客房名称、标准价格等信息),使链表的形态为:【头结点】->【床位数>beds的结点】->【床位数为beds的新结点】->【床位数<=beds的结点】,要求【超过beds的结点】和【不超过beds的结点】这两段链表中的结点保持原来的前后相对顺序;

(11)实现函数void Merge(HLink &H1, HLink &H2),将两个按入住价格非递减排序的客房记录单合并为一个按入住价格非递增排序的客房记录单;要求算法的时间复杂度不超过两个链表的长度之和O(m+n);

(12)主函数main()调用以上函数,(3)若返回值>=1则输出该客房在链表中的位置序号,否则输出该客房不存在;输出(4)~(10)处理后的链表内容,其中(6)还要输出入住价格最高的客房信息。

 

可能用到的函数:

从文件中读取客房数据: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<stdio.h>

#include<stdlib.h>

#include<string.h>

//定义客房链表结点结构

typedef struct HNode

    {

        char    roomN[7];   //客房名称

        float   Price;      //标准价格

        float   PriceL; //入住价格(默认值=标准价格*80%)

        int    Beds;        //床位数Beds

        char       State[5];    //入住状态(值域:"空闲"、"入住"、"预订",默认值为"空闲")

        struct HNode  *next;    //指针域

    }Hotel, *HLink;

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

typedef struct HNode{
	char roomN[7];//客房名称 
	float Price;//标准价格 
	float Pricel;//入住价格(默认值=标准价格*0.8) 
	int Beds;//床位数 
	char State[5];//入住状态(值域:空闲,入住,预定,默认值为空闲) 
	struct HNode *next;//指针域 
}Hotel,*HLink;

//正序创建一个链表 
void Build(HLink &H)
{
	HLink rear;
	HLink p;
	const char *indata = "studata.txt";//数据输入,文件路径
	FILE*inflie;
	inflie = fopen(indata,"r");
	if(!inflie){
		printf("文件没有找到捏嘻嘻\n");
		exit(1); 
	}
	H = (HLink)malloc(sizeof(HNode));
	rear = H;
	while(!feof(inflie))
	{
	p = (HLink)malloc(sizeof(HNode));
	fscanf(inflie,"%s%f%d",&p->roomN,&p->Price,&p->Beds);
    p->Pricel=(float)0.8*p->Price;
    strcpy(p->State,"空闲");
	rear->next=p;
	rear = p;
	}
	rear->next=NULL;
	fclose(inflie);
}

//创建另外的单子1
void Build1(HLink &H)
{
	HLink rear;
	HLink p;
	const char *indata = "studata1.txt";//数据输入,文件路径
	FILE*inflie;
	inflie = fopen(indata,"r");
	if(!inflie){
		printf("文件没有找到捏嘻嘻\n");
		exit(1); 
	}
	H = (HLink)malloc(sizeof(HNode));
	rear = H;
	while(!feof(inflie))
	{
	p = (HLink)malloc(sizeof(HNode));
	fscanf(inflie,"%s%f%d",&p->roomN,&p->Price,&p->Beds);
    p->Pricel=(float)0.8*p->Price;
    strcpy(p->State,"空闲");
	rear->next=p;
	rear = p;
	}
	rear->next=NULL;
	fclose(inflie);
}

//创建另外的单子2
void Build2(HLink &H)
{
	HLink rear;
	HLink p;
	const char *indata = "studata2.txt";//数据输入,文件路径
	FILE*inflie;
	inflie = fopen(indata,"r");
	if(!inflie){
		printf("文件没有找到捏嘻嘻\n");
		exit(1); 
	}
	H = (HLink)malloc(sizeof(HNode));
	rear = H;
	while(!feof(inflie))
	{
	p = (HLink)malloc(sizeof(HNode));
	fscanf(inflie,"%s%f%d",&p->roomN,&p->Price,&p->Beds);
    p->Pricel=(float)0.8*p->Price;
    strcpy(p->State,"空闲");
	rear->next=p;
	rear = p;
	}
	rear->next=NULL;
	fclose(inflie);
}

//创建结点
void Build3(HLink &F)
{
	HLink rear;
	HLink p;
	const char *indata = "studata3.txt";//数据输入,文件路径
	FILE*inflie;
	inflie = fopen(indata,"r");
	if(!inflie){
		printf("文件没有找到捏嘻嘻\n");
		exit(1); 
	}
	F = (HLink)malloc(sizeof(HNode));
	rear = F;
	while(!feof(inflie))
	{
	p = (HLink)malloc(sizeof(HNode));
	fscanf(inflie,"%s%f%d",&p->roomN,&p->Price,&p->Beds);
    p->Pricel=(float)0.8*p->Price;
    strcpy(p->State,"空闲");
	rear->next=p;
	rear = p;
	}
	rear->next=NULL;
	fclose(inflie);
}

//将床位数为beds客房入住状态改为state
void updateH(HLink &H,int beds,char state[]){
	HLink p;
	p=H->next;
	while(p)
	{
		if(p->Beds==beds)
		strcpy(p->State,"入住");//为state
		p = p->next;
	}
} 

//查找房间名称为roomN的客房,返回次序
int Find(HLink &H, char roomN[]){
    HLink p = H->next;
    int count = 1;
    int a = 0;
    while (p != NULL){
    if(strcmp(p->roomN,roomN) == 0){
        printf("次序是%d",count);
        a = 1;
    }
    p = p->next;
    count ++;
    }
    if (a == 0)
    printf("%d",a);
    return 0;
}

//升序排序(很好的模板)
void sort(HLink &H){
    HNode *p=H->next,*pre;
    HNode *r=p->next;
    p->next=NULL;
    p=r;
    while(p!=NULL){
        r=p->next;
        pre=H;
        while(pre->next!=NULL&&pre->next->Pricel<p->Pricel){
            pre=pre->next;
        }
        p->next=pre->next;
        pre->next=p;
        p=r;
    }
}

//输出所有客房的房客名称、标准价格
void Exp(HLink H)
{
	HLink p;
	p=H->next;
	if(!p)
	{
		printf("没有数据捏\n");
		return ;
	}
	printf("\n******************客房信息输出如下****************\n");
	printf("----------------------------------\n");
	printf("客房名称 标准价格 入住价格 床位数 入住状态\n");
	printf("----------------------------------\n");
	while(p){
		printf("%s %8.1f %8.1f %6d %8s\n",p->roomN,p->Price,p->Pricel,p->Beds,p->State);
		p=p->next;
	}
	printf("/n");
 } 
 
 //将该链表中未入住的价格加价0.2
 void Add(HLink &H){
    HLink p;
    p = H->next;
    while(p){
        if(!strcmp(p->State,"空闲"))
        p->Pricel = (float)1.2*p->Pricel;
        p = p->next;
    }
 }

 //求出入住价格最高的客房函数,返回入住价格最高的客房价格指针,返回前将该结点在链表中删除
HLink FirstH(HLink &H){
    HLink p,q,r=H;
    p = H->next;
    q = H->next;
    float priceMax = 0.0;
    while(p){
        if(p->Pricel>priceMax){
            priceMax = p->Pricel;
            //q = q->next;
            //r = r->next;
        }
        p = p->next;
    }
    while(q->Pricel!=priceMax){
        q = q->next;
        r = r->next;
    }
    r->next = q->next;
    return q;
}

//将单链表中倒数第k个结点移到第一个结点位置
void MoveK1(HLink &H,int k){
    HLink p,q,r,f;
    p = H->next;
    q = H->next;
    r = H;
    f = r->next;
    for(int i =0;i<k&&p != NULL;i++){
        p = p->next;
    }
    if(p!=NULL){
    while(p){
        p = p->next;
        q = q->next;
        r = r->next;
    }
    r->next = q->next;
    H->next = q;
    q->next = f;
    }
    else
    printf("错误");
}

//将单链表的正中间位置结点之后的全部结点倒置的功能
void ReverseN2(HLink &H){
    HLink p = H,q= H,h;
    while(p){
        if(p->next)
        p = p->next->next;
        else
        {
            p = p->next;
            break;
        }
        q = q->next;
    }
    p = q->next;
    q->next = NULL;
    while(p){
        h = p->next;
        p->next = q->next;
        q->next = p;
        p = h;
    }
}

//两个单子的归并
void Merge(HLink &H1, HLink &H2)
{
    HNode *p1 = H1->next;
    H1->next = NULL;            //选择L1作为结果链表的头指针,先将结果链表初始化为空
    HNode *p2 = H2->next;
    HNode *temp;                //用于临时存储后继结点
    while(p1!=NULL && p2!=NULL)
    {
        //用头插法将较小的结点插入L1
        if(p1->Pricel < p2->Pricel)
        {
            temp= p1->next;
            p1->next = H1->next;
            H1->next = p1;
            p1 = temp;
        }
        else
        {
            temp = p2->next;
            p2->next = H1->next;
            H1->next = p2;
            p2 = temp;
        }
    }

    if(p1!=NULL)  //结束上面操作之后,一般来说,L1和L2会剩下一个链表不为空
        p2 = p1;

    while(p2!=NULL)
    {
        temp = p2->next;
        p2->next = H1->next;
        H1->next = p2;
        p2 = temp;
    }
    free(H2);
}

//按要求进行排序输出
void upBed(HLink &H,int Beds)
{
	HLink p,r,t,pret;
	p=new HNode;//??????
	p->next=NULL;
	printf("输入节点信息:房间名称,标准价格\n");
	scanf("%s %f",p->roomN,&p->Price);
	p->Beds=Beds;
	p->Pricel=float(0.8)*p->Price;
	strcpy(p->State,"空闲");
	t=H->next;
	pret=H;
	r=p;
	while(t)
	{
		if(t->Beds<=p->Beds)
		{
			pret->next=t->next;
			r->next=t;
			t->next=NULL;
			r=t;
			t=pret->next;
		}
		else
		{
			pret=pret->next;
			t=t->next;
		}
	}
	pret->next=p;
	Exp(H);
}


//主函数
int main()
{
    HLink L,h,L1,L2;
    int id,k,Beds;
    int beds_num;
    char beds_state[5];
    char roomname[7];
    while(1){
        printf("\n******************欢迎进入客房信息管理系统****************\n");
        printf("\n\n请查看相关功能,并[!!!按照顺序!!!]输入相关功能编号,谢谢!\n");
        printf("***************************************\n");
        printf("|1-查看所有客房信息|\n");
        printf("|2-查找客房|\n");
        printf("|3-更改客房入住状态|\n");
        printf("|4-所有未入住客房加价20%%|\n");
        printf("|5-查找入住价格最高的客房并清空该信息,然后输入更新后信息|\n");
        printf("|6-将倒数第k个客房排在首行|\n");
        printf("|7-正中间位置结点之后的全部结点倒置后的客房信息|\n");
        printf("|8-入住价格升序排序|\n");
        printf("|9-创建新节点,按要求输出|\n");
        printf("|10-归并两个单子|\n");
        printf("||\n");
        printf("|!其他退出|\n");
        printf("****************************************\n");
        printf("请选择:");
        scanf("%d",&id);
        if((id<1)||(id>12))
        break;
        switch (id){
            case 1:
            Build(L);
            Exp(L);
            break;

            case 2:
            printf("\n查找房间号\n\n");
            printf("\n输入你要查找的房间号\n\n");
            scanf("%s",roomname);
            Find(L,roomname);
            break;

            case 3:
            printf("\n更改客房入住状态\n\n");
            printf("输入需要更改的床位数:");
            scanf("%d",&beds_num);
            printf("\n输入要更改的客房状态(空闲、入住、预定):");
            scanf("%s",beds_state);
            updateH(L,beds_num,beds_state);
            printf("输入更改后的客房信息\n");
            Exp(L);
            break;

            case 4:
            printf("\n!将该链表中未入住的客房入住价格均加价20%%");
            Add(L);
            printf("输入加价后的客房信息:\n");
            Exp(L);
            break;

            
            case 5:
            h = FirstH(L);
            printf("\n输出入住客房价格最高的客房信息,并删除该结点\n\n");
            printf("-----------------------------\n");
            printf("客房名称 标准价格 入住价格 床位数 入住状态 \n");
            printf("-----------------------------\n");
            printf("%s %8.1f %8.1f %6d %8s\n",h->roomN,h->Price,h->Pricel,h->Beds,h->State);
            printf("-----------------------------\n\n");
            printf("\n\n输出删除后的客房信息\n");
            Exp(L);
            break;

            case 6:
            printf("输入K值(1<k<13):");
            scanf("%d",&k);
            MoveK1(L,k);
            Exp(L);
            break;

            case 7:
            printf("输出正中间位置结点之后的全部节点倒置后的客房信息\n");
            ReverseN2(L);
            Exp(L);
            break;

            case 8:
            printf("开始按照入住价格排序");
            sort(L);
            Exp(L);
            break;

            case 9:
            printf("创建新结点,按要求输出");
            HLink haha;
            Build3(haha);
            upBed(L,2);
            break;

            case 10:
            printf("两个客房记录单的归并");
            Build1(L1);
            Build2(L2);
            printf("归并前");
            Exp(L1);
            Exp(L2);
            Merge(L1,L2);
            printf("归并后");
            Exp(L1);
            break;

            default:
            printf("!你的输入有误!\n\n");
            break;
        }
    }
return 0;
}

实验二 串模式匹配算法(串实验)

  1. 实现功能: 从主串中第K个字符起,求出子串在主串中首次出现的位置,即模式匹配或串匹配。要求用三种模式匹配算法分别实现:
    1. 朴素的模式匹配算法(BF算法)
    2. KMP改进算法(Next[ ])
    3. KMP改进算法(NextVal[ ])
  2. 实验机时:8
  3. 设计要求:

首先设计一个含有多个菜单项的主控菜单程序,然后再为这些菜单项配上相应的功能。

程序运行后,给出5个菜单项的内容和输入提示:

1.输入主串、子串和匹配起始位置

2.朴素的模式匹配算法

3.KMP改进算法(Next[ ])

4.KMP改进算法(NextVal[ ])

0.退出管理系统

请选择0—4:

菜单设计要求:使用数字0—4来选择菜单项,其它输入则不起作用。

输出结果要求:输出各趟匹配详细过程(其中3、4,首先输出Next[ ]或者NextVal[ ]的各元素的数值),然后输出匹配总趟数、单个字符比较次数、匹配成功时的位置序号或者匹配失败提示信息。

//
// Created by David on 2023/11/13.
//
#include<iostream>
using namespace std;
#define MAXLEN 255
typedef char SString[MAXLEN + 1];


//建立主串、子串
void Getstring(SString &S,SString& T)
{
    SString s, t;
    int i = 0, j = 0;
    cout << "请输入主串S:";
    cin >> s;
    cout << "请输入子串T:";
    cin >> t;
    while (s[i])
    {
        S[0] = i + 1;
        S[i + 1] = s[i];
        i++;
    }
    while (t[j])
    {
        T[0] = j + 1;
        T[j + 1] = t[j];
        j++;
    }
}


//朴素的模式匹配法,BF算法
void BF(SString S, SString T, int pos)
{
    int i = pos, j = 1, t = 1;
    int num[MAXLEN];
    for (int k = 0; k < T[0]; k++)
        num[k] = 0;
    cout << "第1 次匹配:";
    for (int l = 1; l <= S[0]; l++)
        cout << S[l];
    cout << "\n";
    for (int m = 0; m < i+10; m++)
        cout << " ";
    cout << T[1];
    while (i <= S[0] && j <= T[0])
    {
        num[j - 1] = num[j - 1] + 1;
        if (S[i] == T[j])
        {
            i++;
            j++;
            cout << T[j];
        }
        else
        {
            t++;
            i = i - j + 2;
            j = 1;
            cout << "\n";
            if (t < 10)
                cout << "第" << t << " 次匹配:";
            else
                cout << "第" << t << "次匹配:";
            for (int k = 1; k <= S[0]; k++)
                cout << S[k];
            cout << "\n";
            for (int n = 0; n < i + 10; n++)
                cout << " ";
            cout << T[1];
        }
    }
    if (j > T[0])
    {
        cout << "\n匹配成功,匹配点为:" << (t + pos - 1) << "\n";
        for (int k = 1; k <= T[0]; k++)
        {
            cout << T[k] << "匹配次数:" << num[k - 1] << "\n";
        }
        cout << "\n";
    }
    else
        cout << "\n匹配失败!!!\n";
}

//正常计算的next
void get_next(SString T, int next[])
{
    int i = 1, j = 0;
    next[0] = T[0];
    next[1] = 0;
    while (i < T[0])
    {
        if (j == 0 || T[i] == T[j])
        {
            i++;
            j++;
            next[i] = j;
        }
        else
            j = next[j];
    }
}

//利用模式串T的next函数求T在主串S中第pos字符之后的位置的KMP算法
void KMP(SString S, SString T, int pos, int next[])
{
    int t = 1;
    int num[MAXLEN];//每个字符匹配次数
    num[0] = T[0];
    for (int i = 1; i <= T[0]; i++)
        num[i] = 0;
    cout << "第1 次匹配:";
    for (int o = 1; o <= S[0]; o++)
        cout << S[o];
    cout << "\n";
    for (int p = 1; p <= pos + 10; p++)
        cout << " ";
    cout << T[1];
    num[1]++;
    int k = pos, j = 1;
    while (k <= S[0] && j <= T[0])
    {
        if ( S[k] == T[j])
        {
            k++;
            j++;
            if (j <= T[0])
            {
                cout << T[j];
                num[j]++;
            }
        }
        else
        {
            cout << "\n";
            t++;
            if(t<10)
                cout << "第" << t << " 次匹配:";
            else
                cout << "第" << t << "次匹配:";
            for (int i = 1; i <= S[0]; i++)
                cout << S[i];
            cout << "\n";
            j = next[j];


            if (j != 0)
            {
                for (int i = 1; i <= k + 10; i++)
                    cout << " ";
                cout << T[j];
                num[j]++;
            }
            if (j == 0)
            {
                k++;
                j++;
                for (int i = 1; i <= k + 10; i++)
                    cout << " ";
                cout << T[j];
                num[j]++;
            }

        }

    }
    if (j > T[0])
    {
        cout << "\n匹配成功,匹配点为:" << k - T[0];
        for (int k = 1; k <= T[0]; k++)
            cout <<"\n"<< T[k] << "匹配次数:" << num[k];
        cout << "\n";
    }
    else
        cout << "\n匹配失败!!!\n";

}

//利用模式串T的next函数修正值求T在主串S中第pos字符之后的位置的高效KMP算法
void get_nextval(SString T, int nextval[])
{
    int i = 1, j = 0;
    nextval[0] = T[0];
    nextval[1] = 0;
    while (i < T[0])
    {
        if (j == 0 || T[i] == T[j])
        {
            i++;
            j++;
            if (T[i] != T[j])
                nextval[i] = j;
            else
                nextval[i] = nextval[j];
        }
        else
            j = nextval[j];
    }
}

//主函数
int main()
{
    int id, pos,k;
    int m,n,u;
    SString S, T;
    int next[MAXLEN];
    int nextval[MAXLEN];
    while (1)
    {
        cout << "------------字符串匹配------------";
        cout << "\n1.输入主串、子串、匹配起始位置";
        cout << "\n2.朴素的模式匹配算法";
        cout << "\n3.KMP算法";
        cout << "\n4.KMP改进算法";
        cout << "\n0.退出管理系统";
        cout << "\n----------------------------------";
        cout << "\n请输入功能序号:";
        cin >> id;
        switch (id) {
            case 0:
                exit(0);
            case 1:
                Getstring(S, T);
            Lab:
                cout << "请输入匹配的起始位置:";
                cin >> k;
                pos = k-1;
                if (pos > S[0])
                {
                    cout << "起始位置超出主串长度!!\n";
                    goto Lab;
                }
                break;
            case 2:
                BF(S, T, pos);
                break;
            case 3:
                get_next(T, next);
                cout << "S   串:";
                for (m=1; m <= S[0]; m++)
                    cout << S[m]<<" ";
                cout << "\n";
                cout << "T   串:";
                for (n=1; n <= T[0]; n++)
                    cout << T[n]<<" ";
                cout << "\n";
                cout<<"next[]:";
                for (u=1; u <= T[0]; u++)
                    cout << next[u]<<" ";
                cout << "\n";
                KMP(S, T, pos, next);
                break;
            case 4:
                get_nextval(T, nextval);
                cout << "S      串:";
                for (m=1; m <= S[0]; m++)
                    cout << S[m]<<" ";
                cout << "\n";
                cout << "T      串:";
                for (n=1; n <= T[0]; n++)
                    cout << T[n]<<" ";
                cout << "\n";
                cout<<"nextval[]:";
                for (u=1; u <= T[0]; u++)
                    cout << nextval[u]<<" ";
                cout << "\n";
                KMP(S, T, pos, nextval);
                break;
            default:
                cout << "请输入正确的功能编号!!\n";
        }

    }
    return 0;
}

实验三 二叉树遍历与路径查找(二叉树实验)

  1. 实现功能:建立二叉树存储结构、求二叉树的先序遍历、求二叉树的中序遍历、求二叉树的后序遍历、求二叉树的层次遍历、求根到给定结点的路径。
  2. 实验机时:8
  3. 设计要求:

数据结构:

typedef struct  node{

    char data;  //数据域

    struct node *lchild ,  *rchild;  //左右孩子指针

}BinTNode, *BinTree;   //树中结点类型

 

首先设计一个含有多个菜单项的主控菜单程序,然后再为这些菜单项配上相应的功能。

程序运行后,给出如下菜单项的内容和输入提示,使用数字0—6来选择菜单项,其它输入则不起作用:

1.建立二叉树存储结构

2.求二叉树的先序遍历

3.求二叉树的中序遍历

4.求二叉树的后序遍历

5.求二叉树的层次遍历

6.求给定结点的路径

7. 求树的深度

0.退出系统

请选择0—7:

//
// Created by David on 2023/11/13.
//
#include <iostream>
#include <stdlib.h>
#define MAXSIZE 255
using namespace std;

typedef struct node
{
    char data;
    struct node* lchild, * rchild;
}BinTNode,*BinTree;
BinTree H;

//先序遍历的顺序建立二叉树
void Create(BinTree& T)
{
    char ch;
    cin >> ch;
    if (ch == '#')
        T = NULL;
    else
    {
        T = new BinTNode;
        T->data = ch;
        Create(T->lchild);
        Create(T->rchild);
    }
}

//先序遍历
void PreOrderTraverse(BinTree T)
{
    if (T)
    {
        cout << T->data;
        PreOrderTraverse(T->lchild);
        PreOrderTraverse(T->rchild);
    }
}

//中序遍历
void InOrderTraverse(BinTree T)
{
    if (T)
    {
        InOrderTraverse(T->lchild);
        cout << T->data;
        InOrderTraverse(T->rchild);
    }
}

//后序遍历
void PostOrderTraverse(BinTree T)
{
    if (T)
    {
        PostOrderTraverse(T->lchild);
        PostOrderTraverse(T->rchild);
        cout << T->data;
    }
}

//定义链队
typedef struct QNode
{
    BinTree data;
    struct QNode* next;
}QNode,*QueuePtr;
typedef struct
{
    QueuePtr front;
    QueuePtr rear;
}LinkQueue;
LinkQueue Queue;

//链队初始化
void InitQueue(LinkQueue &Q)
{
    Q.front = Q.rear = new QNode;
    Q.front->next = NULL;
}

//入队
void EnQueue(LinkQueue &Q,BinTree e)
{
    QueuePtr q;
    q = new QNode;
    q->data=e;
    q->next = NULL;
    Q.rear->next = q;
    Q.rear = q;
}

//出队
BinTree DeQueue(LinkQueue& Q)
{
    BinTree e;
    QueuePtr p;
    if (Q.front == Q.rear)
        return NULL;
    p = Q.front->next;
    e = p->data;
    Q.front->next = p->next;
    if (Q.rear == p)
        Q.rear = Q.front;
    delete p;
    return e;
}

//层次遍历
void LevelOrderTraverse(BinTree T)
{
    BinTree r;
    InitQueue(Queue);
    EnQueue(Queue,T);
    r=DeQueue(Queue);
    while (r!=NULL)
    {
        cout << r->data;
        if (r->lchild)
        {
            EnQueue(Queue, r->lchild);
        }
        if (r->rchild)
        {
            EnQueue(Queue, r->rchild);
        }
        r = DeQueue(Queue);
    }
}

//结点路径
typedef struct
{
    char *base;
    char *top;
    int stacksize;
}SqStack;

//*初始化栈
typedef struct
{
    node* bt;
    int isFirst;
}SElemType;

typedef struct
{
    SElemType leaf[MAXSIZE];
    int top;
} Stack;

void initStack(Stack &s)
{
    s.top=0;
}

void push(Stack &s,SElemType n)
{
    s.leaf[s.top]=n;
    s.top++;
}

SElemType pop(Stack &s) //出栈并返回栈顶元素
{
    SElemType x=s.leaf[s.top-1];
    s.top--;
    return x;
}
int isEmpty(Stack s)
{
    if(s.top==0) return 1;  //空
    return 0;   //非空
}

Stack getPath(BinTree t,int x)
{
    Stack s;
    initStack(s);
    SElemType elem;
    while(t||!isEmpty(s))
    {
        //所有左孩子入栈
        while(t)
        {
            elem.isFirst=1;    //第一次访问
            elem.bt=t;
            push(s,elem);
            if(t->data==x) return s;    //找到指定结点,返回。
            t=t->lchild;
        }
        if(!isEmpty(s))
        {
            elem=pop(s);
            t=elem.bt->rchild;
            //如果第一次访问该节点(即还有右子树没有查找),出栈后取其右孩子后,更改访问状态再放回
            if(elem.isFirst==1)
            {
                elem.isFirst=0;
                push(s,elem);
            }
        }
    }
    return s;
}

int Depth1(BinTree T)
{
    int m, n;
    if (T == NULL)
        return 0; //如果是空树,深度为0,递归结束
    else
    {
        m = Depth1(T->lchild); //递归计算左子树的深度记为m
        n = Depth1(T->rchild); //递归计算右子树的深度记为n
        if (m > n)
            return (m + 1); //二叉树的深度为m 与n的较大者加1
        else
            return (n + 1);
    }
}

int main()
{
    Stack sta;
    int id;
    char ch;char a;
    char FA[MAXSIZE];
    a = 'e';
    int i=0,j=0;
    while(1)
    {
        cout << "---------二叉树---------";
        cout << "\n1.建立二叉树存储结构";
        cout << "\n2.求二叉树的先序遍历";
        cout << "\n3.求二叉树的中序遍历";
        cout << "\n4.求二叉树的后序遍历";
        cout << "\n5.求二叉树的层次遍历";
        cout << "\n6.求给定结点的路径";
        cout << "\n7.求树的深度";
        cout << "\n0.退出系统";
        cout << "\n------------------------";
        cout << "\n请输入功能编号:";
        cin >> id;
        switch (id)
        {
            case 1:
                cout << "请输入结点值:";
                Create(H);
                cout << "创建成功!!\n";
                break;
            case 2:
                cout << "先序遍历:";
                PreOrderTraverse(H);
                cout << "\n";
                break;
            case 3:
                cout << "中序遍历:";
                InOrderTraverse(H);
                cout << "\n";
                break;
            case 4:
                cout << "后序遍历:";
                PostOrderTraverse(H);
                cout<<"\n";
                break;
            case 5:
                cout << "层次遍历:";
                LevelOrderTraverse(H);
                cout << "\n";
                break;
            case 6:
                cout << "请输入待查询结点值:";
                cin >> ch;
                a = ch;
                sta = getPath(H,a);
                if(isEmpty(sta))
                    cout<<"该节点不存在!!\n";
                else
                {
                    while(!isEmpty(sta))
                    {
                        FA[i]=pop(sta).bt->data;
                        i++;
                    }
                    for(j=i-1;j>=0;j--)
                    {
                        cout<<FA[j];
                        if(j!=0)
                            cout<<" -> ";
                    }
                    cout<<"\n";
                    i=0;
                }
                break;
            case 7:
                cout << "数的深度为:" << Depth1(H) << endl;
            case 0:
                exit(0);
                break;
            default:
                cout << "请输入正确的功能编号!!!\n\n";
        }
    }

    return 0;
}

 

 

  • 20
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实验一 客房管理(链表应用实验) 定义客房链表结点结构HLink (1)实现创建客房信息链表函数void Build(HLink &H),输入(客房名称、标准价格、床位数),同时修改入住价格、入住状态为默认值,即入住价格=标准价格*80%,入住状态为”空闲”(提示:用strcpy()字符串拷贝函数)。为了提高程序调试效率,强烈建议:用文件操作来输入客房信息(客房名称、标准价格、床位数); (2)实现输出客房信息函数void Exp(HLink H),输出所有客房客房名称、标准价格、入住价格、床位数、入住状态; (3)函数int Find(HLink &H, char *roomN)),查找房间名称为roomN的客房。 (4)实现函数void updateH(HLink &H, int beds, char *state),将床位数为beds的客房入住状态改为state。 (5)函数void Add(HLink &H),将该链表中未入住的客房入住价格均加价20%; (6)求出入住价格最高的客房函数HLink FirstH(HLink &H),该函数内return语句返回入住价格最高的客房结点指针,返回前将该结点在链表中删除; (7)函数void MoveK1(HLink &H, int k),将单链表中倒数第k个结点移到第一个结点位置,注意:严禁采用先计算链表长度n再减k(即n-k)的方法; (8)函数void ReverseN2(HLink &H),将单链表的正中间位置结点之后的全部结点倒置的功能,注意:严禁采用先计算链表长度n再除以2(即n/2)的方法; (9)函数void SortPriceL(HLink &H),按照客房(入住价格,客房名称)升序排序; (10)函数void upBed(HLink &H,int beds),创建一个【床位数为beds的新结点】(还需输入:客房名称、标准价格等信息),使链表的形态为:【头结点】->【床位数>beds的结点】->【床位数为beds的新结点】->【床位数=1则输出该客房在链表中的位置序号,否则输出该客房不存在;输出(4)~(10)处理后的链表内容,(6)还要输出入住价格最高的客房信息。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值