數據結構習題19-26

title

基於圖的深度優先搜索策略(耿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;
}

 

title

基於圖的廣度優先搜索策略(耿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;
}

 

 

title

逆波蘭表達式(嚴7.38)

time_limit

3000MS

memory_limit

10000KB

description

一個四則運算算術表達式以有向無環圖的鄰接表方式存儲,每個操作數原子都由單個字母表示。編寫程序輸出其逆波蘭表達式。

input

輸入四則運算算術表達式。

output

輸出其逆波蘭表達式。

sample_input

(a+b)*c

sample_output

ab+c*

暫無

 

title

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;
}

 

title

構造哈希表(耿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;
}

 

 

title

二叉排序樹的判別(耿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;
}

 

title

二叉排序樹的插入和刪除(嚴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;
}

 

 

title

二叉排序樹的合併(嚴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;
}*/

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章