目录
25、二叉排序树的插入和删除(严9.35、9.36和9.37)
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 | 假设二叉排序树以后继线索链表作存储结构,编写程序,满足以下要求:
|
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;
}*/