数据结构习题19-26

目录

19、基于图的深度优先搜索策略(耿7.10) 

20、基于图的广度优先搜索策略(耿7.11)

21、逆波兰表达式(严7.38)

22、Dijkstra算法(严7.42)

23、构造哈希表(耿8.12)

24、二叉排序树的判别(耿8.6)

25、二叉排序树的插入和删除(严9.35、9.36和9.37)

26二叉排序树的合并(严9.38)


 

19、基于图的深度优先搜索策略(耿7.10) 

time_limit

3000MS

memory_limit

10000KB

description

试基于图的深度优先搜索策略编写程序,判别以邻接表方式存储的有向图中,是否存在由顶点vi到顶点vj的路径(i不等于j)。注意:程序中涉及的图的基本操作必须在此存储结构上实现。

input

第一行输入有向图的顶点数n和边数m,用空格隔开;第二行输入顶点信息;分m行输入有向图边的信息,例如顶点对1,2表示从顶点1到顶点2的一条弧。最后一行输入待判别的顶点对vi,vj.(0<m,n<100)

output

若有向图中存在由顶点vi到顶点vj的路径(i不等于j),则输出yes;否则输出no。

sample_input

4 4

1 2 3 4

1 2

1 3

1 4

2 3

2 3

sample_output

yes

 

#include <iostream>
#include <cstdio>
#include <cstdlib>

using namespace std;
#define Maxsize_vexter 20
#define Begined 1
#define Ended 0
typedef char VexType;
typedef int AdjType;

int flag = 0;
int isbegin = 0;
VexType v1, v2;

typedef struct node {
	int endvex;//相邻顶点的位置
	AdjType weight;//边的权重
	struct node* nextedge;
}Edgelist,*PEdgelist,Edgenode,*PEdgenode;

typedef struct {
	VexType vexter;
	PEdgelist list;
}VexNode;

typedef struct {
	VexNode vex[Maxsize_vexter];
	int vexNum, adjNum;
}Graph;

int Locate(Graph g, VexType v)
{
	int i;
	for (i = 0; g.vex[i].vexter != v;)
		i++;
	return i;
}

void CreateGraph(Graph &g)
{
	int i, j, k;
	char v11, v21;
	PEdgenode p;
	cin >> g.vexNum >> g.adjNum;
	for (i = 0; i < g.vexNum; i++) {
		cin >> g.vex[i].vexter;
		g.vex[i].list = NULL;
	}
	for (k = 0; k < g.adjNum; k++) {
		cin >> v11 >> v21;
		i = Locate(g, v11);
		j = Locate(g, v21);
		p = (PEdgenode)malloc(sizeof(Edgenode));
		p->endvex = j;
		p->nextedge = g.vex[i].list;
		g.vex[i].list = p;
	}
}

int FirstAdjVex(Graph &g, int v)
{
	if (g.vex[v].list == NULL)
		return -1;
	else
		return g.vex[v].list->endvex;
}

int NextAdjVex(Graph &g, int v, int w)
{
	int i;
	PEdgenode p;
	i = g.vex[v].list->endvex;
	for (p = g.vex[v].list; i != w; ) {
		p = p->nextedge;
		if (p == NULL)return -1;
		i = p->endvex;
	}
	p = p->nextedge;
	if (p)
		i = p->endvex;
	else
		return -1;
	return i;
}

void DFS(Graph &g, int *visited, int v)
{
	visited[v] = 1;
	if (g.vex[v].vexter == v1)isbegin = Begined;
	for (int w = FirstAdjVex(g, v); w >= 0; w = NextAdjVex(g, v, w)) {
		if (g.vex[w].vexter == v2 && isbegin == 1)
			flag = 1;
		if (!visited[w])
			DFS(g, visited, w);
	}
	if (g.vex[v].vexter == v1)isbegin = Ended;
}

void DFS_list(Graph &g)
{
	int visited[Maxsize_vexter];
	for (int i = 0; i < Maxsize_vexter; i++)
		visited[i] = 0;
	/*for (int i = 0; i < g.vexNum; i++)		
		if (!visited[i])
			DFS(g, visited, i);*/
	DFS(g, visited, Locate(g, v1));
}

/*void isIn(Graph &g)
{
	VexType v;
	cin >> v;
	PEdgenode p;
	int i;
	i = Locate(g, v);
	for (p = g.vex[i].list; p != NULL; p = p->nextedge) {

	}
}*/

int main()
{
	Graph g;
	CreateGraph(g);
	cin >> v1 >> v2;
	DFS_list(g);
	//isIn(g);
	flag == 0 ? cout << "no" : cout << "yes";
	cout << endl;
	return 0;
}

20、基于图的广度优先搜索策略(耿7.11)

time_limit

3000MS

memory_limit

10000KB

description

试基于图的广度优先搜索策略编写程序,判别以邻接表方式存储的有向图中,是否存在由顶点vi到顶点vj(i不等于j)。注意:程序中涉及的图的基本操作必须在此存储结构上实现。

input

第一行输入有向图的顶点数n和边数m,用空格隔开;第二行输入顶点信息;分m行输入有向图边的信息,例如顶点对1,2表示从顶点1到顶点2的一条弧。最后一行输入待判别的顶点对vi,vj。(0<m,n<100)

output

若有向图中存在由顶点vi到顶点vj的路径(i不等于j),则输出yes;否则输出no。

sample_input

4 4

1 2 3 4

1 2

1 3

1 4

2 3

2 3

sample_output

yes

#include <cstdio>
#include <cstdlib>
#include <string.h>
#include<iostream>
#define Initsize 20
using namespace std;
#define Maxsize_vexter 20
#define Begined 1
#define Ended 0
#define True 1
#define False 0
typedef char VexType;
typedef int AdjType;
typedef char Elemtype;

VexType v1, v2;
int flag = 0;
int isbegin = 0;

typedef struct {
	Elemtype *base;
	int Front;
	int rear;
	int length;
}Quene, *PQuene;

typedef struct node {
	int endvex;//相邻顶点的位置
	AdjType weight;//边的权重
	struct node* nextedge;
}Edgelist, *PEdgelist, Edgenode, *PEdgenode;

typedef struct {
	VexType vexter;
	PEdgelist list;
}VexNode;

typedef struct {
	VexNode vex[Maxsize_vexter];
	int vexNum, adjNum;
}Graph;

PQuene Init_quene()
{
	PQuene p;
	p = (PQuene)malloc(sizeof(Quene));
	p->base = (Elemtype *)malloc(sizeof(Elemtype)*Initsize);
	if (p == NULL) { printf("Error Init"); return p; }
	p->length = p->Front = 0;
	p->rear = 0;
	return p;
}

void enQuene(PQuene p, Elemtype x, int Size)
{
	if ((p->rear) % Size == p->Front&&p->length != 0) { printf("Error enQuene"); return; }  //if length==Size
	if (p->rear == -1)p->rear = 0;
	p->base[p->rear] = x;
	p->rear = (p->rear + 1) % Size;
	p->length++;
}

Elemtype deQuene(PQuene p, int Size)
{
	Elemtype x;
	x = p->base[p->Front];
	p->Front = (p->Front + 1) % Size;
	p->length--;
	return x;
}

int isfull(PQuene p, int Size)
{
	return (p->length == Size);
}

int isnull(PQuene p)
{
	return (p->length == 0);
}

int Locate(Graph g, VexType v)
{
	int i;
	for (i = 0; g.vex[i].vexter != v;)
		i++;
	return i;
}

void CreateGraph(Graph &g)
{
	int i, j, k;
	char v11, v21;
	PEdgenode p;
	cin >> g.vexNum >> g.adjNum;
	for (i = 0; i < g.vexNum; i++) {
		cin >> g.vex[i].vexter;
		g.vex[i].list = NULL;
	}
	for (k = 0; k < g.adjNum; k++) {
		cin >> v11 >> v21;
		i = Locate(g, v11);
		j = Locate(g, v21);
		p = (PEdgenode)malloc(sizeof(Edgenode));
		p->endvex = j;
		p->nextedge = g.vex[i].list;
		g.vex[i].list = p;
	}
}

int FirstAdjVex(Graph &g, int v)
{
	if (g.vex[v].list == NULL)
		return -1;
	else
		return g.vex[v].list->endvex;
}

int NextAdjVex(Graph &g, int v, int w)
{
	int i;
	PEdgenode p;
	i = g.vex[v].list->endvex;
	for (p = g.vex[v].list; i != w; ) {
		p = p->nextedge;
		if (p == NULL)return -1;
		i = p->endvex;
	}
	p = p->nextedge;
	if (p)
		i = p->endvex;
	else
		return -1;
	return i;
}

void BFS(Graph &g, int *visited, int v)
{
	PQuene p;
	VexType x;
	int pos;
	p = Init_quene();
	visited[v] = True;
	isbegin = Begined;
	enQuene(p, v1, Initsize);
	while (!isnull(p)) {
		x = deQuene(p, Initsize);
		pos = Locate(g, x);
		//if (x == v1)isbegin = Ended;
		for (int w = FirstAdjVex(g, pos); w >= 0; w = NextAdjVex(g, pos, w)) {
			if (!visited[w]) {
				visited[w] = True;
				if (isbegin == True && g.vex[w].vexter == v2)flag = 1;
				enQuene(p, g.vex[w].vexter, Initsize);
			}
		}
	}
}

void BFS_list(Graph &g)
{
	int visited[Maxsize_vexter];
	for (int i = 0; i < Maxsize_vexter; i++)
		visited[i] = 0;
	/*for (int i = 0; i < g.vexNum; i++)
	if (!visited[i])
	BFS(g, visited, i);*/
	BFS(g, visited, Locate(g, v1));
}

int main()
{
	Graph g;
	CreateGraph(g);
	cin >> v1 >> v2;
	BFS_list(g);
	flag == 0 ? cout << "no" : cout << "yes";
	cout << endl;
	return 0;
}

 

21、逆波兰表达式(严7.38)

time_limit

3000MS

memory_limit

10000KB

description

一个四则运算算术表达式以有向无环图的邻接表方式存储,每个操作数原子都由单个字母表示。编写程序输出其逆波兰表达式。

input

输入四则运算算术表达式。

output

输出其逆波兰表达式。

sample_input

(a+b)*c

sample_output

ab+c*

暂无

22、Dijkstra算法(严7.42)

time_limit

3000MS

memory_limit

10000KB

description

编写程序,实现以邻接表作存储结构,求从源点到其余各顶点的最短路径的Dijkstra算法。

input

第一行输入顶点数n和边数m;第二行输入顶点信息;分m行输入m对顶点vi,vj(表示由顶点vi到顶点vj(i不等于j)的边)以及该弧的权值。(0<m,n<100)

output

输出从源点到其余各顶点的最短路径(不可达用-1表示)。

sample_input

6 11

1 2 50

1 3 10

1 5 45

2 3 15

2 5 10

3 1 20

3 4 15

4 2 20

4 5 35

5 4 30

6 4 3

sample_output

1 3 10

1 4 25

1 2 45

1 5 45

1 6 -1

 

#include <iostream>
#include <cstdio>
#include <cstdlib>

using namespace std;
#define INFINITY 10000
#define Vexsize 100
#define True 1
#define False 0
typedef int VexType;

typedef struct {
	int weight;
}ArcCell,AdjMatrix[Vexsize][Vexsize];

typedef struct {
	AdjMatrix arcs;
	int vexnum, arcnum;
	VexType vexs[Vexsize];
}Graph;

void Init_Graph(Graph &g)
{
	int j, k, w;
	cin >> g.vexnum >> g.arcnum;
	for (int i = 0; i < g.vexnum; i++)
		g.vexs[i] = i + 1;
	for (int i = 0; i < g.vexnum; i++)
		for (int j = 0; j < g.vexnum; j++)
			g.arcs[i][j].weight = INFINITY;
	for (int i = 0; i < g.arcnum; i++) {
		cin >> j >> k >> w;
		g.arcs[j - 1][k - 1].weight = w;
	}
}

int ShortestPath_DIJ(Graph &g, VexType v0, int p[Vexsize][Vexsize], int d[Vexsize])
{
	int f[Vexsize];
	for (int v = 0; v < g.arcnum; v++) {
		f[v] = False;
		d[v] = g.arcs[v0][v].weight;
		for (int w = 0; w < g.vexnum; w++)
			p[v][w] = False;
		if (g.arcs[v0][v].weight != INFINITY)
			p[v][v0] = True, p[v][v] = True;
	}
	d[v0] = 0;
	f[v0] = True;
	for (int v = 1; v < g.vexnum; v++) {
		int min = INFINITY;
		int i;
		for (int w = 0; w < g.vexnum; w++)
			if (!f[w])
				if (d[w] < min)i = w, min = d[w];
		f[i] = True;

		if (min == INFINITY) {
			//cout << v0 + 1 << " " << i + 1 << " " << -1 << endl;
			for(int k=0;k<g.vexnum;k++)
				if(!f[k])
					cout << v0 + 1 << " " << k + 1 << " " << -1 << endl;
			return 0;
		}
		else
			cout << v0 + 1 << " " << i + 1 << " " << min << endl;

		for (int w = 0; w < g.vexnum; w++) {
			if (!f[w] && d[w] > min + g.arcs[i][w].weight) {
				d[w] = min + g.arcs[i][w].weight;
				for (int j = 0; j < g.vexnum; j++)
					p[i][j] = p[w][j];
				p[w][w] = True;
			}
		}
	}
}

int main()
{
	Graph g;
	int p[Vexsize][Vexsize], d[Vexsize];
	Init_Graph(g);
	ShortestPath_DIJ(g, 0, p, d);
	return 0;
}

23、构造哈希表(耿8.12)

time_limit

3000MS

memory_limit

10000KB

description

选取哈希函数H(k)=(3k)%11,用线性探测再散列法处理冲突。试在0-10的散列地址空间中,编写程序,对关键字序列 (22,41,53 46,30,13,01,67)构造哈希表,并求等概率情况下查找成功的平均查找长度。

input

output

输出等概率情况下查找成功的平均查找长度。

sample_input

sample_output

2

#include<stdio.h>
#include<iostream>
#include<stdlib.h>
#define SIZE_Haxi 11
using namespace std;
int num = 0;
int a[8] = { 22,41,53,46,30,13,01,67 };
typedef struct Haxi {
	int data;
	bool flag;
}Haxi;
void createHaxi(Haxi*L) {
	int j = 0, jj;
	while (1) {
		for (int i = 0; ; i++) {
			jj = (3 * a[j] + i) % (SIZE_Haxi);
			if (L[jj].flag == false) {
				L[jj].data = a[j];
				L[jj].flag = true;
				j++;
				break;
			}
		}
		if (j == 8)break;
	}
}
void caculate(Haxi *L) {
	int ii, jj;
	for (int i = 0; i < 8; i++) {
		for (ii = 0;; ii++) {
			jj = (3 * a[i] + ii) % (SIZE_Haxi);
			num++;
			if (L[jj].data == a[i])break;
		}
	}
}
int main() {
	Haxi T[SIZE_Haxi];
	for (int i = 0; i < SIZE_Haxi; i++) {
		T[i].flag = false;
	}
	createHaxi(T);
	caculate(T);
	cout << num / 8;
	//system("pause");
	return 0;
}

 

24、二叉排序树的判别(耿8.6)

time_limit

3000MS

memory_limit

10000KB

description

试编写程序,判别给定的二叉树是否为二叉排序树。设此二叉树以二叉链表作存储结构,且树中结点的关键字均不同。

input

按先序输入二叉树各结点(结点值大于0),其中-1表示取消建立子树结点。

output

若该二叉树为二叉排序树,则输出yes;否则,输出no。

sample_input

12 8 4 -1 -1 10 -1 -1 16 13 -1 -1 18 -1 -1

sample_output

yes

#include <cstdio>
#include <cstdlib>
#include <iostream>
using namespace std;
typedef int DataType;

int last = 0, flag = 1;

typedef struct node{
	DataType data;
	struct node *lchild, *rchild;
}BitNode,*PBitNode;

void initBitree(PBitNode &T) {
	int a;
	cin >> a;
	if (a == -1)T = NULL;
	else {
		T = (PBitNode)malloc(sizeof(BitNode));
		T->data = a;
		initBitree(T->lchild);
		initBitree(T->rchild);
	}
}

void judge(PBitNode T) {
	/*if (T->lchild&&flag)judge(T->lchild);
	if (T->data < last)flag = 0;
	last = T->data;
	if (T->rchild&&flag)judge(T->rchild);*/
	if (T&&flag) {
		judge(T->lchild);
		if (T->data < last)flag = 0;
		last = T->data;
		judge(T->rchild);
	}
}

int main() {
	PBitNode T;
	initBitree(T);
	judge(T);
	flag == 1 ? cout << "yes" : cout << "no";
	cout << endl;
	return 0;
}

25、二叉排序树的插入和删除(严9.35、9.36和9.37)

time_limit

3000MS

memory_limit

10000KB

description

假设二叉排序树以后继线索链表作存储结构,编写程序,满足以下要求:

  1. 输出该二叉排序树中所有大于a小于b的关键字;
  2. 在二叉排序树中插入一个关键字;
  3. 在二叉排序树中删除一个关键字。

input

第一行按先序输入二叉排序树各结点(结点值大于0),其中-1表示取消建立子树结点;第二行输入要求1中a、b,用空格隔开;第三行输入要求2中要插入的关键字;第四行输入要求3中要删除的关键字。

output

按照中序序列,分三行输出要求1、要求2和要求3的结果。

sample_input

12 8 4 -1 -1 10 -1 -1 16 13 -1 -1 18 -1 -1

10 17

6

12

sample_output

12 13 16

4 6 8 10 12 13 16 18

4 8 10 13 16 18

#include <cstdio>
#include <cstdlib>
#include <iostream>
using namespace std;

typedef int DataType;
typedef struct node{
	DataType data;
	struct node *lchild, *rchild;
}BitNode,*PBitNode,BiTree,*PBiTree;

void init_bitree(PBiTree &T) {
	DataType x;
	cin >> x;
	if (x == -1)T = NULL;
	else {
		T = (PBitNode)malloc(sizeof(BitNode));
		T->data = x;
		init_bitree(T->lchild);
		init_bitree(T->rchild);
	}
}

void traverse_conditional(const PBiTree T, const DataType v0, const DataType v1) {
	if (T) {
		traverse_conditional(T->lchild, v0, v1);
		if (T->data > v0&&T->data < v1)cout << T->data << " ";
		traverse_conditional(T->rchild, v0, v1);
	}
}

void traverse(const PBiTree T) {
	if (T) {
		traverse(T->lchild);
		cout << T->data << " ";
		traverse(T->rchild);
	}
}

int searchBST(PBiTree T, DataType key, PBitNode f, PBitNode &p) {
	if (!T) { p = f; return 0; }
	else if (T->data == key) { p = T; return 1; }
	else if (T->data < key)searchBST(T->rchild, key, T, p);
	else searchBST(T->lchild, key, T, p);
}

int InsertBST(PBiTree &T, DataType key) {
	PBitNode p = NULL, s;
	if (!searchBST(T, key, NULL, p)) {
		s = (PBitNode)malloc(sizeof(BitNode));
		s->data = key;
		s->lchild = s->rchild = NULL;
		if (!p)T = p;
		else if (key < p->data) p->lchild = s;
		else p->rchild = s;
		return 1;
	}
	else
		return 0;
}

int Delete(PBiTree &p) {
	PBitNode q, s;
	if (!p->rchild) {
		q = p;
		p = p->lchild;
		delete(q);
	}
	else if (!p->lchild) {
		q = p;
		p = p->rchild;
		delete(q);
	}
	else {
		q = p;
		s = p->lchild;
		while (s->rchild) {
			q = s;
			s = s->rchild;
		}
		p->data = s->data;
		if (q != p)q->rchild = s->lchild;
		else q->lchild = s->lchild;
		delete(s);
	}
	return 1;
}

int DeleteBST(PBiTree &T, DataType key) {
	if (!T)return 0;
	else {
		if (T->data == key) return Delete(T);
		else if (T->data < key) return DeleteBST(T->rchild, key);
		else return DeleteBST(T->lchild, key);
	}
}

int main()
{
	DataType v0, v1, v2, v3;
	PBiTree T;
	init_bitree(T);
	cin >> v0 >> v1 >> v2 >> v3;
	traverse_conditional(T, v0, v1);
	cout << endl;
	if (!InsertBST(T, v2))cout << "Error" << endl;
	traverse(T);
	cout << endl;
	DeleteBST(T, v2);
	DeleteBST(T, v3);
	traverse(T);
	cout << endl;
	return 0;
}

 

26二叉排序树的合并(严9.38)

time_limit

3000MS

memory_limit

10000KB

description

试编写程序,将两棵二叉排序树合并为一棵二叉排序树。

input

按照先序序列,分两行输入两棵二叉排序树各结点(结点值大于0),其中-1表示取消建立子树结点。

output

按照中序序列输出合并后的二叉排序树。

sample_input

12 8 4 -1 -1 10 -1 -1 16 13 -1 -1 18 -1 -1

17 6 2 -1 -1 9 -1 -1 24 19 -1 -1 26 -1 -1

sample_output

2 4 6 8 9 10 12 13 16 17 18 19 24 26

#include <cstdio>
#include <cstdlib>
#include <iostream>
using namespace std;
typedef struct node {
	int data;
	struct node *rchild, *lchild;
}BitNode,*PBitNode,*PBST;

void init_BST(PBST &T) {
	int x;
	cin >> x;
	if (x == -1)T = NULL;
	else {
		T = new BitNode;
		T->data = x;
		init_BST(T->lchild);
		init_BST(T->rchild);
	}
}

int searchBST(PBST T, int key, PBitNode f, PBitNode &p) {
	if (!T) { p = f; return 0; }
	else if (T->data == key) { p = T; return 1; }
	else if (T->data < key)searchBST(T->rchild, key, T, p);
	else searchBST(T->lchild, key, T, p);
}

int Insert(PBST &T, int key) {
	PBitNode p = NULL, s;
	if (!searchBST(T, key, NULL, p)) {
		s = (PBitNode)malloc(sizeof(BitNode));
		s->data = key;
		s->lchild = s->rchild = NULL;
		if (!p)T = p;
		else if (key < p->data) p->lchild = s;
		else p->rchild = s;
		return 1;
	}
	else
		return 0;
}

void InsertBST(PBST &T1, PBST T2) {
	if (T2) {
		InsertBST(T1, T2->lchild);
		Insert(T1, T2->data);
		InsertBST(T1, T2->rchild);
	}
}

void traverse(PBST T) {
	if (T) {
		traverse(T->lchild);
		cout << T->data << " ";
		traverse(T->rchild);
	}
}

int main() {
	PBST T1, T2;
	init_BST(T1);
	init_BST(T2);
	InsertBST(T1, T2);
	traverse(T1);
	return 0;
}

/*void InsertBST(BTree *T,int key)//向二叉排序树中插入单个关键字key
{
    while((*T)!=NULL)
    {
        if((*T)->data>key)   T=&(*T)->lchild;
        else if((*T)->data<key) T=&(*T)->rchild;
    }

    (*T)=new BTNode;
    (*T)->lchild=NULL;
    (*T)->rchild=NULL;
    (*T)->data=key;
}*/

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值