考研需要吧,虽然挺基础的,但是还是要练习下的,而且,还可以帮助一些其他同样需要这些代码的朋友。
实现最基础的数据结构建议是用C语言,这样子很多细节都可以很好地把握,当然,如果用STL可以简单地实现,那么我也会实现一下。
第一题
题目
编一C程序,它能根据读入的数据构造有向图
G
,并输出G
的邻接矩阵和邻接表及G
的拓扑序列。图的输入形式为 i 0    j 0    i 1    j 1    i 2    j 2    . . .    i m    j m    − 1    − 1 i_0 \; j_0 \; i_1 \; j_1 \; i_2 \; j_2\; ...\; i_m\; j_m \; -1 \; -1 i0j0i1j1i2j2...imjm−1−1(-1,-1
为有向边输入结束标记,其余的值都>= 0
且< n
。), 它们都是整数,n
是有向图G
的顶点个数且40 > n > 0
,顶点名字依次是 V 0 , V 1 , V 2 , …    V n − 1 V_0,V_1,V_2,…\; V_{n-1} V0,V1,V2,…Vn−1; i k    j k i_k \; j_k ikjk表示向图G的有向边 < V i k , V j k > <V_{i_k},V_{j_k}> <Vik,Vjk>。
解析
邻接矩阵和邻接表是图论中的基础,那么在代码中如何表示,这是一个基础;
拓扑序列牵扯到拓扑排序,这个还是要了解下的。
C语言
#define MAX_SIZE 50
int buff[MAX_SIZE << 1];
int adjacencyMatrix[MAX_SIZE][MAX_SIZE];
int head[MAX_SIZE];
typedef struct
{
int to, next;
} Edge;
int n, m;
Edge edges[MAX_SIZE * MAX_SIZE];
void GetAdjacencyMatrix(int m)
{
int i;
memset(adjacencyMatrix, 0, sizeof(adjacencyMatrix));
for (i = 0; i < 2 * m; i += 2) {
adjacencyMatrix[buff[i]][buff[i + 1]] = 1;
}
}
void GetAdjacencyTable(int m)
{
int i;
memset(head, -1, sizeof(head));
for (i = 0; i < 2 * m ; i += 2) {
edges[i] = {buff[i + 1], head[buff[i]]};
head[buff[i]] = i >> 1;
}
}
void PrintAdjacencyMatrix(int n)
{
int i, j;
for (i = 0; i < n; ++i)
for (j = 0; j < n; j++)
printf("%d%c", adjacencyMatrix[i][j], " \n"[j + 1 == n]);
puts("");
}
void PrintAdjacencyTable(int n)
{
int i, j;
for (i = 0; i < n; ++i) {
printf("%d : ", i);
for (j = head[i]; j + 1; j = edges[j].next)
printf("%d%c", edges[j].to, " \n"[edges[j].next + 1 == 0]);
}
puts("");
}
int in[MAX_SIZE];
// using adjacency matrix
int TopologicalSort(int n)
{
int res[MAX_SIZE], used[MAX_SIZE];
int index = 0;
int i, j;
memset(in, 0, sizeof(in));
memset(used, 0, sizeof(used));
for (i = 0; i < n; ++i)
for (j = 0; j < n; ++j)
in[j] += adjacencyMatrix[i][j];
do {
for (i = 0; i < n; ++i)
if (!in[i] && !used[i])
break;
if (i == n)
return -1;
used[i] = 1;
res[index++] = i;
for (j = 0; j < n; ++j)
in[j] -= adjacencyMatrix[i][j];
} while (index != n);
for (i = 0; i < n; printf("%d%c", res[i], " \n"[i + 1 == n]), ++i) {}
return 0;
}
int main()
{
int i;
int x, y;
scanf("%d", &n);
for (m = 0, i = 0; scanf("%d%d", &x, &y) && x + 1 && y + 1; ++m, i += 2)
buff[i] = x, buff[i + 1] = y;
GetAdjacencyMatrix(m);
GetAdjacencyTable(m);
PrintAdjacencyMatrix(n);
PrintAdjacencyTable(n);
TopologicalSort(n);
return 0;
}
C++
C++的std::vector
可以很容易实现邻接表,这个可以实现下
std::vector<int> head[MAX_SIZE];
void GetAdjacencyTable(int m)
{
for (int i = 0; i < m; ++i)
head[buff[i]].push_back(buff[i + 1]);
}
第二题
题目
编一C程序,它能读入两组整数(每组整数都以
-9999
为结束标记,个数都不大于1000
),并以从小到大的次序输出既在第一组整数中也在第二组整数中的所有整数(同一个整数不能输出两次)。(输入时,两个相邻的整数用空格隔开)。
解析
C语言
#define MAX_SIZE 1000
#define END -9999
int n, m;
int arrayN[MAX_SIZE], arrayM[MAX_SIZE];
int res[MAX_SIZE], index;
int cmp(const void *a, const void *b)
{
return *(const int *)a - *(const int *)b;
}
void GetAns()
{
int p1, p2;
qsort(arrayN, n, sizeof(arrayN[0]), cmp);
qsort(arrayM, m, sizeof(arrayM[0]), cmp);
for (p1 = p2 = index = 0; p1 < n && p2 < m; ) {
if (arrayN[p1] == arrayM[p2])
res[index++] = arrayN[p1], ++p1, ++p2;
else
arrayN[p1] < arrayM[p2] ? ++p1 : ++p2;
}
}
int main()
{
int x, i;
for (n = 0; scanf("%d", &x) && x != END; arrayN[n++] = x) {}
for (m = 0; scanf("%d", &x) && x != END; arrayM[m++] = x) {}
GetAns();
for (i = 0; i < index; printf("%d%c", res[i], " \n"[i + 1 == index]), ++i);
return 0;
}
C++
C++的sort
比C语言中的qsort
好用;
这种类似求交集的运算,STL中提供了std::set_intersection
,具体参考图解STL中算法的分类、简介及其Demo
#include <bits/stdc++.h>
#define END -9999
std::vector<int> arrayN, arrayM, res;
void GetAns()
{
std::sort(arrayN.begin(), arrayN.end());
std::sort(arrayM.begin(), arrayM.end());
std::set_intersection(arrayN.begin(), arrayN.end(),
arrayM.begin(), arrayM.end(),
std::back_inserter(res));
}
int main()
{
for (int x; std::cin >> x && x != END; arrayN.push_back(x)) {}
for (int x; std::cin >> x && x != END; arrayM.push_back(x)) {}
GetAns();
for (auto it = res.begin(); it != res.end();
std::cout << *it << " \n"[it + 1 == res.end()], ++it) {}
return 0;
}