《算法分析与设计》练习5

本文详细介绍了使用C语言实现冒泡排序、二分查找、随机数生成以及整数奇偶排序的方法。针对不同排序需求,如有序序列的查找和无序序列的排序,给出了相应的代码实现,并通过示例输入和输出展示了算法的正确性。此外,还讨论了如何在快速排序的基础上实现随机化排序,以提高算法的效率和避免最坏情况的发生。
摘要由CSDN通过智能技术生成

目录

A 冒泡排序

B 用二分法试试

C 随机数

D 整数奇偶排序

E 快速排序

F 随机化快速排序


A 冒泡排序

题目描述

从键盘上输入10个整数,用冒泡法对这10个数进行排序(由小到大)。【必须使用冒泡排序实现】

输入

以空格分隔的10个整数

输出

依次输出排好序的10个整数,每个数占一行。

样例输入 Copy

1 3 5 7 9 2 4 6 8 0

样例输出 Copy

0

1

2

3

4

5

6

7

8

9

分析:题目都说了是冒泡排序,这应该手写代码,就是两两之间比较 ,如果比我大,就换位置

代码分析:c语言

#include <stdio.h>

#include <stdlib.h>



int main (){

int a[10];

for(int i=0;i<10;i++)

    scanf("%d",&a[i]);

sort(a);

for(int i=0;i<10;i++)

    printf("%d\n",a[i]);

return 0;

}



void sort(int a[]){

for(int i=1;i<=9;i++)

    for(int j=0;j<10-i;j++)

{

    if(a[j]>a[j+1])

        swap(a,j+1,j);

}

}

void swap(int a[],int i,int j){

int temp=a[i];

a[i]=a[j];

a[j]=temp;

}

B 用二分法试试

题目描述

请编写一个程序,输入包含n(n<=100000)个整数的数列S以及包含q个(q<=50000)不重复整数的数列T,输出既包含于T也包含于S的整数的个数C。S、T中的元素均大于0且小于109。S的元素按升序排列,T的元素不重复。

输入

第一行输入n,第二行输入代表S的n个整数,第三行输入q,第四行输入代表T的q个整数。

输出

用1行输出C。

样例输入 Copy

5

1 2 3 4 5

3

3 4 1

分析:如果要用二分法,必定有序,果然 S 有序

就是在之前学过的二分法基础上,寻找key的值变成了一个T序列而已,就是说T序列的所有数均是key

所以我们先把之前学过的二分法写出来,然后再在主函数里,一个一个key值判断即可;    

代码实现:c语言

#include <stdio.h>

#include <stdlib.h>



int main (){

int a[200000];

int b[200000];

int al;

int bl;



while(~scanf("%d",&al)){

        int count=0;

    for(int i=0;i<al;i++)

        scanf("%d",&a[i]);

        scanf("%d",&bl);

    for(int i=0;i<bl;i++)

        scanf("%d",&b[i]);

    for(int i=0;i<bl;i++)

    {

        int z=digui(a,0,al-1,b[i]);

        if(z!=-1)

            count++;

    }

printf("%d",count);

printf("\n");



}





return 0;

}



int digui (int a[],int low,int high,int key){

    if(low<=high){

          int mid =(low+high)/2;

          if(a[mid]==key) return mid+1;

          else{

            if(a[mid]>key) return digui(a,low,mid-1,key);

            if(a[mid]<key) return digui(a,mid+1,high,key);



          }

    }



    return -1;

}

C 随机数

题目描述

有一个rand(n)的函数,它的作用是产生一个在[0,n)的随机整数。现在有另外一个函数,它的代码如下:

int random(int n, int m)

{

         return rand(n)+m;

}

显而易见的是函数random(n,m)可以产生任意范围的随机数。现在问题来了,如果我想要产生范围在[a,b)内的一个随机数,那么对应的n,m分别为多少?

输入

输入的第一行为一个正整数T (T<=1000),表示一共有T组测试数据。

对于每组测试数据包含两个整数a,b (a<=b)。

输出

对于每组测试数据,输出一行包含两个整数n和m,两个整数中间有一个空格分隔。

样例输入 Copy

2

0 5

1 4

样例输出 Copy

5 0

3 1

分析:这个题,给大家一个公式吧 ,if  我们要取一个在  【a,b】之间的数(闭区间)

那么就是 x=rand()%(b-a+1)+a。   其中% 很重要,他主要是控制 【0,某个数】的区间

然后这一题就很简单了,就是n=b-a     ,     m=a

代码实现:c语言

#include <stdio.h>

#include <stdlib.h>



int main (){

int a;

int b;

int n;

int m;

int t;

scanf("%d",&t);

    for(int i=0;i<t;i++)

{



        scanf("%d %d",&a,&b);

    n=b-a;

    m=a;

    printf("%d %d",n,m);

    printf("\n");



}



return 0;

}

D 整数奇偶排序

题目描述

输入10个整数,彼此以空格分隔。重新排序以后输出(也按空格分隔),要求:

1.先输出其中的奇数,并按从大到小排列;

2.然后输出其中的偶数,并按从小到大排列。

输入

任意排序的10个整数(0~100),彼此以空格分隔。

输出

可能有多组测试数据,对于每组数据,按照要求排序后输出,由空格分隔。

样例输入 Copy

0 56 19 81 59 48 35 90 83 75

17 86 71 51 30 1 9 36 14 16

样例输出 Copy

83 81 75 59 35 19 0 48 56 90

71 51 17 9 1 14 16 30 36 86

分析:这个题乍一看,还是思路比较清晰滴,首先把一个数列分为奇数列和偶数列

 然后对其分别排序输出即可

代码实现:c语言

#include <stdio.h>

#include <stdlib.h>



int main (){

int a[10];



while(~scanf("%d",&a[0])){

    for(int i=1;i<10;i++)

    scanf("%d",&a[i]);



   int j[10];

   int o[10];

   int x=0;

   int y=0;

for(int i=0;i<10;i++)

{

    if(a[i]%2==1)

    {

        j[x]=a[i];

        x++;

    }

    else{

        o[y]=a[i];

        y++;

    }

}

jsort(j,x);

osort(o,y);

for(int i=0;i<x;i++)

    printf("%d ",j[i]);



for(int i=0;i<y;i++)

    printf("%d ",o[i]);

    printf("\n");

}



return 0;

}





void jsort(int b[],int bl){

for(int i=1;i<bl;i++)

    for(int j=0;j<bl-i;j++)

    if(b[j]<b[j+1])

          swap(b,j,j+1);

}







void osort(int b[],int bl){

for(int i=1;i<bl;i++)

    for(int j=0;j<bl-i;j++)

    if(b[j]>b[j+1])

          swap(b,j,j+1);

}



void swap(int a[],int i,int j)

{

    int temp=a[i];

    a[i]=a[j];

    a[j]=temp;

}

E 快速排序

题目描述

编程实现快速排序算法,深入理解快速排序算法的基本思想。

输入

多组输入,每组第一个数字为数组长度,然后输入一个一维整型数组。

输出

输出快速排序之后的一维整型数组(升序)

样例输入 Copy

6 1 8 6 5 3 4

5 12 42 2 5 8

样例输出 Copy

1 3 4 5 6 8

2 5 8 12 42

分析:没什么好讲的,就是快排,请快速写代码

其实就是先分区,再排序,排序里面嵌套分区方法和排序....

请看我直接记事本手写代码:

代码实现:c语言

#include <stdio.h>

#include <stdlib.h>



int main (){

int a[200];

int al;

while(~scanf("%d",&al)){

    for(int i=0;i<al;i++)

        scanf("%d",&a[i]);

    sort(a,0,al-1);

    for(int i=0;i<al;i++)

        printf("%d ",a[i]);

    printf("\n");

}







return 0;

}



int patition(int a[],int p,int q){

int i=p,j;

int x=a[p];

for(j=p+1;j<=q;j++)

{

    if(x>a[j])

    {

        i++;

        swap(a,i,j);

    }

}

swap(a,i,p);

return i;



}



void sort(int a[],int p,int q){

if(p<q) {

    int r=patition(a,p,q);

    sort(a,p,r-1);

    sort(a,r+1,q);

}



}



void swap(int a[],int i,int j){

int temp=a[i];

a[i]=a[j];

a[j]=temp;



}

F 随机化快速排序

题目描述

使用Java或C++等语言中内置的随机函数实现随机化快速排序,在数组中随机选择一个元素作为分区的主元(Pivot)。

输入

多组样例输入,每组由一个一维整型数组组成。

输出

随机化快速排序之后的一维整型数组(升序排列)。

样例输入 Copy

6 1 8 6 5 3 4

5 12 42 2 5 8

样例输出 Copy

1 3 4 5 6 8

2 5 8 12 42

分析:就是在快排的基础上,使刚开始的 i 值 为这一数列的任意一个下标,也就是随机化下标。

嘿嘿嘿,然后我们就把该下标的数与第一个数交换,再次使 i 为 p即可。看(标记2)

代码实现:c语言


 

#include <stdio.h>

#include <stdlib.h>

#include <math.h>

int main (){

int a[200];

int al;

while(~scanf("%d",&al)){

    for(int i=0;i<al;i++)

        scanf("%d",&a[i]);

    sort(a,0,al-1);

    for(int i=0;i<al;i++)

        printf("%d ",a[i]);

    printf("\n");

}







return 0;

}



int patition(int a[],int p,int q){

int i=rand()%(q-p+1)+p;   //  (标记2)

swap(a,i,p);          // (标记2)

i=p;                 //    (标记2)

int j;

int x=a[p];

for(j=p+1;j<=q;j++)

{

    if(x>a[j])

    {

        i++;

        swap(a,i,j);

    }

}

swap(a,i,p);

return i;



}



void sort(int a[],int p,int q){

if(p<q) {

    int r=patition(a,p,q);

    sort(a,p,r-1);

    sort(a,r+1,q);

}



}



void swap(int a[],int i,int j){

int temp=a[i];

a[i]=a[j];

a[j]=temp;



}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值