一、首先我们先讲一下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、(普通排序)首先,我们还是借用上述代码,
首先我们先创建一个数组,同样的 调用我们写好的方法,
class="brush:csharp;gutter:true;"> /// <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 }
这就是通过二分法实现查找方式。
以上仅为随笔,若有错误,或有所指点之地,希望大神们不要吝啬。谢谢!