ref与out的区别、冒泡排序、普通排序,以及二分法查询_.NET_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > .NET > ref与out的区别、冒泡排序、普通排序,以及二分法查询

ref与out的区别、冒泡排序、普通排序,以及二分法查询

 2017/9/8 12:08:51  苏寒?莫非  程序员俱乐部  我要评论(0)
  • 摘要:一、首先我们先讲一下ref与out的区别和使用方法;1、ref与out的区别:out:需要在使用前声明变量,分配地址但不能赋值,但是需要在使用中的时候需要初始化(进入方法体中的时候需要先赋值在使用),至于为什么要在方法体中使用,我个人认为是为了区别ref;(即只出不进)ref:需要在使用前声明且初始化,分配地址并且赋值,这样做可以根据初始化的值带入,可以根据传入的值进行一些逻辑判断;(即有进有出,有头有尾)共同点:都需要先声明变量,且都有回传值。2、使用方法:首先我们先看看两者使用方法
  • 标签:区别 冒泡排序

一、首先我们先讲一下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             }

 

这就是通过二分法实现查找方式。

 

以上仅为随笔,若有错误,或有所指点之地,希望大神们不要吝啬。谢谢!

 

发表评论
用户名: 匿名