数据结构实验

在这里插入图片描述

实验一:多项式

实验一(必做, 基本实验,4学时)
https://blog.csdn.net/weixin_43824597/article/details/104986419
https://blog.csdn.net/weixin_43824597/article/details/104986419
实验题目:多项式乘法问题
实验目的:设计一个一元稀疏多项式简单计算器。
实验内容与要求
一元稀疏多项式简单计算器的基本功能是:
(1)输入并建立多项式;
(2)输出多项式,输出形式为整数序列:n,c1,e1,c2,e2,…,cn,en,其中n是多项式的项数,ci和ei分别是第i项的系数和指数,序列按指数降序排列。
(3)多项式a与多项式b相乘,建立多项式。

  • mooc
    https://www.cnblogs.com/nickchen121/p/11457287.html#%E5%9B%9B%E3%80%81%E7%A8%8B%E5%BA%8F%E6%A1%86%E6%9E%B6%E6%90%AD%E5%BB%BA

解题思路

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述??
2
在这里插入图片描述
注意在这里插入图片描述
指针的指针,因为值传递
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

代码实现

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>


typedef struct PolyNode* Polynomial;
struct PolyNode
{
	int coef;//系数
	int expon;//指数
	Polynomial link;
};

void Attach(int c, int e, Polynomial* pRear)
{
	Polynomial P;
	P = (Polynomial)malloc(sizeof(struct PolyNode));
	P->coef = c;
	P->expon = e;
	P->link = NULL;
	(*pRear)->link = P;
	(*pRear) = P;
}
Polynomial ReadPoly()
{
	Polynomial P, Rear, t;
	int c, e, N;
	scanf("%d", &N);
	P = (Polynomial)malloc(sizeof(struct PolyNode));
	P->link = NULL;
	Rear = P;
	while (N--)
	{
		scanf("%d %d", &c, &e);
		Attach(c, e, &Rear);
	}
	t = P;
	P = P->link;
	free(t);
	return P;// 删除临时生成的头结点
}

void PrintPoly(Polynomial P)
{
	int flag = 0;  // 辅助调整输出格式用,判断输出加法还是乘法

	if (!P) { printf("0 0\n"); return; }

	while (P) {
		if (!flag)
			flag = 1;
		else
			printf(" ");
		printf("%d %d", P->coef, P->expon);
		P = P->link;
	}
	printf("\n");
}

Polynomial Mult(Polynomial P1, Polynomial P2)
{
	Polynomial P, Rear, t1, t2, t;
	int c, e;

	if (!P1 || !P2) return NULL;

	t1 = P1; t2 = P2;
	P = (Polynomial)malloc(sizeof(struct PolyNode)); P->link = NULL;
	Rear = P;
	while (t2) { // 先用P1的第一项乘以P2,得到P
		Attach(t1->coef * t2->coef, t1->expon + t2->expon, &Rear);
		t2 = t2->link;
	}

	t1 = t1->link;
	while (t1)
	{
		t2 = P2;
		Rear = P; 
		while (t2)
		{
			e = t1->expon + t2->expon;
			c = t1->coef * t2->coef;
			while (Rear->link && Rear->link->expon > e) //P第一个的e肯定大于e,从第二个开始比较,P大就指下一个
				Rear = Rear->link;
			if (Rear->link && Rear->link->expon == e) //
			{
				if (Rear->link->coef + c) //
					Rear->link->coef += c;
				else {
					t = Rear->link;
					Rear->link = t->link; //
					free(t); //如果系数相加等于0就释放 怎么释放?
				}
			}
			else {
				t = (Polynomial)malloc(sizeof(struct PolyNode));
				t->coef = c;
				t->expon = e;
				t->link = Rear->link;
				Rear->link = t; 
				Rear = Rear->link;
			}
			t2 = t2->link;
		}
		t1 = t1->link;
	}
	t2 = P; P = P->link; free(t2);
	return P;
}


Polynomial Add(Polynomial P1, Polynomial P2)
{
	int sum;
	Polynomial t1, t2, P, Reaper, t;
	P = (Polynomial)malloc(sizeof(struct PolyNode));
	P->link = NULL;
	Reaper = P;
	t1 = P1;
	t2 = P2;
	while (t1 && t2)
	{
		if (t1->expon == t2->expon)
		{
			sum = t1->coef + t2->coef;
			if (sum)
				Attach(sum, t1->expon, &Reaper);
			//判断加和系数是否为零,如果为零,则不存入结果多项式中
			t1 = t1->link;
			t2 = t2->link;
		}
		else if (t1->expon > t2->expon)
		{
			Attach(t1->coef, t1->expon, &Reaper);
			t1 = t1->link;
		}
		else
		{
			Attach(t2->coef, t2->expon, &Reaper);
			t2 = t2->link;

		}
	}while (t1)
	{
		Attach(t1->coef, t1->expon, &Reaper);
		//Reaper->link = t1;
		t1 = t1->link;
	}
	while (t2)
	{
		//Reaper->link = t1;  用if
		Attach(t2->coef, t2->expon, &Reaper);
		t2 = t2->link;
	}
	Reaper->link = NULL;
	t = P;
	P = P->link;
	free(t);
	return P;
}


int main()
{
	Polynomial p1, p2, pp, ps;
	p1 = ReadPoly();
	p2 = ReadPoly();
	pp = Mult(p1, p2);
	PrintPoly(pp);
	ps = Add(p1, p2);
	PrintPoly(ps);
	return 0;
}

实验二 迷宫

最优解:https://blog.csdn.net/qq_1844548689/article/details/78170830
在这里插入图片描述

实验题目:迷宫的求解
实验内容与要求: 迷宫只有两个门,一个叫做入口,另一个叫做出口。把一只老鼠从一个无顶盖的大盒子的入口处赶进迷宫。迷宫中设置很多隔壁,对前进方向形成了多处障碍,在迷宫的唯一出口处放置了一块奶酪,吸引老鼠在迷宫中寻找通路以到达出口。求解迷宫问题,即找出从入口到出口的路径。
【知识要点】迷宫问题是栈应用的一个典型例子。求解过程可采用回溯法。回溯法是一种不断试探且及时纠正错误的搜索方法。从入口出发,按某一方向向前探索,若能走通(未走过的),即某处可以到达,则到达新点,否则试探下一方向 ; 若所有的方向均没有通路,则沿原路返回前一点,换下一个方向再继续试探,直到所有可能的通路都探索到,或找到一条通路,或无路可走又返回到入口点。在求解过程中,为了保证在到达某一点后不能向前继续行走(无路)时,能正确返回前一点以便继续从下一个方向向前试探,则需要用一个栈保存所能够到达的每一点的下标及从该点前进的方向,栈中保存的就是一条迷宫的通路。
为了确保程序能够终止,调整时,必须保证曾被放弃过的填数序列不被再次试验,即要求按某种有序模型生成填数序列。给解的候选者设定一个被检验的顺序,按这个顺序逐一生成候选者并检验。
【实现提示】对于迷宫问题,用回溯法的难点就在如何为解空间排序,以确保曾被放弃过的填数序列不被再次试验,在二维迷宫里面,从出发点开始,每个点按四邻域算,按照右、上、左、下的顺序搜索下一落脚点,有路则进,无路即退,前点再从下一个方向搜索,即可构成一有序模型。

代码实现

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <malloc.h>
typedef struct Point
{
	int x, y;//坐标位置
	int ord;//标号,0表示未走过,2表示走过
	int di;//从此走向下一个通道的方向,0表示向东,1表示向南,2表示向西,3表示向北
}point,*link_point;

typedef struct Maze_stack //栈,存储通道
{
	point po[100];
	int top;
}maze_stack, *linkmaze_stack;


typedef struct Maze 
{
	int map[10][10]; //用二维数组表示迷宫
	int start[2];//入口
	int end[2];//出口
}maze, * link_maze;

link_maze InitMaze(link_maze &ma)//创建迷宫
{
	ma = (link_maze)malloc(sizeof(maze));
	if (ma == NULL)
		return 0;
	int con[10][10] = { //定义二维数组
		{1,1,1,1,1,1,1,1,1,1},
		{1,0,0,1,0,0,0,1,0,1},
		{1,0,0,1,0,0,0,1,0,1},
		{1,0,0,0,0,1,1,0,0,1},
		{1,0,1,1,1,0,0,0,0,1},
		{1,0,0,0,1,0,0,0,0,1},
		{1,0,1,0,0,0,1,0,0,1},
		{1,0,1,1,1,0,1,1,0,1},
		{1,1,0,0,0,0,0,0,0,1},
		{1,1,1,1,1,1,1,1,1,1}
	};
	for (int i = 0; i < 10; i++)//赋值
	{
		for (int j = 0; j < 10; j++)
		{
			ma->map[i][j] = con[i][j];
			printf("%d ", con[i][j]);//打印迷宫
		}
		printf("\n");
	}
	ma->end[0] = 8; //定义出口
	ma->end[1] = 8;
	ma->start[0] = 1;//定义入口
	ma->start[1] = 1;
	return ma;
}

void InitStack(linkmaze_stack& S) //创立链表
{
	S = (linkmaze_stack)malloc(sizeof(maze_stack));
	S->top = -1;
}

void Push(linkmaze_stack& S, point e)
{
	S->po[++S->top] = e;
}

void Pop(linkmaze_stack& S, point &e)//传地址
{
	
	e = S->po[S->top];
	--S->top;
}

int IsExited(linkmaze_stack S, point e)
{
	//在栈中是否存在元素e
	for (int i = 0; i <= S->top; i++)
	{
		if (S->po[i].x == e.x && S->po[i].y == e.y)
		{
			return 1;
		}
	}
	return 0;
}

point nextpos(point &cur, linkmaze_stack S)//按顺序探测下一个位置
{
	int direction = cur.di;
	if (direction == 0)//东
	{
		++cur.di;
		int m = ++cur.y;
		point cur1 = { cur.x,m,0,0 };
		if (IsExited(S, cur1) == 1)
		{
			cur1.ord = 1;
		}
		//printf("向东为(%d,%d)\r\n", cur1.x, cur1.y);
		return cur1;
	}
	else if (direction == 1)//南
	{
		++cur.di;
		int m = ++cur.x;
		point cur1 = { m,cur.y,0,0 };
		if (IsExited(S, cur1) == 1)
		{
			cur1.ord = 1;
		}
		//printf("(向南为%d,%d)\r\n", cur1.x, cur1.y);
		return cur1;
	}
	else if (direction == 2)//西
	{
		++cur.di;
		int m = --cur.y;
		point cur1 = { cur.x,m,0,0 };
		if (IsExited(S, cur1) == 1)
		{
			cur1.ord = 1;
		}
		//printf("(向西为%d,%d)\r\n", cur1.x, cur1.y);
		return cur1;
	}
	else if (direction == 3)//北
	{
		++cur.di;
		int m = --cur.x;
		point cur1 = { m,cur.y,0,0 };
		if (IsExited(S, cur1) == 1)
		{
			cur1.ord = 1;
		}
		//printf("(向北为%d,%d)\r\n", cur1.x, cur1.y);
		return cur1;
	}
	else//错误判断
	{
		printf("error!");
		point a = { 0,0,0,0 };
		return a;
	}
}

void show_maze(linkmaze_stack& S) //打印迷宫通道的坐标值
{
	int m;
	for (m = 0; m <= S->top; m++)
	{
		if (m==S->top)
		{ 
			printf("(%d,%d)", S->po[m].x, S->po[m].y);
			return;
		}
		printf("(%d,%d)->", S->po[m].x, S->po[m].y);
	}
	
}

//递归求解迷宫通道
//1.检查要走的点是否可以落脚
//2.若可以,则标记并入栈
//3.判断是否为出口
//4.若不是出口,就进行旁边探测
void MazePath(linkmaze_stack& S, link_maze ma)
{
	point start = { ma->start[0],ma->start[1],0,0 };
	point end = { ma->end[0],ma->end[1],0,0 };
	point cur = start;
	point e = { 0,0,0,0 };
	int m = 0;
	do
	{
		
		if (cur.ord != 1 && ma->map[cur.x][cur.y] != 1)
		{
			cur.ord = 1;
			Push(S, cur);
			if (cur.x == end.x && cur.y == end.y)
			{
				printf("\nFind the exit!\n");
				show_maze(S);
				show_maze_path(S, ma);
				return;
			}
			cur = nextpos(cur, S);
		}
		else
		{
	
			if (S->top != -1)
			{
				Pop(S, e);
				while (e.di == 3 && S->top != -1)//如果四周都探测完后
				{
					ma->map[e.x][e.y] = 1;//标记:不能通过
					Pop(S, e);
				}
				if (e.di < 3)
				{
					e.di++;
					Push(S, e);
					cur = nextpos(e, S);
				}
			}
		}
	} while (S->top != -1);
}

int main()
{
	linkmaze_stack S;
	InitStack(S);
	link_maze ma;
	InitMaze(ma);
	MazePath(S, ma);
	return 0;
}

实验三 Huffman 树

同校:https://blog.csdn.net/besonn/article/details/106199290
https://blog.csdn.net/liyuanyue2017/article/details/83870849
全部c++: https://blog.csdn.net/Wood_Du/article/details/80366094
c++: https://blog.csdn.net/google19890102/article/details/54848262
https://blog.csdn.net/i6223671/article/details/86750310
https://blog.csdn.net/weixin_43074474/article/details/90339446
1 实验题目
Huffman 树及 Huffman 编码的算法实现
2 实验目的

  1. 了解该树的应用实例,熟悉掌握 Huffman 树的构造方法及 Huffman 编码的应
    用,
  2. 了解 Huffman 树在通信、编码领域的应用过程。
    3 实验要求
  3. 输入一段100—200字的英文短文,存入一文件 a 中。
  4. 写函数统计短文出现的字母个数 及每个字母的出现次数
  5. 写函数以字母出现次数作权值,建 Huffman 树( 个叶子),给出每个字母的
    Huffman 编码。
  6. 用每个字母编码对原短文进行编码,码文存入文件 b 中。
  7. 用 Huffman 树对 b 中码文进行译码,结果存入文件 c 中,比较 a 、 c 是否一
    致,以检验编码、译码的正确性。
    4 实验内容和实验步骤
    4.1 需求分析
    陈述程序设计的任务,强调程序要做什么,明确规定:
  8. 输入的形式和输入值的范围;
  9. 输出的形式;
  10. 程序所能实现的功能;
    4.2 概要设计
    4.2.1 数据结构定义
//可以运行的
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR -1
#define maxnumber 10000000
typedef  struct art
{
	char* code;
	char letter;
	int   num;
}ART, * INK;
typedef  struct
{
	int weight;
	int parent, lchild, rchild;
}HTNode, * HuffmanTree;

typedef char** HuffmanCode;

void PutArticle()
{
	FILE* fp;
	char ch = '0';
	if ((fp = fopen("article.txt", "w")) == NULL)//打开文件,不存在此文件则新建
	{
		fp = fopen("article.txt", "w");
	}
	printf("请属于一段英文段落以#结束\n");
	while (ch != '#')
	{
		ch = getchar();
		fputc(ch, fp);
	}
	fclose(fp);
}

int SearchArticle(INK& p, int& n)
{
	FILE* fp;
	int i, k;
	//char* INK, ch = '0';
	char ch = '0';
	if ((fp = fopen("article.txt", "r")) == NULL)//打开文件
	{
		printf("\n记录文件不存在!");
		exit(0);
	}
	while (ch != '#')
	{
		ch = fgetc(fp);
		if (ch >= 65 && ch <= 90 || ch >= 97 && ch <= 122)
		{
			for (i = 0, k = 0; i <= n; i++)
			{
				if (ch == p[i].letter)
				{
					p[i].num++;
					k = 1;
				}
			}
			if (k == 0)
			{
				p[n].letter = ch;
				p[n].num = 1;
				n++;

			}
		}
	}fclose(fp);
	return 0;
}

int* CreatW(int n, INK p)//创造权重的数组
{
	int* w = (int*)malloc((n) * sizeof(int));
	for (int i = 0; i < n; i++)
	{
		w[i] = p[i].num;

	}
	return w;
}

void select(HTNode* HT, int n, int& s1, int& s2)
{
	int min = maxnumber; int min2 = maxnumber + 1;
	int p, q;
	p = q = 0;

	for (int i = 1; i <= n; i++)
	{
		if (HT[i].parent == 0)
		{

			if (HT[i].weight <= min && HT[i].weight < min2)
			{
				min2 = min; min = HT[i].weight;
				q = p; p = i;
			}
			if (HT[i].weight<min2 && HT[i].weight>min)
			{
				min2 = HT[i].weight;
				q = i;
			}

		}
	}
	s1 = p;

	s2 = q;
}


void HuffmanCreat(HuffmanTree& HT, HuffmanCode& HC, int* w, int n)
{
	if (n <= 1) return;
	int m = 2 * n - 1, s1 = 0, s2 = 0;
	int i;
	HTNode* p;
	HT = (HTNode*)malloc((m + 1) * sizeof(HTNode));//因为为了号码方便,第0号不用
	p = HT;
	for (i = 1; i <= n; ++i)
		p[i] = { w[i - 1],0,0,0 };//为n个叶子节点赋初值,顺序刚好和字母排列的顺序相同也就是w里面的顺序
	for (; i <= m; ++i)
		p[i] = { 0,0,0,0 };

	for (i = n + 1; i <= m; ++i)
	{
		select(HT, i - 1, s1, s2);

		HT[s1].parent = i; HT[s2].parent = i;
		HT[i].lchild = s1; HT[i].rchild = s2;
		HT[i].weight = HT[s1].weight + HT[s2].weight;
	}




	HC = (HuffmanCode)malloc((n + 1) * sizeof(char*));//创建一个指针数组,每个元素为数组指针指向一个字符串,同理数组长度为n+1
	char* cd = (char*)malloc(n * sizeof(char));//创建一个数组指针,长度为n,因为有n个被编码的叶子就有n-1层,就最多需要n-1位二进制,但是为了保证每串字符能有结尾的标识符所以长度设为了n
	cd[n - 1] = '\0';//字符串结尾标志
	for (int i = 1; i <= n; ++i)
	{
		int start = n - 1;//编码中的倒数第二位
		for (int c = i, f = HT[i].parent; f != 0; c = f, f = HT[f].parent)
		{
			if (HT[f].lchild == c)  cd[--start] = '0';
			else	cd[--start] = '1';
		}
		HC[i] = (char*)malloc((n - start) * sizeof(char));//1.防止浪费过多空间2.编码中没有赋值的不用输出
		strcpy(HC[i], &cd[start]);
	}
	free(cd);//动态存储记得free
}

void CodeArticle(const char* a, int n, INK p)
{

	FILE* fp1, * fp2;
	int i;
	fp1 = fopen("article.txt", "r");
	if ((fp2 = fopen("barticle.txt", "w")) == NULL)
	{
		fp2 = fopen("barticle.txt", "w");
	}
	char ch = fgetc(fp1);
	while (ch != '#')
	{
		for (i = 0; i < n; i++)
			if (ch == p[i].letter)
				break;
		if (i < n) {
			fprintf(fp2, "%s", p[i].code);
		}
		else { fputc(ch, fp2); }
		ch = fgetc(fp1);
	}
	fputc('#', fp2);
	fclose(fp1);
	fclose(fp2);
}

void TransCode(HuffmanTree HT, int n, INK p)//依次读入电文,根据哈夫曼树译码
{
	printf("\n译码结果如下\n");
	char ch;
	int i = 2 * n - 1;//从根节点开始往下搜索
	FILE* fp = fopen("barticle.txt", "r");
	ch = fgetc(fp);
	while (ch != '#')
	{
		if (ch != '0' && ch != '1')
			printf("%c", ch);
		if (ch == '0')
			i = HT[i].lchild;   //走向左孩子
		else if (ch == '1')
			i = HT[i].rchild;   //走向右孩子
		if (HT[i].lchild == 0 && HT[i].lchild == 0)     //tree[i]是叶结点
		{
			printf("%c", p[i - 1].letter);
			i = n * 2 - 1;      //回到根结点
		}
		ch = fgetc(fp);
	}
	printf("\n");
	if (i != n * 2 - 1 && ch == '#')   //电文读完,但尚未到叶子结点
		printf("\nERROR\n");  //输入电文有错
	fclose(fp);
}//decode

int main()
{
	INK p = (INK)malloc(52 * sizeof(ART));//大小写字母
	int n1 = 0;
	PutArticle();
	SearchArticle(p, n1);

	printf("\n总个数:%d\n", n1);
	HuffmanTree HT;
	HuffmanCode HC;
	int s1, s2;
	int* w = CreatW(n1, p);
	FILE* fp2;
	HuffmanCreat(HT, HC, w, n1);
	printf("字母   权值    编码\n");
	for (int i = 0; i < n1; i++)
	{

		printf("%c\t", p[i].letter);
		printf("%d\t", p[i].num);
		p[i].code = HC[i + 1];
		printf("%s\n", p[i].code);
	}

	CodeArticle("article.txt", n1, p);
	TransCode(HT, n1, p);

	free(HT);
	free(HC);
	free(w); system("pause");
	return 0;


}

//遇到调试过程中的断点,尤其是在malloc,一定要往前找,肯定之前的malloc出错1了

okk

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <malloc.h>
#include<string>
typedef char* Code;//Huffman 编码定义
//Huffman 树定义
typedef struct
{
	char letter;// 字符
	int weight;	// 权重
	int parent, left, right;// 父节点、左孩子、右孩子下标
} Node, * Tree;

//输入英文短文
void InputAndSave(const char* filename)
{
	// 新建 / 打开文件
	FILE* fp = fopen(filename, "w");
	printf("Please input an essay, end with an enter:\n");
	while (true)
	{
		// 从 stdin 中读取一个字符
		char ch = getchar();
		// 若字符为'\n',退出循环
		if (ch == '\n')
			break;
		// 写入文件中
		fputc(ch, fp);
	}
	// 关闭文件
	fclose(fp);
}

//找两个权重小的
void Select(Tree ht, int n, int& s1, int& s2)
{
	// ......
	int i;//计数的
	int min1 = 1000;
	int min2 = 1000;//规定一个特别大的数
	for (i = 1; i <= n; i++)
	{
		if (ht[i].parent == 0 && min1 > ht[i].weight)
		{
			min1 = ht[i].weight;
			s1 = i;
		}
	}
	for (i = 1; i <= n; i++)
	{
		if (ht[i].parent == 0 && i != s1)
		{
			if (min2 > ht[i].weight)
			{
				min2 = ht[i].weight;
				s2 = i;
			}
		}
	}
}

//构造 Huffman 树
void CreateHuffmanTree(const char* filename, Tree& ht, int& n)
{
	// 从文件中逐个读取字符并计数
	FILE* fp = fopen(filename, "r");
	int count[128] = { 0 };
	n = 0;
	while (true)
	{
		char ch = fgetc(fp);
		if (ch == EOF)
			break;
		if (count[ch] == 0)
			n += 1;
		count[ch] += 1;
	}
	fclose(fp);
	// 申请 Huffman 树空间
	ht = (Tree)malloc((2 * n) * sizeof(Node));
	// 不使用 0 号单元
	// 将字符及权重存入树中
	// 置 parent, left, right 为 0
	Tree p = ht + 1;//为什么加1
	int i;
	for (i = 0; i < 128; i++)
	{
		// ......
		if (count[i] != 0)
		{
			p->weight = count[i];
			p->letter = (char)i;
			p->left = 0;
			p->right = 0;
			p->parent = 0;
			p++;
		}
	}
	for (int i = n + 1; i <= 2 * n - 1; i++)
	{
		*p = { 0,0,0,0,0 };
		p++;
	}
	// 构建 Huffman 树
	int s1, s2;
	s1 = s2 = 0;
	for (int i = n + 1; i < 2 * n; i++) {
		// 在 ht[1..i-1] 中选择 parent=0 且 weight 最小的两个结点
		Select(ht, i - 1, s1, s2);
		// 更新子节点与父节点的信息
		// ......
		ht[s1].parent = i; ht[s2].parent = i;
		ht[i].left = s1; ht[i].right = s2;
		ht[i].weight = ht[s1].weight + ht[s2].weight;
	}
}

//获取字符 Huffman 编码
void CreateHuffmanCode(Tree ht, int n, Code hc[]) {
	// 编码临时存储空间
	char* cd = (char*)malloc(n * sizeof(char));
	cd[n - 1] = '\0';
	// 从叶子节点逆向求编码
	// ......
	//Code hc = (char*)malloc((n+1) * sizeof(char*));
	for (int i = 1; i <= n; i++)
	{
		int start = n - 1;//编码中的倒数第二位
		int pos = i;//pos记录正在处理的当前位置
		int	f = ht[i].parent;//找到父节点
		for (; f != 0; pos = f, f = ht[f].parent)
		{
			if (ht[f].left == pos)//判断是左孩子还是右孩子
				cd[--start] = '0';
			else
				cd[--start] = '1';
		}
		hc[i] = (char*)malloc((n - start) * sizeof(char));//1.防止浪费过多空间2.编码中没有赋值的不用输出
		strcpy(hc[i], &cd[start]);
	}
	// 释放临时存储空间
	free(cd);
}

void Encode(const char* src, const char* dst, Code* hc, int n, Tree ht)
{  //短文编码
	int i;
	FILE* fsrc = fopen(src, "r");
	FILE* fdst = fopen(dst, "w");
	while (true)
	{
		i = 1;
		char ch = fgetc(fsrc);
		if (ch == EOF) //当读到文件尾时编码结束
			break;
		for (i = 1; i <= n; i++)
		{  //查找字符对应的Huffman编码
			if (ch == ((ht + i)->letter))
				break;
		}
		fputs(*(hc + i), fdst);//将编码写入文件中
		//printf("%c", *(hc + i));

	}
	fclose(fsrc);
	fclose(fdst);
}

//短文解码
void Decode(const char* src, const char* dst, Tree h, int n)
{
	FILE* fsrc = fopen(src, "r");
	FILE* fdst = fopen(dst, "w");
	// 寻找叶子节点
	// 到达叶子结点后将对应字符写入 dst 中
	// ......
	int i = 2 * n-1;
	char ch = fgetc(fsrc);
	Tree ht = h;
	while ( ch!= EOF)
	{
		if (ch == '0')
			i = (ht + i)->left;
		else if (ch == '1')
			i = (ht + i)->right;
		if ((h + i)->left == 0 && (h + i)->right == 0)     //tree[i]是叶结点
		{
			fputc((h+i)->letter, fdst);
			i = n * 2-1;//返回头节点
		}
		ch = fgetc(fsrc);
	}
	if (i != 2 * n-1)
		printf("\nERROR\n");
	fclose(fsrc);
	fclose(fdst);
}


bool Compare(const char* first, const char* second) {
	FILE* f1 = fopen(first, "r");
	FILE* f2 = fopen(second, "r");
	// 逐字符比较两个文件
	while (!feof(f1) && !feof(f2)) {
		char c1 = fgetc(f1);
		char c2 = fgetc(f2);
		// 字符不相同,跳出循环
		if (c1 != c2)
			break;
	}
	// 两个文件未同时到达末尾
	int res = true;
	if (!feof(f1) || !feof(f2))
		res = false;
	fclose(f1);
	fclose(f2);
	return res;
}


int main() {
	Tree ht;
	int n = 0;
	// 输入英文文章并保存到 a.txt 中
	InputAndSave("a.txt");
	// 构造 Huffman 树
	CreateHuffmanTree("a.txt", ht, n);
	// 获取 Huffman 编码
	Code* hc = (Code*)malloc((n + 1) * sizeof(char*));
	CreateHuffmanCode(ht, n, hc);
	// 短文编码
	Encode("a.txt", "b.txt", hc, n, ht);
	// 短文解码
	Decode("b.txt", "c.txt", ht, n);
	// 原文与解码后短文比较
	printf("a.txt is %s to c.txt",
		Compare("a.txt", "c.txt") ? "equal" : "NOT equal");
	// 释放空间
	free(ht);
	return 0;
}

跟上面一样的

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct
{
	char letter;//字符
	unsigned int weight;//权重
	unsigned int parent, lchild, rchild; //父结点、左孩子、右孩子结点
}HTNode, * HuffmanTree;
typedef char* HuffmanCode;

void InputAndSave(const char* filename) //文章读入
{
	FILE* fp;
	fp = fopen(filename, "w");
	printf("Please input an essay, end with an enter:\n");
	while (true)
	{
		char ch = getchar();
		if (ch == '\n') //换行符标志着短文的结束
			break;
		fputc(ch, fp); //将每一个字符输入到文件中
	}
	fclose(fp);
}

void CountChar(const char* filename, int& n, int count[])
{  //统计短文中出现的字符种类数以及每个字符的个数,并存储在count数组中
	FILE* fp = fopen(filename, "r");
	n = 0;
	while (true)
	{
		char ch = fgetc(fp);
		if (ch == EOF)
			break;
		if (count[ch] == 0)
			n += 1;
		count[ch] += 1;
	}
	fclose(fp);

}
void Select(HuffmanTree ht, int n, int& s1, int& s2)
{   //在HT[1...i-1]中选择parent为0且weight最小的两个结点,其序号为s1和s2
	int min1 = 1000, min2 = 1000, i, j;
	for (i = 1; i <= n; i++)
	{
		if (min1 > ((ht + i)->weight) && ((ht + i)->parent) == 0)
		{  //如果当min1大于下一个结点的权值并且下一个结点没有父亲,则更新当前min1的值
			min1 = ((ht + i)->weight);
			s1 = i;
		}
	}
	for (j = 1; j <= n; j++)
	{
		if (min2 > ((ht + j)->weight) && ((ht + j)->parent) == 0 && j != s1)
		{  //如果当min2大于下一个结点的权值并且下一个结点没有父亲并且不是权值最小的结点,则更新当前min1的值
			min2 = ((ht + j)->weight);
			s2 = j;
		}
	}
}
void CreateHuffmanTree(HuffmanTree& HT, int n, int count[])
{
	int s1, s2;
	HT = (HuffmanTree)malloc(2 * n * sizeof(HTNode));
	HuffmanTree p = HT + 1;
	//初始化Huffman树,1-n个结点为叶子结点
	for (int i = 0; i < 128; i++)
	{
		if (count[i] != 0)
		{
			p->weight = count[i];
			p->letter = (char)i;
			p->lchild = 0;
			p->rchild = 0;
			p->parent = 0;
			p++;
		}
	}
	for (int i = n + 1; i <= 2 * n - 1; ++i, ++p)
		*p = { 0,0,0,0,0 };
	//构建Huffman树
	for (int i = n + 1; i <= 2 * n - 1; i++)
	{
		Select(HT, i - 1, s1, s2);
		HT[s1].parent = i;
		HT[s2].parent = i;
		HT[i].lchild = s1;
		HT[i].rchild = s2;
		HT[i].weight = HT[s1].weight + HT[s2].weight;
	}
}

void CreateHuffmanCode(HuffmanTree ht, HuffmanCode hc[], int n)
{   //从叶子到根逆向求每个字符的Huffman编码
	int start, i, c, f;
	HuffmanCode cd = (char*)malloc(n * sizeof(char));//分配求编码的工作空间
	cd[n - 1] = '\0'; //编码结束符
	for (i = 1; i <= n; i++)
	{
		start = n - 1; //编码结束符位置
		for (c = i, f = (ht + i)->parent; f != 0; c = f, f = (ht + f)->parent)
		{  //从叶子到根逆向求编码
			if ((ht + f)->lchild == c)
				cd[--start] = '0';
			else
				cd[--start] = '1';
		}
		//为第i个字符编码分配空间
		hc[i] = (char*)malloc((n - start) * sizeof(char));
		strcpy(hc[i], &cd[start]);//从cd复制编码串到HC
	}
	free(cd);
}

void Encode(const char* src, const char* dst, HuffmanCode* hc, int n, HuffmanTree ht)
{  //短文编码
	int i;
	FILE* fsrc = fopen(src, "r");
	FILE* fdst = fopen(dst, "w");
	while (true)
	{
		i = 1;
		char ch = fgetc(fsrc);
		if (ch == EOF) //当读到文件尾时编码结束
			break;
		for (i = 1; i <= n; i++)
		{  //查找字符对应的Huffman编码
			if (ch == ((ht + i)->letter))
				break;
		}
		fputs(*(hc + i), fdst);//将编码写入文件中
		//printf("%c", *(hc + i));

	}
	fclose(fsrc);
	fclose(fdst);
}

void Decode(const char* src, const char* dst, HuffmanTree ht, int n)
{   //文章解码
	int flag = 0;
	unsigned int i = 0;

	FILE* fsrc = fopen(src, "r");
	FILE* fdst = fopen(dst, "w");
	HuffmanTree p = ht;
	i = 2 * n - 1;
	while (true)
	{
		char ch = fgetc(fsrc);
		if (ch == EOF)
			break;
		if (ch == '0')
			i = (p + i)->lchild;
		else if (ch == '1')
			i = (p + i)->rchild;
		if ((ht + i)->lchild == 0 && (ht + i)->rchild == 0)
		{
			fputc((ht + i)->letter, fdst);
			i = 2 * n - 1;
		}
	}
	fclose(fsrc);
	fclose(fdst);
}

bool Compare(const char* first, const char* second)
{
	FILE* f1 = fopen(first, "r");
	FILE* f2 = fopen(second, "r");
	//逐字符比较两个文件
	while (!feof(f1) && !feof(f2))
	{
		char c1 = fgetc(f1);
		char c2 = fgetc(f2);
		if (c1 != c2)
			break;
	}
	int res = true;
	if (!feof(f1) || !feof(f2))
		res = false;
	fclose(f1);
	fclose(f2);
	return res;
}
int main()
{
	int n;//n表示文章中字符种类数
	int count[128] = { 0 };//记录不同字符的个数
	HuffmanTree HT;
	HuffmanCode* HC;
	//输入英文文章并保存到a.txt中
	InputAndSave("a.txt");
	CountChar("a.txt", n, count);
	//构造Huffman树
	CreateHuffmanTree(HT, n, count);
	HC = (HuffmanCode*)malloc((n + 1) * sizeof(char*)); //HC表示存储n个编码的字符指针数组的首地址
	//求每个字符的Huffman编码
	CreateHuffmanCode(HT, HC, n);
	//短文编码
	Encode("a.txt", "b.txt", HC, n, HT);
	//短文解码
	Decode("b.txt", "c.txt", HT, n);
	//原文与解码后短文比较
	printf("a.txt is %s to c.txt", Compare("a.txt", "c.txt") ? "equal" : "not equal");

	free(HT);
	return 0;
}

实验四

c++ https://www.docin.com/p-708437906.html?docfrom=rrela
https://www.docin.com/p-80529155.html?docfrom=rrela 💛
https://www.pianshen.com/article/44091116126/
实验题目:校园导游咨询
实验目的:掌握图的存储方法和最短路经算法。
实验内容:设计一个校园导游程序,为来访客人提供各种信息查询服务。测试数据根据实际情况指定。提示:一般情况下,校园的道路是双向通行的,可设校园平面图是一个无向图。顶点和边均含有相关信息。
实验要求: 1、设计所在学校的校园平面图,所含景点不少于10个。以图中顶点表示校内各景点,存放景点名称、代号、简介等信息;以边表示路径,存放路径长度等相关信息。 2、为来访客人提供图中任意景点相关信息的查询。 3、为来访客人提供图中任意景点的纹路查询,即查询任意两个景点之间的一条最短的简单路径。
实验内容和实验步骤:(由学生填写)
实验用测试数据和相关结果分析:(由学生填写)
实验总结:(由学生填写)

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<Windows.h>
#include<conio.h>//用于输入输出
#define INFFINITY 10000 //无穷大
#define VERTEX 12 //景点个数 (0号不用
//邻接矩阵
typedef struct ArCell
{
	int adj;
}ArCell, AdjMatrix[VERTEX][VERTEX];
typedef struct//图中顶点表示主要景点
{
	char name[20];
	int num;
	char introduction[100];
}infotype;
typedef struct
{
	infotype vexs[VERTEX];
	AdjMatrix arcs;
	int vexnum, arcnum;
}MGraph;


void Menu();//全景图和选项
void map();//地图全景
MGraph InitGraph();//图初始化
void Search(MGraph G);//查看景点信息
void ShortestPath_Floyd(MGraph G);//最短路径

int main()
{
	system("color ec");
	system("mode con:cols=110 lines=30");//换个底色
	Menu();
	return 0;
}

void map()
{
	printf("┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ┓\n");
	printf("┃                                                                                               ┃\n");
	printf("┃                  【  11操场  】 ━━━━━━━━━━━━━━━━━━━━━━┓                ┃\n");
	printf("┃                        ┃                                                   ┃                ┃\n");
	printf("┃                        ┃                                                   ┃                ┃\n");
	printf("┃ 【 10校医院  】━━【 9食堂 】━━━━━━【 8樱花大道 】━━━━━━【 7图书馆 】            ┃\n");
	printf("┃                       ┃                         ┃                          ┃               ┃\n");
	printf("┃                       ┃                      【 4教学区 】 【 5映月湖 】━━┛━【 6行远楼 】┃\n");
	printf("┃                       ┃                           ┃                        ┃               ┃\n");
	printf("┃                  【 3体育馆 】━━━━━━━━【 2二五广场 】━━━━━━━━┛               ┃\n");
	printf("┃                                                    ┃                                         ┃\n");
	printf("┃                                               【 1西北门 】                                   ┃\n");
	printf("┃                                                                                               ┃\n");
	printf("┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ┛\n");
}

void Menu()
{
	MGraph G = InitGraph();
	printf("欢迎来到中国海洋大学!\n");
	printf("校园全景:\n");
	map();
	printf("选择界面:【1】查看景点  【2】最短路程  【3】退出系统\n");
	int i;
	scanf("%d", &i);
	while (i != 1 && i != 2 && i != 3)
	{
		printf("输入错误,请重新输入:");
		scanf("%d", &i);
	}
	switch (i)
	{
	case 1:
		system("cls");
		map();
		Search(G);
		system("cls");
		Menu();
		break;
	case 2:
		system("cls");
		map();
		ShortestPath_Floyd(G);
		system("cls");
		Menu();
		break;
	case 3:
		break;
	}
}

//图的定义
MGraph InitGraph()
{
	MGraph G;
	int i, j;
	G.vexnum = 11;
	G.arcnum = 17;
	for (i = 1; i <= G.vexnum; i++)
		G.vexs[i].num = i;
	strcpy(G.vexs[1].name, "西北门");
	strcpy(G.vexs[1].introduction, "学校正门。");
	strcpy(G.vexs[2].name, "二五广场");
	strcpy(G.vexs[2].introduction, "二五广场。");
	strcpy(G.vexs[3].name, "体育馆");
	strcpy(G.vexs[3].introduction, "可以容纳3千人。");
	strcpy(G.vexs[4].name, "教学区");
	strcpy(G.vexs[4].introduction, "学生上课的地方");
	strcpy(G.vexs[5].name, "映月湖");
	strcpy(G.vexs[5].introduction, "美丽的湖。");
	strcpy(G.vexs[6].name, "行远楼");
	strcpy(G.vexs[6].introduction, "教师工作人员办公的地方。");
	strcpy(G.vexs[7].name, "图书馆");
	strcpy(G.vexs[7].introduction, "里面有丰富的藏书。");
	strcpy(G.vexs[8].name, "樱花大道");
	strcpy(G.vexs[8].introduction, "两旁有樱花树。");
	strcpy(G.vexs[9].name, "食堂");
	strcpy(G.vexs[9].introduction, "有很多美食。");
	strcpy(G.vexs[10].name, "校医院");
	strcpy(G.vexs[10].introduction, "看病的地方。");
	strcpy(G.vexs[11].name, "操场");
	strcpy(G.vexs[11].introduction, "学生运动的地方。");

	for (i = 1; i <= G.vexnum; i++)
		for (j = 1; j <= G.vexnum; j++)
			G.arcs[i][j].adj = INFFINITY;
	G.arcs[1][2].adj = 100;
	G.arcs[2][3].adj = 70;
	G.arcs[2][4].adj = 50;
	G.arcs[2][5].adj = 900;
	G.arcs[2][6].adj = 1000;
	G.arcs[2][7].adj = 1100;
	G.arcs[3][9].adj = 200;
	G.arcs[4][8].adj = 300;
	G.arcs[5][6].adj = 200;
	G.arcs[5][7].adj = 200;
	G.arcs[7][6].adj = 400;
	G.arcs[8][7].adj = 500;
	G.arcs[9][8].adj = 200;
	G.arcs[9][10].adj = 1000;
	G.arcs[9][11].adj = 500;
	G.arcs[11][7].adj = 1500;
	for (i = 1; i <= G.vexnum; i++)
		for (j = 1; j <= G.vexnum; j++)
			G.arcs[j][i].adj = G.arcs[i][j].adj;
	return G;
}



void ShortestPath_Floyd(MGraph G)
{
	int n = G.vexnum;
	int v, i, j, k, flag = 1, v0;
	int dist[VERTEX][VERTEX], path[VERTEX][VERTEX][VERTEX];
	for (i = 1; i <= n; i++)
		for (j = 1; j <= n; j++)
		{
			dist[i][j] = G.arcs[i][j].adj;
			for (k = 1; k <= n; k++)
				path[i][j][k] = 0;
			if (dist[i][j] < INFFINITY)
			{
				path[i][j][i] = 1;
				path[i][j][j] = 1;
			}
		}
	for (k = 1; k <= n; k++)
		for (i = 1; i <= n; i++)
			for (j = 1; j <= n; j++)
				if (dist[i][k] + dist[k][j] < dist[i][j])
				{
					dist[i][j] = dist[i][k] + dist[k][j];
					for (int l = 1; l <= n; l++)
					{
						path[i][j][l] = path[i][k][l] || path[k][j][l];
					}
				}
	while (flag)
	{
		printf("请输入出发点和目的地的编号(格式如:x-y):");
		scanf("%d-%d", &v0, &v);
		while (v0<1 || v0>n || v<1 || v>n || (v0 == v))
		{
			printf("景点编号不存在!请重新输入出发点和目的地的编号(格式如:x-y):");
			scanf("%d-%d", &v0, &v);
		}
		if (v0 > 0 && v0 <= n && v > 0 && v <= n && v != v0)
			flag = 0;
	}

	
	if (v0 > v)
	{
		printf("最短路径点为:%s->", G.vexs[v0].name);
		for (k = n; k > 0; k--)
			if (path[v0][v][k] && v0 != k && v != k && v0 > v)
				printf("%s->", G.vexs[k].name);
		printf("%s\n", G.vexs[v].name);
	}
	else
	{
		printf("%s", G.vexs[v0].name);
		for (k = 1; k < n; k++)
			if (path[v0][v][k] && v0 != k && v != k && v0 < v)
				printf("->%s", G.vexs[k].name);
		printf("->%s\n", G.vexs[v].name);
	}
	printf("输入:【1】继续  【2】返回菜单\n");
	scanf("%d", &i);
	while (i != 1 && i != 2)
	{
		printf("输入错误,请重新输入:");
		scanf("%d", &i);
	}
	if (i == 1)
		ShortestPath_Floyd(G);

}


void Search(MGraph G)
{
	int k, flag = 1;
	while (flag)
	{
		printf("请输入要查询的景点编号:");
		scanf("%d", &k);
		while (k<1 || k>G.vexnum)
		{
			printf("景点编号不存在!请重新输入要查询的景点编号:");
			scanf("%d", &k);
		}
		if (k >= 1 && k <= G.vexnum)
			flag = 0;
	}
	printf("【%d %s】简介:%s\n", G.vexs[k].num, G.vexs[k].name, G.vexs[k].introduction);
	int i;
	printf("输入:【1】继续  【2】返回菜单\n");
	scanf("%d", &i);
	while (i != 1 && i != 2)
	{
		printf("输入错误,请重新输入:");
		scanf("%d", &i);
	}
	if (i == 1)
		Search(G);

}


改了 一下调用的

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<Windows.h>
#include<conio.h>//用于输入输出
#define INFFINITY 10000 //无穷大
#define VERTEX 12 //景点个数 (0号不用
//邻接矩阵
typedef struct ArCell
{
	int adj;
}ArCell, AdjMatrix[VERTEX][VERTEX];
typedef struct//图中顶点表示主要景点
{
	char name[20];//名称
	int num;//编号
	char introduction[100];//简介
}infotype;
typedef struct
{
	infotype vexs[VERTEX];
	AdjMatrix arcs;
	int vexnum, arcnum;
}MGraph;


void Menu();//全景图和选项
void map();//地图全景
MGraph InitGraph();//图初始化
void Search(MGraph G);//查看景点信息
void ShortestPath_Floyd(MGraph G, int path[][VERTEX][VERTEX]);//计算每对顶点的最短路径
void Qshortpath(int path[][VERTEX][VERTEX], MGraph G);//查询最短路径

int main()
{
	system("color ec");
	system("mode con:cols=110 lines=30");//换个底色
	Menu();
	return 0;
}

void Menu()
{
	MGraph G = InitGraph();
	int path[VERTEX][VERTEX][VERTEX];
	ShortestPath_Floyd(G,path);
	printf("欢迎来到中国海洋大学!\n");
	printf("校园全景:\n");
	map();
	printf("选择界面:【1】查看景点  【2】最短路程  【3】退出系统\n");
	int i;
	scanf("%d", &i);
	while (i != 1 && i != 2 && i != 3)
	{
		printf("输入错误,请重新输入:");
		scanf("%d", &i);
	}
	switch (i)
	{
	case 1:
		system("cls");
		map();
		Search(G);
		system("cls");
		Menu();
		break;
	case 2:
		system("cls");
		map();
		Qshortpath(path, G);
		system("cls");
		Menu();
		break;
	case 3:
		break;
	}
}

void map()
{
	printf("┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ┓\n");
	printf("┃                                                                                               ┃\n");
	printf("┃                  【  11操场  】 ━━━━━━━━━━━━━━━━━━━━━━┓                ┃\n");
	printf("┃                        ┃                                                   ┃                ┃\n");
	printf("┃                        ┃                                                   ┃                ┃\n");
	printf("┃ 【 10校医院  】━━【 9食堂 】━━━━━━【 8樱花大道 】━━━━━━【 7图书馆 】            ┃\n");
	printf("┃                       ┃                         ┃                          ┃               ┃\n");
	printf("┃                       ┃                      【 4教学区 】 【 5映月湖 】━━┛━【 6行远楼 】┃\n");
	printf("┃                       ┃                           ┃                        ┃               ┃\n");
	printf("┃                  【 3体育馆 】━━━━━━━━【 2二五广场 】━━━━━━━━┛               ┃\n");
	printf("┃                                                    ┃                                         ┃\n");
	printf("┃                                               【 1西北门 】                                   ┃\n");
	printf("┃                                                                                               ┃\n");
	printf("┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ┛\n");
}


//图的定义
MGraph InitGraph()
{
	MGraph G;
	int i, j;
	G.vexnum = 11;
	G.arcnum = 17;
	for (i = 1; i <= G.vexnum; i++)
		G.vexs[i].num = i;
	strcpy(G.vexs[1].name, "西北门");
	strcpy(G.vexs[1].introduction, "学校正门。");
	strcpy(G.vexs[2].name, "二五广场");
	strcpy(G.vexs[2].introduction, "二五广场。");
	strcpy(G.vexs[3].name, "体育馆");
	strcpy(G.vexs[3].introduction, "可以容纳3千人。");
	strcpy(G.vexs[4].name, "教学区");
	strcpy(G.vexs[4].introduction, "学生上课的地方");
	strcpy(G.vexs[5].name, "映月湖");
	strcpy(G.vexs[5].introduction, "美丽的湖。");
	strcpy(G.vexs[6].name, "行远楼");
	strcpy(G.vexs[6].introduction, "教师工作人员办公的地方。");
	strcpy(G.vexs[7].name, "图书馆");
	strcpy(G.vexs[7].introduction, "里面有丰富的藏书。");
	strcpy(G.vexs[8].name, "樱花大道");
	strcpy(G.vexs[8].introduction, "两旁有樱花树。");
	strcpy(G.vexs[9].name, "食堂");
	strcpy(G.vexs[9].introduction, "有很多美食。");
	strcpy(G.vexs[10].name, "校医院");
	strcpy(G.vexs[10].introduction, "看病的地方。");
	strcpy(G.vexs[11].name, "操场");
	strcpy(G.vexs[11].introduction, "学生运动的地方。");

	for (i = 1; i <= G.vexnum; i++)
		for (j = 1; j <= G.vexnum; j++)
			G.arcs[i][j].adj = INFFINITY;
	G.arcs[1][2].adj = 100;
	G.arcs[2][3].adj = 70;
	G.arcs[2][4].adj = 50;
	G.arcs[2][5].adj = 900;
	G.arcs[2][6].adj = 1000;
	G.arcs[2][7].adj = 1100;
	G.arcs[3][9].adj = 200;
	G.arcs[4][8].adj = 300;
	G.arcs[5][6].adj = 200;
	G.arcs[5][7].adj = 200;
	G.arcs[7][6].adj = 400;
	G.arcs[8][7].adj = 500;
	G.arcs[9][8].adj = 200;
	G.arcs[9][10].adj = 1000;
	G.arcs[9][11].adj = 500;
	G.arcs[11][7].adj = 1500;
	for (i = 1; i <= G.vexnum; i++)
		for (j = 1; j <= G.vexnum; j++)
			G.arcs[j][i].adj = G.arcs[i][j].adj;
	return G;
}



void ShortestPath_Floyd(MGraph G,int path[][VERTEX][VERTEX])
{
	int n = G.vexnum;
	int  i, j, k;
	int dist[VERTEX][VERTEX];
	for (i = 1; i <= n; i++)
		for (j = 1; j <= n; j++)
		{
			dist[i][j] = G.arcs[i][j].adj;
			for (k = 1; k <= n; k++)
				path[i][j][k] = 0;
			if (dist[i][j] < INFFINITY)
			{
				path[i][j][i] = 1;
				path[i][j][j] = 1;
			}
		}
	for (k = 1; k <= n; k++)
		for (i = 1; i <= n; i++)
			for (j = 1; j <= n; j++)
				if (dist[i][k] + dist[k][j] < dist[i][j])
				{
					dist[i][j] = dist[i][k] + dist[k][j];
					for (int l = 1; l <= n; l++)
					{
						path[i][j][l] = path[i][k][l] || path[k][j][l];
					}
				}
}

void Qshortpath(int path[][VERTEX][VERTEX],MGraph G)
{
	int flag = 1, v0, v, k, i;
	int n = G.vexnum;
	while (flag)
	{
		printf("请输入出发点和目的地的编号(格式如:x-y):");
		scanf("%d-%d", &v0, &v);
		while (v0<1 || v0>n || v<1 || v>n || (v0 == v))
		{
			printf("景点编号不存在!请重新输入出发点和目的地的编号(格式如:x-y):");
			scanf("%d-%d", &v0, &v);
		}
		if (v0 > 0 && v0 <= n && v > 0 && v <= n && v != v0)
			flag = 0;
	}


	if (v0 > v)
	{
		printf("最短路径点为:%s->", G.vexs[v0].name);
		for (k = n; k > 0; k--)
			if (path[v0][v][k] && v0 != k && v != k && v0 > v)
				printf("%s->", G.vexs[k].name);
		printf("%s\n", G.vexs[v].name);
	}
	else
	{
		printf("%s", G.vexs[v0].name);
		for (k = 1; k < n; k++)
			if (path[v0][v][k] && v0 != k && v != k && v0 < v)
				printf("->%s", G.vexs[k].name);
		printf("->%s\n", G.vexs[v].name);
	}
	printf("输入:【1】继续  【2】返回菜单\n");
	scanf("%d", &i);
	while (i != 1 && i != 2)
	{
		printf("输入错误,请重新输入:");
		scanf("%d", &i);
	}
	if (i == 1)
		Qshortpath(path, G);
}


void Search(MGraph G)
{
	int k, flag = 1;
	while (flag)
	{
		printf("请输入要查询的景点编号:");
		scanf("%d", &k);
		while (k<1 || k>G.vexnum)
		{
			printf("景点编号不存在!请重新输入要查询的景点编号:");
			scanf("%d", &k);
		}
		if (k >= 1 && k <= G.vexnum)
			flag = 0;
	}
	printf("【%d %s】简介:%s\n", G.vexs[k].num, G.vexs[k].name, G.vexs[k].introduction);
	int i;
	printf("输入:【1】继续  【2】返回菜单\n");
	scanf("%d", &i);
	while (i != 1 && i != 2)
	{
		printf("输入错误,请重新输入:");
		scanf("%d", &i);
	}
	if (i == 1)
		Search(G);

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值