MyException - 我的异常网
当前位置:我的异常网» C# » ref与out的差异、冒泡排序、普通排序,以及二分法查

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

www.MyException.Cn  网友分享于:2013-09-19  浏览:0次
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             }

 

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

 

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

 

文章评论

程序员周末都喜欢做什么?
程序员周末都喜欢做什么?
如何区分一个程序员是“老手“还是“新手“?
如何区分一个程序员是“老手“还是“新手“?
要嫁就嫁程序猿—钱多话少死的早
要嫁就嫁程序猿—钱多话少死的早
聊聊HTTPS和SSL/TLS协议
聊聊HTTPS和SSL/TLS协议
做程序猿的老婆应该注意的一些事情
做程序猿的老婆应该注意的一些事情
程序员最害怕的5件事 你中招了吗?
程序员最害怕的5件事 你中招了吗?
科技史上最臭名昭著的13大罪犯
科技史上最臭名昭著的13大罪犯
什么才是优秀的用户界面设计
什么才是优秀的用户界面设计
10个调试和排错的小建议
10个调试和排错的小建议
程序员都该阅读的书
程序员都该阅读的书
程序员眼里IE浏览器是什么样的
程序员眼里IE浏览器是什么样的
初级 vs 高级开发者 哪个性价比更高?
初级 vs 高级开发者 哪个性价比更高?
我跳槽是因为他们的显示器更大
我跳槽是因为他们的显示器更大
程序员的鄙视链
程序员的鄙视链
程序员必看的十大电影
程序员必看的十大电影
我的丈夫是个程序员
我的丈夫是个程序员
十大编程算法助程序员走上高手之路
十大编程算法助程序员走上高手之路
“懒”出效率是程序员的美德
“懒”出效率是程序员的美德
当下全球最炙手可热的八位少年创业者
当下全球最炙手可热的八位少年创业者
总结2014中国互联网十大段子
总结2014中国互联网十大段子
 程序员的样子
程序员的样子
鲜为人知的编程真相
鲜为人知的编程真相
中美印日四国程序员比较
中美印日四国程序员比较
编程语言是女人
编程语言是女人
程序员应该关注的一些事儿
程序员应该关注的一些事儿
团队中“技术大拿”并非越多越好
团队中“技术大拿”并非越多越好
2013年美国开发者薪资调查报告
2013年美国开发者薪资调查报告
Java 与 .NET 的平台发展之争
Java 与 .NET 的平台发展之争
一个程序员的时间管理
一个程序员的时间管理
Web开发人员为什么越来越懒了?
Web开发人员为什么越来越懒了?
Java程序员必看电影
Java程序员必看电影
Google伦敦新总部 犹如星级庄园
Google伦敦新总部 犹如星级庄园
代码女神横空出世
代码女神横空出世
那些争议最大的编程观点
那些争议最大的编程观点
2013年中国软件开发者薪资调查报告
2013年中国软件开发者薪资调查报告
“肮脏的”IT工作排行榜
“肮脏的”IT工作排行榜
为啥Android手机总会越用越慢?
为啥Android手机总会越用越慢?
60个开发者不容错过的免费资源库
60个开发者不容错过的免费资源库
5款最佳正则表达式编辑调试器
5款最佳正则表达式编辑调试器
老美怎么看待阿里赴美上市
老美怎么看待阿里赴美上市
10个帮程序员减压放松的网站
10个帮程序员减压放松的网站
如何成为一名黑客
如何成为一名黑客
我是如何打败拖延症的
我是如何打败拖延症的
不懂技术不要对懂技术的人说这很容易实现
不懂技术不要对懂技术的人说这很容易实现
程序员的一天:一寸光阴一寸金
程序员的一天:一寸光阴一寸金
老程序员的下场
老程序员的下场
看13位CEO、创始人和高管如何提高工作效率
看13位CEO、创始人和高管如何提高工作效率
那些性感的让人尖叫的程序员
那些性感的让人尖叫的程序员
程序员和编码员之间的区别
程序员和编码员之间的区别
软件开发程序错误异常ExceptionCopyright © 2009-2015 MyException 版权所有