ref与out的区别、冒泡排序、普通排序,以及二分法查询
一、首先我们先讲一下ref与out的区别和使用方法;
1、ref与out的区别:
out:需要在使用前声明变量,分配地址但不能赋值,但是需要在使用中的时候需要初始化(进入方法体中的时候需要先赋值在使用),至于为什么要在方法体中使用,我个人认为是为了区别ref;(即只出不进)
ref:需要在使用前声明且初始化,分配地址并且赋值,这样做可以根据初始化的值带入,可以根据传入的值进行一些逻辑判断;(即有进有出,有头有尾)
共同点:都需要先声明变量,且都有回传值。
2、使用方法:
首先我们先看看两者使用方法:首先我们先创建两个方法一个用out一个用ref,回传一个int值
private static int[] bubbleSort(int[] sources,out int count)
{
int temp;
count = 0;
for (int i = 0; i < sources.Length; i++)
{
for (int j = i + 1; j < sources.Length; j++)
{
if (sources[j] < sources[i])
{
temp = sources[j];
sources[j] = sources[i];
sources[i] = temp;
}
count++;
}
}
return sources;
}
private static int[] bubbleSort2(int[] sources, ref int count)
{
int i, j, temp;
for (j = 0; j < sources.Length; j++)
{
for (i = 0; i < sources.Length - 1; i++)
{
if (sources[i] > sources[i + 1])
{
temp = sources[i];
sources[i] = sources[i + 1];
sources[i + 1] = temp;
} count++;
}
}
return sources;
}
标黄的就是我们用到的out,ref,在两个方法体中就可以发现不一样之处,out方法里的count这个参数进入后就有初始化值,然后在后面才能使用,而下面用ref的方法体中我们没有发现count的初始化,就可以直接使用,那么两者在调用的区别就在于调用的时候了,下面就是方法调用的时候:
static void Main(string[] args)
{
int[] array = new[] { 1223, 918, 234, 765, 974, 867, 86786, 145432, 867633, 9999999 }; // 目标数组
int findValue = 145432; // 被查找数
//二分法结果
Console.WriteLine(BinarySearch(array, findValue, 0, array.Length - 1) ? "被查找数存在数组array中" : "被查找数不存在数组array中");
//冒泡排序
int count;
int[] intlist = bubbleSort(array, out count); for (int i = 0; i < intlist.Length; i++)
{
Console.Write(intlist[i]+" "); } Console.WriteLine("\t"+"循环次数为:"+count); //类似冒泡排序,单循环次数较多
int count2 = 0;
int[] intlist2 = bubbleSort2(array, ref count2);
for (int i = 0; i < intlist2.Length; i++)
{
Console.Write(intlist2[i] + " "); } Console.WriteLine("\t" + "循环次数为:" + count2);
Console.ReadKey();
}
先只看有深色背景颜色的地方,因为在之前我闷在方法体中看见out在方法体中已经有初始化动作,而ref没有,那么再调用之前ref就需要先初始化,out就不需要初始化!
这里我们在扩展一下,我们知道return也是可以返回值,那么return的返回值和上述两者有什么区别呢?
首先我们之前说了,out和ref,只要在参数值前面注明out或者ref,那么咱们的返回值可以实现多个,但是用return的话只能是返回一个唯一值,这是最大的区别!
并且return的返回值是直接不可修改的,但是out和ref是可以修改的!
二、接下来我们就看看最常见的排序算法
1、(普通排序)首先,我们还是借用上述代码,
首先我们先创建一个数组,同样的 调用我们写好的方法,
/// <summary>
/// 非冒泡排序
/// </summary>
/// <param name="sources">目标数组</param>
/// <param name="count">循环次数</param>
/// <returns>升序排列结果</returns>
private static int[] bubbleSort2(int[] sources, ref int count)
{
int i, j, temp;
for (j = 0; j < sources.Length; j++)
{
for (i = 0; i < sources.Length - 1; i++)
{
if (sources[i] < sources[i + 1])
{
temp = sources[i];
sources[i] = sources[i + 1];
sources[i + 1] = temp;
} count++;
}
}
return sources;
}
此代码有内外循环,外循环是增加循环次数,内循环是则是主循环,若当前值sources[i]与下一个值对比,如果满足条件那么就将此值记录下来,这里面他会将所有的都循环一遍,才结束!
2、(冒泡排序)
1 /// <summary>
2 /// 冒泡排序
3 /// </summary>
4 /// <param name="sources">目标数组</param>
5 /// <param name="count">循环次数</param>
6 /// <returns>升序排列结果</returns>
7 private static int[] bubbleSort(int[] sources,out int count)
8 {
9 int temp; count = 0;
10 for (int i = 0; i < sources.Length; i++)
11 {
12 for (int j = i + 1; j < sources.Length; j++)
13 {
14 if (sources[j] > sources[i])
15 {
16 temp = sources[j];
17 sources[j] = sources[i];
18 sources[i] = temp;
19 }
20 count++;
21 }
22 }
23 return sources;
24 }
上述代码我们看出同样是两个循环,但是不一样就在于内循环中,内循环的循环次数我们看到了,他是根据外循环的次数来相对的,如果外循环显示第一个数据,那么内循环则是显示第二个数字,所以两个在结果上是一样的,但是在循环次数上这个(冒泡排序)就比那个快一倍,接下来我们就执行以下这两个方法,在此同时我们同时在看上述中调用的out和ref的用法也用上了
1 static void Main(string[] args)
2 {
3 int[] array = new[] { 1223, 918, 234, 765, 974, 867, 86786, 145432, 867633, 9999999 }; // 目标数组
4
5 //冒泡排序
6 int count;
7 int[] intlist = bubbleSort(array, out count);
8
9 for (int i = 0; i < intlist.Length; i++)
10 {
11 Console.Write(intlist[i]+" ");
12
13 } Console.WriteLine("\t"+"循环次数为:"+count);
14
15 //类似冒泡排序,单循环次数较多
16 int count2 = 0;
17 int[] intlist2 = bubbleSort2(array, ref count2);
18 for (int i = 0; i < intlist2.Length; i++)
19 {
20 Console.Write(intlist2[i] + " ");
21
22 } Console.WriteLine("\t" + "循环次数为:" + count2);
23 Console.ReadKey();
24 }
其运行结果如下

结果我们看到了此方法运行,也通过out与ref传出了我们需要的循环次数的值!
三,接下来我们看看二分法
二分法:通俗理解为在一个大数据中查找需要的值,如果一个人查找的话想对费力,两个人的话就相对快得多,
我们看下代码
1 static void Main(string[] args)
2 {
3 int[] array = new[] { 1223, 918, 234, 765, 974, 867, 86786, 145432, 867633, 9999999 }; // 目标数组
4 int findValue = 145432; // 被查找数
5 //二分法结果
6 Console.WriteLine(BinarySearch(array, findValue, 0, array.Length - 1) ? "被查找数存在数组array中" : "被查找数不存在数组array中");
7 }
8
9 /// <summary>
10 /// 二分查找/折半查找(分治思想、递归,目标数组必须是有序序列),算法复杂度为o(log(n),n代表目标数组长度)
11 /// </summary>
12 /// <param name="sources">目标数组</param>
13 /// <param name="findValue">目标查找数</param>
14 /// <param name="low">区间最小索引</param>
15 /// <param name="high">区间最大索引</param>
16 /// <returns>true:存在,false,不存在</returns>
17 private static bool BinarySearch(int[] sources, int findValue, int low, int high)
18 {
19 // 未找到,终止递归
20 if (low > high) return false;
21
22 // 折半查找中间值 索引:(a + b) / 2表示算数平均数,即中点
23 int middleIndex = (low + high) % 2 == 0 ? (low + high) / 2 : (low + high) / 2 + 1;
24
25 if (findValue > sources[middleIndex])
26 {
27 // 大于中间值,在区间[middleIndex + 1, high]递归继续查找
28 return BinarySearch(sources, findValue, middleIndex + 1, high);
29 }
30 if (findValue < sources[middleIndex])
31 {
32 // 小于中间值,在区间[low, middleIndex - 1]递归继续查找
33 return BinarySearch(sources, findValue, low, middleIndex - 1);
34 }
35
36 // findValue 等于 sources[middleIndex],找到,终止递归
37 return true;
38 }
这就是通过二分法实现查找方式。
以上仅为随笔,若有错误,或有所指点之地,希望大神们不要吝啬。谢谢!
ref与out的区别、冒泡排序、普通排序,以及二分法查询的更多相关文章
- ref和out的区别,值类型和引用类型的使用
今天刚刚明白ref和out的区别,只限于个人理解如有不同请赐教,谢谢 首先我感觉ref和out是针对于值类型来说,以前一直认为是针对于引用类型看下面的一段代码 1.首先结果 i=0:ints[0]=0 ...
- ref和out的区别?
ref 和out的区别在面试中会常问到: 首先:两者都是按地址传递的,使用后都将改变原来参数的数值. 其次:ref可以把参数的数值传递进函数,但是out是要把参数清空,就是说你无法把一个数值从out传 ...
- ref和out的区别
ref类型参数是按地址传递,能改变原来的数值.使用ref传参前,变量必须赋值. 带有ref类型参数的函数,不会清空变量,所以离开该函数的时候,所有ref引用的变量可以赋值也可以不赋值. out类型参数 ...
- 归并排序 & 计数排序 & 基数排序 & 冒泡排序 & 选择排序 ----> 内部排序性能比较
2.3 归并排序 接口定义: int merge(void* data, int esize, int lpos, int dpos, int rpos, int (*compare)(const v ...
- 浅谈C#中ref与out的区别
在C#这门高级语言中,你是否注意过ref与out的用法?你是否为在调用方法时需要多个返回值呢?不用急,接下来,我们去一起去研究一下这个问题... 其实呢,C#语言中,参数的传递一共有两种方法,值传递和 ...
- C#中的ref和out的区别
转载原地址 http://www.cnblogs.com/gjahead/archive/2008/02/28/1084871.html ref和out的区别在C# 中,既可以通过值也可以通过引用传递 ...
- 关于ref与out的区别
写在最前面 这几天一直在公司接受培训,都是一些基础的知识,同时也乘着这个机会巩固一下自己的基础,基础太重要了.前些时一直看的是多线程方面的知识,接下来我会写一些其他方面的知识,毕竟作为一个实习新人得和 ...
- C#中ref和out的区别浅析
这篇文章主要介绍了C#中ref和out的区别浅析,当一个方法需要返回多个值的时候,就需要用到ref和out,那么这两个方法区别在哪儿呢,需要的朋友可以参考下 在C#中通过使用方法来获取返回值时,通 ...
- 参数修饰符ref,out ,params的区别
参数修饰符ref,out ,params的区别 C#中有三个关键字-ref,out ,params,可是这三个之间的区别你都明白了吗? 那么我们就来认识一下参数修饰符ref,out ,params吧, ...
随机推荐
- mybatis入门介绍二
相信看过我的上一篇博客的同学都已经对mybatis有一个初步的认识了.这篇博客主要是对mybatis的mapper代理做一下简单的介绍,希望能够帮助大家共同学习. 我的上一篇博客:mybatis入门介 ...
- 如何使用命令行cmd执行java程序
如果你的电脑上没有像idea eclipse这类的IDE,但是因为工作需要必须要执行java代码怎么办呢? 这个时候就需要使用电脑最原始的执行方式 既命令行 1:首先你得安装了jdk与jre (这里就 ...
- Linux 下 安装jdk 1.7
Linux 下 安装jdk 1.7 参考百度经验 http://jingyan.baidu.com/album/ce09321b7c111f2bff858fea.html?picindex=6 第一步 ...
- GPUImage原理
GPUImage是一个开元的基于GPU的图片或视频的处理框架,其本身内置了多达120多种常见的滤镜效果,并且支持照相机和摄像机的实时滤镜,并且能够自定义图像滤镜. 美颜的基本概念 OpenGL ES: ...
- C#字符串格式化(摘抄的,留下来用用)
1.格式化货币(跟系统的环境有关,中文系统默认格式化人民币,英文系统格式化美元) string.Format("{0:C}",0.2) 结果为:¥0.20 (英文操作系统结果:$0 ...
- java大数取余
java大数取余: 类方法:BigInteger.divideAndRemainder() 返回一个数组,key = 0为商key = 1为余数 import java.util.*; import ...
- vue指令v-text示例解析
<div id="app"> <!--两种方式都是插值,输出结果一样--> <p v-text="msg"></p&g ...
- python学习===实现定时发送,方法一
#比如每3秒打印一次helloworld:from threading import Timer def printHello(): print "Hello World" t = ...
- C++之STL总结精华笔记
一.一般介绍 STL(StandardTemplate Library),即标准模板库,是一个具有工业强度的,高效的C++程序库.它被容纳于C++标准程 ...
- Android自定义控件系列之基础篇
一.概述 在android开发中很多UI控件往往需要进行定制以满足应用的需要或达到更加的效果,接下来就通过一个系列来介绍自定义控件,这里更多是通过一些案例逐步去学习,本系列有一些典型的应用,掌握好了大 ...