【趣学C语言和数据结构100例】91-95

简介: 本文涵盖多个经典算法问题的C语言实现,包括堆排序、归并排序、从长整型变量中提取偶数位数、工人信息排序及无向图是否为树的判断。通过这些问题,读者可以深入了解排序算法、数据处理方法和图论基础知识,提升编程能力和算法理解。

【趣学C语言和数据结构100例】

问题描述

91.堆排序算法

92.归并排序

93.设计一个完整的 C 语言程序。要求完成以下功能:从低值开始取出长整型变量 s中偶数位上的数,依次构成一个新数放在t中。例如,当s中的数为 7654321 时,得到结果为 642.

94.实现计算:有 80 工人,每个工人包括的信息有:工号,名字,三个月的收入以及平均收入。用函数(1)完成工人信息的输入,并计算其平均收入。(2)用冒泡排序法排序工人平均收入。(3)完成工人信息的输出。

95.试设计一个算法,判断一个无向图 G是否为一棵树。若是一棵树,则算法返回 true,否则返回 false。

代码分析

==86.堆排序==
算法步骤:
1.建堆: 将输入数组构建成最大堆。这可以通过从数组的最后一个非叶子节点开始,自底向上地进行“向下调整”(heapify)操作来实现。向下调整操作确保每个节点都满足最大堆性质。
2.排序: 重复执行以下步骤,直到堆为空:
将堆顶元素(最大元素)与堆的最后一个元素交换。
将堆的大小减 1(因为最大元素已在正确的位置)。
对新的堆顶元素进行向下调整,以维护最大堆性质。

==87.归并排序==
归并排序是一种基于分治策略的排序算法。其基本思想是:
分治 (Divide): 将待排序的数组递归地分成两个子数组,直到每个子数组只包含一个元素(此时子数组已排序)。
合并 (Conquer): 将两个已排序的子数组合并成一个更大的已排序数组。 合并操作的关键在于比较两个子数组的第一个元素,将较小的元素放入新的数组中,然后继续比较下一个元素,直到所有元素都被合并到新的数组中。
递归 (Recurse): 重复步骤 1 和 2,直到所有子数组都被合并成一个完整的已排序数组。

==88.从低值开始取出长整型变量 s中偶数位上的数==
使用了一个 while 循环来迭代处理 s 中的每一位数字。 它通过取模运算 (% 10) 获取最后一位数字,然后通过除法运算 (/ 10) 去除最后一位数字。 它使用一个 multiplier 变量来正确地构建新数 t。 if 语句确保只处理偶数位数字。 temp 变量用于避免修改原始的 s 值。 代码还添加了对只有一位数和奇数位数情况的处理。

==89.冒泡排序==

==90.无向图 G是否为一棵树==
分析:
1.判断有没有环
2.广度优先搜索 从任意一个顶点开始BFS遍历图。 记录访问过的顶点数量Vnum和经过的边的数量Enum。 如果BFS遍历结束后,访问过的顶点数量等于图中顶点的总数,并且经过的边的数量等于顶点总数减一(因为树是一个没有环的连通图,边的数量总是顶点数减一),则图是一棵树。

代码实现

#include<stdio.h>
#define N 80
typedef struct worker{
   
    char num[10];
    char name[10];
    float money[3];
    float avg;
}worker;
worker wk[N];
void fun1(worker wk[]){
   
    float sum=0;
    for(int i=0;i<N;i++){
   
        scanf("%s %s %f %f %f",&wk[i].num,&wk[i].name,&wk[i].money[0],&wk[i].money[1],&wk[i].money[2]);
        wk[i].avg= (wk[i].money[0]+wk[i].money[1]+wk[i].money[2])/3.0;
        sum=0;
    }    
}

void fun2(worker wk[]){
   
    for(int i=0;i<N-1;i++){
   
        bool flag=false;
        for(int j=N-1;i<j;j--){
   
            if(wk[j].avg<wk[j-1].avg){
   
                int temp=wk[j].avg;
                wk[j].avg=wk[j-1].avg;
                wk[j-1].avg=wk[j].avg;
                flag=true;
            }
            if(flag==false){
   
                return;
            }
        }
    }    
}

void fun3(worker wk[]){
   
    for(int i=0;i<N;i++){
   
        printf("%s %s %f %f %f",wk[i].num,wk[i].name,wk[i].money[0],wk[i].money[1],wk[i].money[2],wk[i].avg);
    }    
}

int main(){
   
//    91.堆排序算法   完全二叉树  k  2k  2k+1 
void HeadAjust(int a[],int k,int len){
   
    a[0]=a[k];
    for(int i=2*k;i<len;i){
   
        if(a[i]<a[i+1] && i<len){
   
            i++;
        }
        if(a[0]>a[i]){
   
            break;
        }else{
   
            a[k]=a[i];
            k=i;
        }
    }
    a[k]=a[0];
}
void BridMaxheap(ElemType[],int len){
   
    for(int i=len/2;i>0;i--){
   
        HeadAjust(A,i,len)
    }
}

//    92.归并排序
void merge(int A,int low,int mid,int high){
   
    int *b=(int *)malloc((high-low+1)*sizeof(int));
    for(int k=low;k<=high;k++){
   
        b[k]=a[k];
    }
    for(int i=low,i=mid+1,k=low;i<=mid && j<=high;){
   
        if(b[i]<=b[j]){
   
            a[k++]=b[i++];
        }else{
   
            a[k++]=b[j++];
        }
    }
    while(i<=mid){
   
        a[k++]=b[i++];
    }
    while(j<=high){
   
        a[k++]=b[j++];
    }
}

//    93.设计一个完整的 C 语言程序。要求完成以下功能:从低值开始取出长整型变量 s中偶数位上的数,依次构成一个新数放在t中。例如,当s中的数为 7654321 时,得到结果为 642.
void fun(long s,long *t){
   
    s=s/10;
    *t=s%100;
    long s1=10while(s>=100){
   
        s=s/100;
        *t=s%10*s1+*t;
        s1=s1*10;
    }    
}

//    实现计算:94.有 80 工人,每个工人包括的信息有:工号,名字,三个月的收入以及平均收入。用函数(1)完成工人信息的输入,并计算其平均收入。(2)用冒泡排序法排序工人平均收入。(3)完成工人信息的输出。
fun1();
fun2();
fun3();

//    95.试设计一个算法,判断一个无向图 G是否为一棵树。若是一棵树,则算法返回 true,否则返回 false。
//1.判断有没有环
//2.广度优先搜索 从任意一个顶点开始BFS遍历图。 记录访问过的顶点数量Vnum和经过的边的数量Enum。  如果BFS遍历结束后,访问过的顶点数量等于图中顶点的总数,并且经过的边的数量等于顶点总数减一(因为树是一个没有环的连通图,边的数量总是顶点数减一),则图是一棵树。
bool istree(Graph G){
   
    bool visited[G.vexunm];
    for(int i=0;i<G.vexnum;i++){
   
        visited[i]=false;
    }
    int Vnum=0,Vnum=0;
    BFS(G,0,visited,Vnum,Enum);
    if(Vnum=G.vexnum && Enum=G.vexnum-1){
   
        return true;
    }else{
   
        return false;
    }
} 
BFS(Graph G,int u,bool visited,int &Vnum,int &Enum){
   
    Vnum++;
    visited[u]=true;
    Inqueue(Q);
    ENqueue(Q,u);
    while(!isEmpty(Q)){
   
        DeQueue(Q,u);
        for(int w=FirstNeihbor(Q,u);w>=0){
   
            w=NextNeihbor;
            if(!visited[w]){
   
                Vnum++;
                Enum++;
                visited[w]=true;
                Enqueue(Q,w);
            }
        }
    }
}

    return 0;
}

总结

本文介绍了几个经典的算法问题及其C语言实现,包括堆排序、归并排序、特定数字处理、工人信息排序和无向图是否为树的判断。这些问题覆盖了排序、数据处理和图论等多个领域,展示了算法和数据结构在解决实际问题中的应用。

堆排序是一种高效的比较类排序算法,其核心在于构建最大堆并进行反复的调整。通过将堆顶的最大元素与堆尾元素交换并缩小堆大小,可以实现高效的排序。堆排序的时间复杂度为O(nlogn),在处理大数据量时表现良好。

归并排序是一种分治算法,通过递归地将数组分成更小的子数组,然后合并这些子数组来实现排序。归并排序的时间复杂度同样为O(nlogn),且由于其稳定的排序特性,在实际应用中非常有效。

在处理特定数字的问题中,我们通过迭代和条件判断,从长整型变量中提取出偶数位上的数构成新数。这个问题虽然简单,但涉及到了位操作和循环控制,是基础算法训练的好例子。

工人信息排序问题涉及到结构体的使用和冒泡排序的实现。通过结构体存储工人信息,并使用冒泡排序算法根据平均收入对工人进行排序,展示了C语言在数据处理方面的能力。冒泡排序虽然时间复杂度为O(n^2),在数据量较大时效率不高,但其实现简单,适合教学和理解排序算法的基本概念。

最后,无向图是否为树的判断问题涉及到图论的基本概念。通过广度优先搜索(BFS)遍历图,并记录访问过的顶点数量和边的数量,可以判断图是否为一棵树。这个问题展示了图论算法在判断图结构方面的应用。

总的来说,这些算法问题不仅锻炼了编程能力,也加深了对算法和数据结构的理解。通过这些问题的解决,我们可以更好地理解算法的工作原理和适用场景,为解决更复杂的问题打下坚实的基础。这些算法的实现和分析,不仅提升了我们的问题解决能力,也让我们更加欣赏算法之美。通过这些练习,我们可以逐步提高自己的编程技能,为将来的学习和工作做好准备。

目录
相关文章
|
1月前
|
机器学习/深度学习 算法 C语言
【趣学C语言和数据结构100例】11-15
本文介绍了五个C语言编程问题及其实现,包括矩阵对角线元素之和、有序数组插入、数组逆序、杨辉三角输出和魔方阵生成。每个问题不仅涉及基本的数组操作,还涵盖了算法设计的核心思想,如循环、条件判断和递归。通过解决这些问题,读者可以加深对C语言和数据结构的理解,提升编程技能。这些问题的解决过程展示了如何有效处理数组和矩阵,以及如何利用算法优化程序性能,为实际应用提供了宝贵的实践经验。
56 4
【趣学C语言和数据结构100例】11-15
|
25天前
|
算法 数据处理 C语言
C语言中的位运算技巧,涵盖基本概念、应用场景、实用技巧及示例代码,并讨论了位运算的性能优势及其与其他数据结构和算法的结合
本文深入解析了C语言中的位运算技巧,涵盖基本概念、应用场景、实用技巧及示例代码,并讨论了位运算的性能优势及其与其他数据结构和算法的结合,旨在帮助读者掌握这一高效的数据处理方法。
38 1
|
1月前
|
存储 机器学习/深度学习 搜索推荐
【趣学C语言和数据结构100例】86-90
本文介绍并用C语言实现了五种经典排序算法:直接插入排序、折半插入排序、冒泡排序、快速排序和简单选择排序。每种算法都有其特点和适用场景,如直接插入排序适合小规模或基本有序的数据,快速排序则适用于大规模数据集,具有较高的效率。通过学习这些算法,读者可以加深对数据结构和算法设计的理解,提升解决实际问题的能力。
43 4
|
1月前
|
存储 算法 数据处理
【趣学C语言和数据结构100例】81-85
本文介绍了五个经典算法问题及其C语言实现,涵盖图论与树结构的基础知识。包括使用BFS求解单源最短路径、统计有向图中入度或出度为0的点数、统计无向无权图各顶点的度、折半查找及二叉排序树的查找。这些算法不仅理论意义重大,且在实际应用中极为广泛,有助于提升编程能力和数据结构理解。
40 4
|
1月前
|
算法 数据可视化 数据建模
【趣学C语言和数据结构100例】76-80
本文介绍了五种图论算法的C语言实现,涵盖二叉树的层次遍历及广度优先搜索(BFS)和深度优先搜索(DFS)的邻接表与邻接矩阵实现。层次遍历使用队列按层访问二叉树节点;BFS利用队列从源节点逐层遍历图节点,适用于最短路径等问题;DFS通过递归或栈深入图的分支,适合拓扑排序等场景。这些算法是数据结构和算法学习的基础,对提升编程能力和解决实际问题至关重要。
50 4
|
1月前
|
存储 算法 vr&ar
【趣学C语言和数据结构100例】71-75
本文介绍了五个C语言数据结构问题及其实现,涵盖链表与二叉树操作,包括按奇偶分解链表、交换二叉树左右子树、查找节点的双亲节点、计算二叉树深度及求最大关键值。通过递归和遍历等方法,解决了理论与实际应用中的常见问题,有助于提升编程能力和数据结构理解。
39 4
|
1月前
|
存储 算法 C语言
【趣学C语言和数据结构100例】66-70
本书《趣学C语言和数据结构100例》精选了5个典型的数据结构问题及C语言实现,涵盖链表与数组操作,如有序集合的集合运算、有序序列表的合并、数组中两顺序表位置互换、三递增序列公共元素查找及奇偶数重排。通过详细解析与代码示例,帮助读者深入理解数据结构与算法设计的核心思想,提升编程技能。
34 4
|
1月前
|
存储 算法 C语言
【趣学C语言和数据结构100例】51-55
本文介绍了五个关于链表操作的C语言实现案例,包括删除单链表中的重复元素、从两个有序链表中查找公共元素、判断一个链表是否为另一链表的连续子序列、判断循环双链表是否对称及合并两个循环单链表。每个案例都详细解析了算法思路与实现方法,涵盖了链表操作的多种场景,旨在帮助读者深入理解链表数据结构的应用,提升算法设计与编程能力。
40 4
|
1月前
|
存储 算法 C语言
【趣学C语言和数据结构100例】16-20
本文精选了五个C语言编程问题,涵盖数组操作、字符串处理等基础领域。包括查找二维数组中的鞍点、折半查找法、统计文章中字符数量、电文解密及字符串连接。每个问题都附有详细的代码实现与分析,旨在帮助读者理解算法逻辑,提升编程技巧。通过这些实践,不仅能锻炼编程能力,还能加深对数据结构和算法的理解,为未来的学习和工作打下坚实基础。
65 4
|
1月前
|
存储 算法 C语言
【趣学C语言和数据结构100例】26-30
本文精选五个编程问题,涵盖递归、数字处理、字符串操作、组合数学和数论等领域,通过C语言实现,旨在提升编程能力和算法理解。包括递归逆序打印字符、正整数位数及逆序打印、回文数判断、0-7组成奇数个数计算及偶数分解为两素数之和。
40 4
【趣学C语言和数据结构100例】26-30