2023(848):
1.设计一数据结构,用来表示图的邻接矩阵存储结构(包括弧的结构和图的结构)。
#define MAXV 100
typedef int InfoType; // 顶点的信息类型,可以根据实际情况定义(权重)
typedef int VertexType; // 顶点的类型,可以根据实际情况定义
// 弧的结构
typedef struct ArcNode {
int adj; // 1表示有弧,0表示无弧
InfoType info; // 弧的相关信息,可以根据实际情况定义
} ArcNode;
// 图的结构
typedef struct MGraph {
AdjMatrix [MAXV][MAXV]; // 邻接矩阵
VertexType vexs[MAXV]; // 顶点信息
int vexnum, arcnum; // 顶点数和弧数
} MGraph;
2.假设二叉树采用二叉链表存储结构,试编写一个非递归算法,输出中序遍历序列中第k个结点的数据值。
// 定义树的结构
typedef struct BitNode {
Elemtype data; // 树的数据
struct BitNode *lchild;
struct BitNode *rchild; // 左子树,右子树
} Bitree;
// 定义函数中序遍历树函数并输出所查元素k的数值
void Inorder(Bitree &T, int k) { // k是key关键字对比
Bitree *p = T; // 定义p指针指向头结点
Stack S; //定义一个栈
InitStack(S); //初始化栈
int count = 0;
while (p || !IsEmpty(S)) {
if (p) { // 如果指针p非空
Push(S, p);
p = p->lchild;
}
if (Gettop(S, &p)) {
count++;
if (count == k) {
printf("%c\n", p->data);
return;
}
Pop(&S, &p);
p = p->rchild;
}
}
// 添加return语句以确保函数正常结束
return;
}
3.试编写一个算法,在链式存储结构上实现直接插入排序算法。
typedef struct LNode{
int data; //链表数据
struct LNode *next;//指向下一个数据指针
}LNode;
void insertsort(LNode *L){
LNode *p,*q,*pre;//定义指针,q用来保存p的值,pre用来指向已经排好序的第一个数值
p=L->next->next;// 将p移动到无序链表第一个数值
L->next->next=null; 将链表有序化
while(p!=null){
q=p->next;//初始化q
pre=L;//初始化pre
while(pre->next!=null&&pre->next->data<=p->data){
//当有序链表头结点下一个值非空且小于无序链表第一个数值
pre=pre->next;
p->next=pre->next;
pre->next=p;
p=q;
}
}
}
4.若矩阵Am*n中的某个元素aij是第i行中的最小值,同时又是第j列中的最大值,则称此元素为该矩阵中的一个马鞍点。假设二维数组存储矩阵Am*n,试编写求出矩阵中所有马鞍点的算法。
void MaAnDian(int A [][],int m,int n){
int i,j,k;
int flag1 , flag2;
for(i=0,i<m,i++){
for(j=0,j<n,j++){
flag 1=1;
flag 2=1;
for(k=0;k<n;k++){
if(A[i][j]>A[i][k]){
flag 1=0
}
for(k=0;k<m;k++){
if((A[i][j]<A[k][j]){
flag 2=0
}
if(flag1&&flag2){
printf("行号:%d 列号:%d\n",i,j,A[i][j]);
}
}
}
}
2022(848):
1.假设二叉树采用二叉链表存储,试写出中序遍历二叉树的非递归算法,要求:先描述二叉树的数据类型。
// 定义树的结构
typedef struct BitNode {
Elemtype data; // 树的数据
struct BitNode *lchild;
struct BitNode *rchild; // 左子树,右子树
} Bitree;
// 定义函数中序遍历树函数并输出所查元素k的数值
void Inorder(Bitree &T) {
Bitree *p = T; // 定义p指针指向头结点
Stack S; //定义一个栈
InitStack(S); //初始化栈
while (p!=null || !IsEmpty(S)) {
if (p) { // 如果指针p非空
Push(S, p);
p = p->lchild;
}esle{
Pop(&S, &p);
p = p->rchild;
}
}
// 添加return语句以确保函数正常结束
return;
}
2.编写实现栈的两个基本运算的函数:入栈和出栈(要求采用顺序存储结构)。
struct Stack {
int data[MAXSIZE];
int top; // 栈顶指针
};
// 初始化栈
void initializeStack(struct Stack *s) {
s->top = -1; // 初始时栈顶指针设为-1表示空栈
}
// 入栈操作
void push(struct Stack *s, int x) {
if (s->top == MAXSIZE - 1) {
printf("Stack overflow\n");
return;
}
s->data[++(s->top)] = x;
}
// 出栈操作
int pop(struct Stack *s) {
if (s->top == -1) {
printf("Stack underflow\n");
return -1; // 表示栈为空
}
return s->data[(s->top)--];
}
3.假设无向图G采用邻接表存储,编写程序,判断图G是否是连通图。如果是连通图返回1,否则返回0。要求先给出算法思想,再写出相应代码。
#define MAXV 100 // 定义最大顶点数为100
// 定义邻接节点的数据结构
struct AdjNode {
int vertex; // 顶点
AdjNode* next; // 指向下一个邻接节点的指针
};
// 定义图的数据结构
struct Graph {
AdjNode* adjList[MAXV]; // 邻接表,数组中的每个元素都是一个链表的头节点
int nvertices; // 图中的顶点数
int visited[MAXV]; // 访问标记数组,如果某个顶点被访问过,相应的元素值为1,否则为0
};
// 深度优先搜索函数
void dfs(Graph* g, int v) {
g->visited[v] = 1; // 标记顶点v已被访问
AdjNode* p = g->adjList[v]; // 获取顶点v的邻接链表的头节点
while (p != NULL) { // 遍历顶点v的所有邻接节点
if (g->visited[p->vertex] == 0) { // 如果邻接节点未被访问过
dfs(g, p->vertex); // 对邻接节点进行深度优先搜索
}
p = p->next; // 移动到下一个邻接节点
}
}
// 判断图是否连通的函数
int isConnected(Graph* g) {
for (int i = 0; i < g->nvertices; i++) { // 初始化所有顶点为未访问状态
g->visited[i] = 0;
}
dfs(g, 0); // 从顶点0开始进行深度优先搜索
for (int i = 0; i < g->nvertices; i++) { // 检查所有顶点是否都被访问过
if (g->visited[i] == 0) { // 如果有未被访问过的顶点
return 0; // 返回0,表示图不连通
}
}
return 1; // 所有顶点都被访问过,返回1,表示图连通
}
2021(848):
1.设树的存储结构为孩子兄弟链表,试编写算法,输出树中所有从根到叶子的路径。
//孩子兄弟链表法储存结构定义
typedef struct TreeNode {
int data;
TreeNode* firstChild;
TreeNode* nextSibling;
}TreeNode;
//定义一个函数用于输出节点路径
void printPaths(TreeNode* root, int path[], int pathLength) {
if (root == NULL) {
return;
}
// 将当前节点的数据添加到路径中
path[pathLength] = root->data;
pathLength++;
// 如果是叶子节点,打印路径
if (root->firstChild == NULL) {
printf("Path: ");
for (int i = 0; i < pathLength; i++) {
printf("%d ", path[i]);
}
printf("\n");
} else {
// 递归处理孩子节点
printPaths(root->firstChild, path, pathLength);
}
// 递归处理下一个兄弟节点
printPaths(root->nextSibling, path, pathLength);
}
2.设一个带头结点的单链表L,数据元素为整数,其中大部分为正数,少数为负数,编写函数,实现将负数结点移到链表尾部,并返回调整后链表中第一个负数结点的位置。要求先给出算法思想,再写出相应算法。
//定义单链表结构体
typedef struct LNode {
int data;
LNode* next;
}LNode,*ListNode; //定义指针*ListNode指向单链表。后续可以直接用ListNode来使用struct LNode
//定义一个函数,这个函数接受一个指向链表的指针作为参数(通常是头结点A),然后返回一个指向链表节点的指针
LNode* Sortlist(ListNode A){
//定义指针p,指针tail,指针minus,指针s
LNode *p, *tail = A, *minus = NULL,*s = NULL;
if(!A) { //判断指向A的指针是否为空
return NULL; //符合则返回NULL,不符合则执行下行代码
}
p = A->next; //移动p指针指向头节点下一个节点
while(p) {
tail->next = p;
s = p; //把p指针赋值给s指针(s暂时指向p节点)
p = p->next;
s->next = minus;
if(s->data >= 0) {//非负数,移动tail指针
tail = s;
} else {//负数
minus = s;
}
}
return minus;
}
2020(848):
1.试编写一个算法完成下面的功能:对于输入的任意一个非负十进制整数,输出与其等值的八进制数。
void decimal_to_octal(int decimal_number) {
// 存储八进制数的数组
int octal_number[100];
int i = 0;
// 将十进制数转换为八进制
while (decimal_number > 0) {
octal_number[i] = decimal_number % 8;
decimal_number /= 8;
i++;
}
// 输出八进制表示
printf("八进制表示: ");
for (int j = i - 1; j >= 0; j--) {
printf("%d", octal_number[j]);
}
printf("\n");
}
2.试编写一个算法,在有向图G中,判定从顶点Vi到顶点Vj是否有通路。
#define MAX_VERTICES 100 //宏定义最大数量
bool visited[MAX_VERTICES];
// 邻接矩阵表示有向图
int graph[MAX_VERTICES][MAX_VERTICES];
int numVertices;
// 深度优先搜索函数
bool DFS(int start, int end) {
if (start == end) {
return true; // 找到通路
}
visited[start] = true;
for (int i = 0; i < numVertices; ++i) {
if (graph[start][i] == 1 && !visited[i]) {
if (DFS(i, end)) {
return true; // 在邻接顶点中找到通路
}
}
}
return false; // 没有找到通路
}