基本算法(7.30)

算法:

排序算法:

选择排序:

思想:数和下标结合,把一个数作为基准和他后面所有的数进行比较,根据比较结果和排序的大小方向来判断是否需要交换两个数的位置,并在合适的位置选择合适的数。

第一层循环的意思:一次定位一个位置,将这个位置的数和后面的每一个相数比较,如果满足后面的数比这个位置的数大(或小),则将这个数与相比的数互换位置。



***选择排序的实现代码:***
1 #include<stdio.h>                                                           
  2 int main(void)
  3 {
  4     int a[10] ={1,29,46,102,84,39,58,79,1,68};//初始化数组
  5     int temp,i,j,len;
  6 
  7     len = sizeof(a)/sizeof(a[1]);//确定数组长度
  8 
  9     for(i = 0; i < len;i++)//打印原数组
 10     {
 11         printf("%d ",a[i]);
 12     }
 13         printf("\n");
 14 
 15     for(i = 0;i < len-1;i++)//确定擂台(比较的左边)
 16     {
 17         for(j = i+1;j < len;j++)//要与之比较的数(比较的右边)
 18         {
 19             if(a[i] < a[j])
 20             {
 21                 temp = a[i];//装要被覆盖的值
 22                 a[i] = a[j];//将另一个值赋给要被被覆盖的值
23                 a[j] = temp;//将被覆盖的值赋给另一个值
 24             }
 25         }
 26     }
 27 
 28     for(i = 0; i < len;i++)
 29     {
 30         printf("%d ",a[i]);
 31     }
 32 
 33     printf("\n");
 34 
 35     return 0;
 36 }                                                       

流程图:
在这里插入图片描述

冒泡排序:

算法思想:
相邻元素进行两两比较,小的放在前大的放在后,将最大数像泡泡一样,一个一个冒出来。

算法思想的代码实现思路:
首先要确定比较的趟数,比较一趟就是其中两个两个数比较,然后一直比较到数组的最后一个数。
一趟可以找出最大的数将其固定位置,然后接下来下一趟需要比较的次数就可以少一次。因此比较的趟数会影响比较的次数。
由此思路可以构建两层循环。

两层循环的意义:
第一层循环:用来确定确定一个有序的数组需要冒泡几次。
第二层循环:用来确定数组中两个两个数需要进行几次比较,还需要注意他的比较次数会跟随趟数的增加而减少。
插入排序:

  1 #include<stdio.h>
  2 int main(void)
  3 {
  4     int a[10] ={1,29,46,102,84,39,58,79,1,68};//初始化数组
  5     int temp,i,j,len;
  6 
  7     len = sizeof(a)/sizeof(a[1]);//确定数组长度
  8 
  9     for(i = 0; i < len;i++)//打印原数组
 10     {
 11         printf("%d ",a[i]);
 12     }
 13         printf("\n");
 14 
 15     for(i = len-1; i > 0; --i)  //其需要进行的趟数就为数据长度减1,也可以理解为需要确定数组长度减1个位置的数
 16     {                                                                       
 17         for(j = 0; j < i;++j)//每一趟他需要两两比较的次数为 i 次
 18         {
 19             if(a[j] > a[j+1])//当后面的数小于前面的数则进行交换
 20             {
 21                 temp = a[j+1];
 22                 a[j+1] = a[j];
23                 a[j] = temp;
 24             }
 25         }
 26     }
 27 
 28 
 29     for(i = 0; i < len;i++)
 30     {
 31         printf("%d ",a[i]);
 32     }
 33 
 34     printf("\n");
 35 
 36     return 0;
 37 }                                            

流程图:
在这里插入图片描述

插入排序:

算法思想:在有序的数组之中,找到合适的位置并插入。
其插入的方式可分为:
原地插入,非原地插入

非原地插入:
1.创建两个数组,一个进行初始化(即需要对其进行排序的数组)。另一个数组全部初始化为0.
2.将第一个数组的数用循环一个一个拿出来。
3.在拿数据的循环之中,还要安排一个排序循环,即把拿出的数与之前放进空数组里排好序的数一个个比较,确定要把拿出来的这个数放在哪个位置。
4.但拿出来的数原默认位置为另一个数组的最后面,将其与前面一个个数据挨个比较,然后若拿出来的数比前面的小,则将这个数要放的位置前移,然后以此循环继续比较直至完全排序。


代码实现非原地插入:
  1 #include<stdio.h>                                                           
  2 int main(void)
  3 {
  4     int i,j,t;
  5     int a[5] = {4,8,2,6,9};//初始化要比较的数组
  6     int b[5] = {0};//定义排列后的数组
  7     for(i = 0;i < 5;i++)//循环把a数组里的数全部移动到b里去
  8     {
  9         j = i;//将a中i的位置和b中的j相对应,取数的位置的下标就是放在b中的初>
 10         t = a[i];//取出对应位置的数
 11         while(j > 0 && b[j-1] > t )//当拿出来的数和前一个数比较,发现前面一>
 12         {
 13             b[j] = b[j-1];//把前面的数往后挪
 14             --j;//并且把预计要放位置的下标往前调整
 15         }
 16         b[j] = t;//把拿出来的数放到确定好的位置上
 17     }
 18     for(i=0;i < 5;i++)
 19     {
 20     printf("%d",b[i]);
 21     }
 22     return 0;
 23 }         

流程图:
在这里插入图片描述


原地插入:
思路和非原地插入一样,但是操作是在同一个数组之中进行的,代码如下。


地代码插入实现方式:
 24     int i,j,t;
 25     int a[5] = {4,8,2,6,9};
 26     for(i = 0;i < 5;i++)
 27     {
 28         j = i;
 29         t = a[i];
 30         while(j > 0 && a[j-1] > t )
 31         {
 32             a[j] = a[j-1];
 33             --j;
 34         }
 35         a[j] = t;
 36     }
 37     for(i=0;i < 5;i++)
 38     {
 39     printf("%d ",a[i]);
 40     }
 41     return 0;
 42 }                                              

查找算法:

二分查找:

大前提:数据得是有序的
思路:每次先找到中间位置的数,然后将中间的数和目标数作比较,根据比较的大小情况折半整个数据,经历循环来实现查找目标数。


实现代码:1 #include<stdio.h>                                                           
  2 int main(void)
  3 {
  4     int begin = 0,end = 9,mid,tag;
  5     int a[10] ={1,2,3,4,5,6,7,8,9,10};
  6     scanf("%d",&tag);
  7     while(begin <= end)//从头到尾将数全部找一遍,当begin > end 时说明全部都>
  8     {
  9         mid = (begin+end)/2;//找中间位置
 10         if(tag > a[mid])//目标数比中间数大
 11         {
 12             begin = begin + 1;//将起始点放在中间数的下一个
 13         }
 14         else if( tag < a[mid])//目标数比中间数小
 15         {
 16             end = end - 1;//把结束点放在中间点前
 17         }
 18         else
 19         {
 20             break;//找到数之后退出循环
 21         }
 22     }
 23         if(begin <= end)//如果循环找到数了,则begin一定<=end
 24         {
 25             printf("找到数的位置在a[%d]",mid);//打印找到目标数字位置
 26         }
 27     return 0;
 28 }                             

流程图:
在这里插入图片描述

一维字符型数组:

对字符串的理解:

从字符数组的角度理解:
一维字符型数组的案例:

char s[20] = {'a','b','c','d'};

语义为:定义了一个叫s的元素类型为字符型的数组,其中给这个数组初始化了几个字符。


从字符串的角度来理解:

以字符串类型来定义字符数组:
   char a[10] = {"hello"};char a[10] = "hello";
//以上两种形式都是合法的

字符串的特点:

1.字符串是当做字符数组来处理的。
2.字符串有一个专门的结束标志'\0'
3.如果处理的数据是字符串,往往以结束标志位来作为操作依据。
4.如果处理的数据是字符数组,往往以字符数组的长度作为操作依据。
5.字符数组可以用于储存字符串,字符数组在内存中也是以字符数组的形式来储存的。因此字符数组和字符串本质上联系很大。

【补充】:'字符串' 以这种形式出现的是字符常量。

字符串和字符数组的分辨方式:

1.结束标志位是关键,如果一个字符数组手动在最后加上结束标志位,其就可看做是字符串。
其中利用部分初始化数组的特点:未初始化的部分是0这个特性也可以用来以字符数组的方式来构建字符串。
2.在代码中看是否有" ",其双引号内部是字符串。


相关输入输出函数:

1.
int puts(const char*s)
功能:输出一个字符串
参数: s  //表示字符串,指针类型
		 //字符数组名
		 //“hello”等字符常量
返回值:成功---非负数(无实际意义)
	   失败---返回-1

·······································································
代码的实例使用:
#include<stdio.h>
  2 int main(void)
  3 {
  4     char a[] = {"hello"};                                                   
  5     char a1[] ={'1','2','3','4','5',0};//手动加0,以字符数组的角度来表示字符
  6     //如果上述‘5’之后不加结束标志位置,其就会先输出字符a2接着输出a1字符,因>
  7     char a2[5] ={'1','2','3'};//部分初始化后面自带0
  8     puts(a1);
  9     return 0;
 10 }

注意:其也可以用来输出字符数组,只需要给定首地址,但是需要注意的是该函数只有检测到结束标志位才会停止输出字符,因此如果没有给字符数组结束标志位,那么他会连带输出该字符串相邻储存空间的字符数组或字符串。


2.
char *gets(char *s)
功能:从键盘获取一个字符串
参数:s   //代表一块储存空间,需要一个一堆数组的数组名
返回值:成功----返回该数组的首地址
	   失败---返回空指针NULL

注意:该函数及其强悍,凡是键盘输入的字符其都会将其存储在空间之中,不会顾及给定存储空间的大小,而且其还不会报错,因此需要特别注意。

  • 11
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值