848数据结构算法

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; // 没有找到通路
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值