C语言:数组与函数实践

任务代码:

【项目1-有序数组中插入数据(函数版)】
  有一个足够“大”的数组a,其中已经存储了n个呈升序排列的数据。调用函数insert(a, n, m),可以将数m插入到a中的合适位置,使其仍然保持升序,并且返回值为数组中有效数字的个数(即原先的n加1)。

#include <stdio.h>
#define N 100

int insert(int a[],int n,int m)
{
    int loc,j;
    //找到要插入位置的下标
    for(loc=0;loc<n;loc++)
    {
        if(a[loc]>m)
        {
            break;
        }
    }
    //数据后移
    for(j=n;j>loc;j--)
    {
        a[j]=a[j-1];
    }
    //插入数据
    a[j]=m;
    
    n++;
    return n;
}

int main()
{
    int a[N]= {1, 7, 8, 17, 23, 24, 59, 62, 101};
    int i, n=9;
    int m =50;
    n = insert(a, n, m);   //在长度为n的a数组中插入m,使仍保持有序
    for(i=0; i<n; ++i)
        printf("%d ", a[i]);
    printf("\n");
    return 0;
}

方法2:

#include <stdio.h>
#define N 100
int insert(int [], int, int);
int main()
{
    int a[N]= {1, 7, 8, 17, 23, 24, 59, 62, 101};
    int i, n=9;
    int m =50;
    n = insert(a, n, m);   //在长度为n的a数组中插入m,使仍保持有序
    for(i=0; i<n; ++i)
        printf("%d ", a[i]);
    printf("\n");
    return 0;
}
int insert(int d[], int n, int m)
{
    int i = n-1;
    while(i>=0&&d[i]>m )  //把大数往后“搬”,腾出位置保存n
    {
        d[i+1] = d[i];
        i--;
    }
    i++;
    d[i] = m;   //找到了确定的位置赋值
    n++;
    return n;   //返回值为数组中新的有效数据的个数
}

【项目2 - 删除数组元素】
del函数的作用是删除数组a中的指定元素x,n为数组a的元素个数。函数的返回值,为删除元素后的有效元素个数(数组中可能有重复元素)。函数的原型为:
int del (int a[10],int n,int x)
(1)请实现这个函数,并完成测试。
(2)如果在函数调用时,要求数组中的元素呈升序排列呢?

(1)

#include <stdio.h>
#define N 100

int del(int a[],int n,int x)
{
    //设置两个数组
    int p=0,q=0;//用p和q两个变量
    while(q<n)//由q控制,扫描所有的元素
    {
        if(a[q]!=x)
        {
            a[p]=a[q];//只有当元素值不等于x才往p标识的位置上“搬”
            p++;
        }
        q++;
    } //最后的效果,等于x的元素都没有“搬”过来,它们被“覆盖”了,也即被删除了
    return p;//p代表的,就是删除后的元素个数
}

int main()
{
    int i,n;
    int a[20]={86,76,62,58,77,85,92,80,96,88,77,67,80,68,78,87,64,59,61,76};//含有重复数字的数组
    int key;
    printf("数组中的原来元素为:\n");
    for(i=0;i<20;i++)
    {
        printf("%d ",a[i]);
    }
    printf("\n");
    
    printf("请输入你想删除的数据:");
    scanf("%d",&key);
    
    //删除数据
    n=del(a, 20, key);
    
    //打剩余的数组:
    printf("删除数据后的数组为:\n");
    for(i=0;i<n;i++)
    {
        printf("%d ",a[i]);
    }
    
    //返回值
    printf("\n");
    printf("数组的有效数字有:%d 个\n",n);
    return 0;
}

(2)

#include <stdio.h>
#define N 100

int del(int a[],int n,int x)
{
    //设置两个数组
    int p=0,q=0;//用p和q两个变量
    while(q<n)//由q控制,扫描所有的元素
    {
        if(a[q]!=x)
        {
            a[p]=a[q];//只有当元素值不等于x才往p标识的位置上“搬”
            p++;
        }
        q++;
    } //最后的效果,等于x的元素都没有“搬”过来,它们被“覆盖”了,也即被删除了
    return p;//p代表的,就是删除后的元素个数
}

void select_sort(int a[],int n)
{
    int i,j,t,k;
    for(i=0;i<n-1;i++)//n个数进行n-1轮的比较
    {
        //
        k=i;
        for(j=i+1;j<n;j++)
        {
            if(a[j]<a[k])
            {
                k=j;
            }
        }
        //
        t=a[k];
        a[k]=a[i];
        a[i]=t;
    }
    return;
}

int main()
{
    int i,n;
    int a[20]={86,76,62,58,77,85,92,80,96,88,77,67,80,68,78,87,64,59,61,76};//含有重复数字的数组
    int key;
    printf("数组中的原来元素为:\n");
    for(i=0;i<20;i++)
    {
        printf("%d ",a[i]);
    }
    printf("\n");
    
    printf("请输入你想删除的数据:");
    scanf("%d",&key);
    
    //删除数据
    n=del(a, 20, key);
    
    //选择排序升序排列数组
    select_sort(a,n);
    
    //打剩余的数组:
    printf("删除数据后的数组为:\n");
    for(i=0;i<n;i++)
    {
        printf("%d ",a[i]);
    }
    
    //返回值
    printf("\n");
    printf("数组的有效数字有:%d 个\n",n);
    return 0;
}


【项目3 - 数组的排序】
(1)编写函数,完成冒泡排序
要求不能改变下面的main函数。

//两个函数bubble_sort和output_array的声明  
int main( )
{
    int a[20]={86,76,62,58,77,85,92,80,96,88,77,67,80,68,88,87,64,59,61,76};
    int b[15]={27,61,49,88,4,20,28,31,42,62,64,14,88,27,73};
    bubble_sort(a,20);   //用冒泡法按降序排序a中元素
    output_array(a,20);   //输出排序后的数组
    bubble_sort(b,15);   //用冒泡法按降序排序b中元素
    output_array(b,15);   //输出排序后的数组
    return 0;
}
//请在下面定义bubble_sort和output_array函数


#include <stdio.h>

void bubble_sort(int a[],int);
void output_array(int a[],int);


//两个函数bubble_sort和output_array的声明

int main( )
{
    int a[20]={86,76,62,58,77,85,92,80,96,88,77,67,80,68,88,87,64,59,61,76};
    int b[15]={27,61,49,88,4,20,28,31,42,62,64,14,88,27,73};
    bubble_sort(a,20);   //用冒泡法按降序排序a中元素
    output_array(a,20);   //输出排序后的数组
    bubble_sort(b,15);   //用冒泡法按降序排序b中元素
    output_array(b,15);   //输出排序后的数组
    return 0;
}
//请在下面定义bubble_sort和output_array函数

void bubble_sort(int a[],int n)
{
    int i,j,t;
    for(i=0;i<n-1;i++)
    {
        for(j=0;j<n-i-1;j++)
        {
            if(a[j+1]<a[j])
            {
                t=a[j+1];
                a[j+1]=a[j];
                a[j]=t;
            }
        }
    }
    return;
}

void output_array(int a[],int n)
{
    printf("排序后的数组为:\n");
    int i;
    for(i=0;i<n;i++)
    {
        printf("%d ",a[i]);
    }
    printf("\n");
    return;
}


(2)字符数组排序:改造(1)的程序,使其能对字符数组进行排序,其中:
int a[20]={...};
int b[15]={...};
改为
char a[20] = {'s','o','r','t','b','u','b','b','l','e','s','e','l','e','c','t','o','k','o','k'};
char b[15] = {'a','b','a',...};  //自己补足

#include <stdio.h>

void bubble_sort(char a[],int);
void output_array(char a[],int);


//两个函数bubble_sort和output_array的声明

int main( )
{
    char a[20] = {'s','o','r','t','b','u','b','b','l','e','s','e','l','e','c','t','o','k','o','k'};
    char b[15] = {'a','b','a','f','c','d','l','q','p','d','x','l','w','o','s'};  //自己补足
    bubble_sort(a,20);   //用冒泡法按降序排序a中元素
    output_array(a,20);   //输出排序后的数组
    bubble_sort(b,15);   //用冒泡法按降序排序b中元素
    output_array(b,15);   //输出排序后的数组
    return 0;
}
//请在下面定义bubble_sort和output_array函数

void bubble_sort(char a[],int n)
{
    int i,j,t;
    for(i=0;i<n-1;i++)
    {
        for(j=0;j<n-i-1;j++)
        {
            if(a[j+1]<a[j])
            {
                t=a[j+1];
                a[j+1]=a[j];
                a[j]=t;
            }
        }
    }
    return;
}

void output_array(char a[],int n)
{
    printf("排序后的数组为:\n");
    int i;
    for(i=0;i<n;i++)
    {
        printf("%c ",a[i]);
    }
    printf("\n");
    return;
}

(3)体验选择排序:改造(1)的程序,将bubble_sort(...)改为select_sort(...),排序算法由冒泡排序换作为选择排序,排序结果由降序变为升序,完成类似的任务。


#include <stdio.h>

void select_sort(int a[],int);
void output_array(int a[],int);


//两个函数select_sort和output_array的声明

int main( )
{
    int a[20]={86,76,62,58,77,85,92,80,96,88,77,67,80,68,88,87,64,59,61,76};
    int b[15]={27,61,49,88,4,20,28,31,42,62,64,14,88,27,73};
    select_sort(a,20);   //用冒泡法按降序排序a中元素
    output_array(a,20);   //输出排序后的数组
    select_sort(b,15);   //用冒泡法按降序排序b中元素
    output_array(b,15);   //输出排序后的数组
    return 0;
}
//请在下面定义select_sort和output_array函数

void select_sort(int a[],int n)
{
    int i,j,k,t;
    for(i=0;i<n-1;i++)
    {
        //
        k=i;
        for(j=i+1;j<n;j++)
        {
            if(a[j]<a[k])
               {
                   k=j;
               }
        }
        //
        t=a[k];
        a[k]=a[i];
        a[i]=t;
    }
}

void output_array(int a[],int n)
{
    printf("排序后的数组为:\n");
    int i;
    for(i=0;i<n;i++)
    {
        printf("%d ",a[i]);
    }
    printf("\n");
    return;
}



【项目4 - 查成绩】
(1) score1.txt 提供了某大学两个班某次测验的数据,包括每位同学的学号及成绩。
请编程序,输入学号,查找出该同学的成绩。
提示1:可以定义两个int型数组,其中一个n存放学号,另一个s存放成绩,可以保证两个数组中,元素下标相同,对应的是同一位同学。例如n[18]值为3123,s[18]为98,说明学号为3123的同学成绩为98。
提示2:因为数据无序,运用顺序查找算法,在n数组中依据学号进行查找,在s数组中对应下标的值则为其成绩。例如,通过在n中的查找,得出学号为3123的同学的下标为18,则其成绩为s[18]。
下面是完成应用的部分代码,已经能够输出成绩清单。请在此基础上实现有关的函数:

//
//  main.c
//  test
//
//  Created by 张子蔚 on 2017/8/31.
//  Copyright © 2017年 张子蔚. All rights reserved.
//

#include <stdio.h>
#include <stdlib.h>

int readData(int [],int []);
int search(int [],int,int);

int main(int argc, const char * argv[]) {
    // insert code here...
        int num[200], score[200];  //分别保存学号和成绩
        int count;  //代表学生人数
        int index;  //代表查找到的学生的下标
        int key;
        count = readData(num, score);   //将成绩数据从文件中读到数组中
        printf("请输入要查找的学生学号:");
        scanf("%d",&key);
        index = search(num, count, key);  //在count个学生中查找学号为key的学生对应的下标
        if(index<0)    //输入的学号不存在时,index的值要求返回-1
            printf("不存在学号为%d的同学\n",key);
        else
            printf("学号为%d的同学的成绩是:%d\n", key, score[index]);
        return 0;  
}


int readData(int n[],int s[])
{
    int count=0;
    FILE *fp;
    fp=fopen("/Users/zhangziwei/Desktop/score1.txt","r");//打开文件以读的 读的形式
    if(fp==NULL)
    {
        printf("file cannot open!");
        exit(0);
    }
    //读取文件
    while(fscanf(fp,"%d%d",&n[count],&s[count])!=EOF)//直到读完
    {
        count++;
    }
    //关闭文件指针
    fclose(fp);
    return count;
}

int search(int n[],int count,int key)
{
    int i;
    int index=-1;
    //顺序查找
    for(i=0;i<count;i++)
    {
        if(n[i]==key)
        {
            index=i;
            break;
        }
    }
    return index;
}


(2)在实际工程中,为了让频繁执行的查询更快一些,常要求对数据进行排序,再进行查询。请改造程序:①在调用readData(num, score);读入数据后,立即调用自定义函数sort对两个数组进行排序(注意在排序需要交换时,应该同时交换两个数组中对应的值,以保证同一下标,对应的是同一个学生的学号和成绩);②这样,search函数可以实现为二分查找了;③改造main函数,支持多次的查找。

#include <stdio.h>
#include <stdlib.h>

int readData(int [],int []);
int search(int [],int,int);
void sort(int [],int [],int);
void press();//任意键输出

int main(){
    // insert code here...
        int num[200], score[200];  //分别保存学号和成绩
        int count;  //代表学生人数
        int index;  //代表查找到的学生的下标
        int key;
    
        while(1)
        {
         count = readData(num, score);   //将成绩数据从文件中读到数组中
         printf("请输入要查找的学生学号:");
         scanf("%d",&key);
         index = search(num, count, key);  //在count个学生中查找学号为key的学生对应的下标
         if(index<0)    //输入的学号不存在时,index的值要求返回-1
            printf("不存在学号为%d的同学\n",key);
         else
            printf("学号为%d的同学的成绩是:%d\n", key, score[index]);
         //回显
         press();
        }
        return 0;
}

void press()
{
    printf("按任意键继续!\n");
    getchar();
    getchar();
}

int readData(int n[],int s[])
{
    int count=0;
    FILE *fp;
    fp=fopen("/Users/zhangziwei/Desktop/score1.txt","r");//打开文件以读的 读的形式
    if(fp==NULL)
    {
        printf("file cannot open!");
        exit(0);
    }
    //读取文件
    while(fscanf(fp,"%d%d",&n[count],&s[count])!=EOF)//直到读完
    {
        count++;
    }
    
    //进行排序(!!因为search中mid使用在学号中,所以要对学号排序!!!)
    sort(n,s,count);
    
    //关闭文件指针
    fclose(fp);
    return count;
}

int search(int n[],int count,int key)
{
    //二分查找
    int low,high,mid;
    int index=-1;
    low=0;
    high=count-1;
    
    while(low<=high)//不要用mid!=0,因为mid没有初始化一开始,报错风险
    {
      mid=(low+high)/2;
        
      if(n[mid]==key)
      {
        index=mid;
        break;
      }
      else if(n[mid]>key)
      {
         high=mid-1;
      }
      else
      {
         low=mid+1;
      }
    }
    return index;
}


void sort(int n[],int s[],int c)
{
    int i,j,t;
    //冒泡排序法
    for(i=0;i<c-1;i++)
    {
        for(j=0;j<c-i-1;j++)
        {
            if(n[j]>n[j+1])
            {
                //学号交换
                t=n[j+1];
                n[j+1]=n[j];
                n[j]=t;
                //成绩随学号交换
                t=s[j+1];
                s[j+1]=s[j];
                s[j]=t;
            }
        }
    }
}

/*选择排序

void sort(int n[],int s[],int c)

{

    int k,i,j,t;

    //选择排序

    for(i=0;i<c-1;i++)

    {

        k=i;

        for(j=i+1;j<c;j++)

        {

            if(n[j]<n[k])

            {

                k=j;

            }

        }

        //学号交换

        t=n[i];

        n[i]=n[k];

        n[k]=t;

        //成绩交换

        t=s[i];

        s[i]=s[k];

        s[k]=t;

    }

*/




执行情况:

项目1 :


项目2 :

(1)


(2)



项目3:

(1)


(2)



项目4:

(1)


(2)



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值