算法练习(六)

一、二叉树的遍历-1

题目

输入图片说明

写出这个二叉树的前序遍历,中序遍历,后序遍历。

答案

前序遍历,也叫先根遍历,遍历的顺序是,根,左子树,右子树

遍历结果:A,B,E,F,C,G

中序遍历,也叫中根遍历,顺序是 左子树,根,右子树

遍历结果:E,B,F,A,G,C

后序遍历,也叫后根遍历,遍历顺序,左子树,右子树,根

遍历结果:E,F,B,G,C,A

代码

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

typedef struct BiTNode {
	char data;
	struct BiTNode *lc, * rc;
}BiTNode, *BiTree;

BiTree createBT() {
	BiTree t;
	char c;
	scanf("%c",&c);
	
	if (c == '#') // # 代表null
		t = NULL;
	else {
		t = (BiTree)malloc(sizeof(BiTNode));
		t -> data = c;
		t -> lc = createBT();
		t -> rc = createBT();
	} 
	
	return t;
}

void PreOrderTraverse(BiTree t) { // 前序遍历 
	if (t == NULL)
		return;
	printf("%c",t -> data);
	PreOrderTraverse(t -> lc);
	PreOrderTraverse(t -> rc);
}

void InOrderTraverse(BiTree t) { // 中序遍历 
	if (t == NULL)
		return;
	InOrderTraverse(t -> lc);
	printf("%c",t -> data);
	InOrderTraverse(t -> rc);
}

void PosOrderTraverse(BiTree t) { // 后序遍历 
	if (t == NULL)
		return;
	PosOrderTraverse(t -> lc);
	PosOrderTraverse(t -> rc);
	printf("%c",t -> data);
}

int main() {
	BiTree t;
	
	t = createBT();
	printf("前序遍历:");
	PreOrderTraverse(t);
	printf("
中序遍历:");
	InOrderTraverse(t);
	printf("
后序遍历:");
	PosOrderTraverse(t);
	
	return 0;
}

//ABE##F##CG###

解题思路

运用二叉树的构建及递归的思想完成此题,要注意三种遍历方式的不同。


二、二叉树的遍历-2

题目

依次给出二叉树的前序历遍和中序历遍,请输出它的后序历遍

Input

输入包含多个测试用例。每个测试用例的第一行包含一个整数n(1 < = n < = 1000),二叉树的结点的个数。其次是两行,分别表示前序遍历和中序遍历。

Output

为每个测试用例输出一行指定相应的后序遍历结果。

Sample Input

9

1 2 4 7 3 5 8 9 6

4 7 2 1 8 5 9 3 6

Sample Output

7 4 2 8 9 5 6 3 1

请思考:

如果给出中序遍历和后序遍历能否求出前序遍历呢?

如果给出前序遍历和后序遍历能否求出中序遍历呢?

代码

#include<stdio.h>
int t1[1000],t2[1000];

void pos(int a,int b,int n) { // a为前序的位置,b为中序的位置,n为结点数
	if (n == 1) { // 结点数为 1,此时为叶结点 
		printf("%d ",t1[a]);
		return;
	} else if (n < 1) {
		return;
	}
	
	int i;
	for (i = 0; t1[a] != t2[b+i]; i++);
	
	pos(a+1,b,i); // 左树 
	pos(a+i+1,b+i+1,n-i-1); // 右树
	
	// 输出结点(根结点或内部结点) 
	printf("%d ",t1[a]);
}

int main() {
	int n,j;
	while (scanf("%d",&n) != EOF) {
		for (j = 0; j < n; j++) 
			scanf("%d",&t1[j]);
		for (j = 0; j < n; j++) 
			scanf("%d",&t2[j]);
			
		pos(0,0,n);
		printf("
");
	}
	
	return 0;
}

解题思路

利用递归思想,不断区分左树与右树,当只有一个节点时输出该结点。

思考:给出中序遍历和后序遍历可以求出前序遍历;给出前序遍历和后序遍历不能求出中序遍历


三、回家过年

题目

NowCoder今年买了一辆新车,他决定自己开车回家过年。回家过程中要经过n个大小收费站,每个收费站的费用不同,你能帮他计算一下最少需要给多少过路费吗?

输入描述:

输入包含多组数据,每组数据第一行包含两个正整数m(1≤m≤500)和n(1≤n≤30),其中n表示有n个收费站,编号依次为1、2、…、n。出发地的编号为0,终点的编号为n,即需要从0到n。
紧接着m行,每行包含三个整数f、t、c,(0≤f, t≤n; 1≤c≤10),分别表示从编号为f的地方开到t,需要交c元的过路费。

输出描述:

对应每组数据,请输出至少需要交多少过路费。

示例

输入:
8 4
0 1 10
0 2 5
1 2 2
1 3 1
2 1 3
2 3 9
2 4 2
3 4 4
输出:
7

地址

代码

#include<stdio.h>

int main() {
	int m,n;
	while (scanf("%d %d",&m,&n) != EOF) {
		int i,j,k,x,y;
		int a[n+1][n+1];
		for (i = 0; i <= n; i++) 
			for (j = 0; j <= n; j++) 
				a[i][j] = 99; // 初始化二维数组为一个较大值 
		for (i = 0; i < m; i++) {
			scanf("%d%d",&x,&y);
			scanf("%d",&a[x][y]);
		}
		for (k = 0; k <= n; k++)
			for (i = 0; i <= n; i++) 
				for (j = 0; j <= n; j++) {
					a[i][j] = a[i][j] < (a[i][k] + a[k][j])?a[i][j]:(a[i][k] + a[k][j]);
 				}
 		printf("%d
",a[0][n]);
	}
	return 0;
}

解题思路

floyd算法,演示所有过程,求最小值。


四、走迷宫

题目

NowCoder最喜欢游乐场的迷宫游戏,他和小伙伴们比赛谁先走出迷宫。
现在把迷宫的地图给你,你能帮他算出最快走出迷宫需要多少步吗?

输入描述:

输入包含多组数据。

每组数据包含一个10*10,由“#”和“.”组成的迷宫。其中“#”代表墙;“.”代表通路。入口在第一行第二列;出口在最后一行第九列。从任意一个“.”点都能一步走到上下左右四个方向的“.”点。

输出描述:

对应每组数据,输出从入口到出口最短需要几步。

示例

输入图片说明

地址

代码

#include<stdio.h> 
struct note{
	int x;
	int y;
	int s;
};

int main() {
	struct note queue[1001];
	char a[11][12],book[11][12];
	int next[4][2] = {{1,0},{0,1},{-1,0},{0,-1}};
	
	int i,j;
	while (scanf("%c",&a[1][1]) != EOF) {
		for (i = 2; i <= 11; i++) {
			scanf("%c",&a[1][i]);
		}
		for (i = 2; i <= 10; i++) {
			for (j = 1; j <= 11; j++) { // 注意此处 j 的范围 
				scanf("%c",&a[i][j]);
				book[i][j] = '.';
			}
		}
		// 上面的内容为输入地图数据 
		
		int head = 1;
		int end = 1;
		queue[end].x = 1;
		queue[end].y = 2;
		queue[end].s = 0;
		end++;
		
		book[1][2] = '#';
		
		while (head < end) {
			for (i = 0; i < 4; i++) {
				int tx = queue[head].x + next[i][0];
				int ty = queue[head].y + next[i][1];
				if (tx < 1 || tx > 10 || ty < 1 || ty >10) {
					continue;
				}
					
				if (a[tx][ty] == '.' && book[tx][ty] == '.') {
					book [tx][ty] = '#';
					queue[end].x = tx;
					queue[end].y = ty;
					queue[end].s = queue[head].s + 1;
					end++;
				}
				
				if (tx == 10 && ty == 9) 
					goto end;
			}
			head++;
		}
		end:
			printf("%d
",queue[end - 1].s);
	} 
	return 0;
}

解题思路

bfs思想,用队列就可以。

注意:此题的地图为字符型构建,不同于整型,回车符也会被记录,所以要扩大数组范围。

附:人生目标

那个看我这周写这么多,以前的一笔勾销好不好,啦啦啦!

以上

原文地址:https://www.cnblogs.com/mxwbq/p/7353881.html