各种算法总结一
求出数组中的最大值,最原始的方式;方式一
static void FindMax03() { //数组中最大的一个数据,它肯定比数组中的每一个数都大,所以。。。就有了下面的算法了滴呀; var arr = new int[6] { 40, 3320, 10, 242, 3450, 2 }; var len = arr.Length; var max = 0; for(var i=0; i < len; i++) { var temp = arr[i]; var times = 0; for(var j = 0; j < len; j++) { if (temp > arr[j]) { //如果Temp 比数组中的每一数 都要大,那么,它一定是最大的数据了滴呀; times++; } } if (times == len-1) { max = arr[i]; //那么这个数据就是我们的最大值滴哎呀; break; } } Console.WriteLine("the max value is {0} ",max); }
求出数组中的最大的数;(方式二),这种方法大概就是,相邻的两个数据,进行比较,留下最大的一个数据,然后继续与下一个数据比较;
反正每次比较之后,我们都留下了最大的那个数据滴啊;
static void GetMaxInt() { var arr = new int [5] {40,20,30,40,50 }; var arrLen = arr.Length; int max = arr[0]; //在开始的第一步,我们自然认为:第一个数值最大的值; for (var i = 0; i < arrLen; i++) { if (arr[i] > max) //与第二个数据比较 { max = arr[i]; //这里隐藏着一个copy的操作; //始终保持手中的数 是最大的一个; } else { } } Console.WriteLine("max value={0}",max);
当然有我们的额(方式三),这种方式,就是相邻连个数据记性比较,最大的数据往后面挪动,自然最大的一个数据就是我们的最大的一个数据;这种方式不借助中间变量,max
这种方式,有点类似我们的额冒泡排序的感觉滴呀;
static void GetMax001() { var arr = new int[5] { 40, 20, 301, 40, 50 }; var arrLen = arr.Length; for (var i = 0; i < arrLen-1; i++) { if (arr[i] > arr[i+1]) //把前面的一个数据和后面的一个数进行比较 { int temp = arr[i + 1];//中间变量 arr[i + 1] = arr[i]; //位置交换,大的数据排在前面 arr[i] = temp; //小的数据排在后面; } } //这样同样能够找出我们的最大的数滴呀; Console.WriteLine("the seconde value is:{0}", arr[arrLen-1]); }
当然有我们的额方式四滴呀,有点分区求最大值的想法,(这种思想有点类型我们的分组晋级练球赛的感觉滴呀;)
这种做法,仅仅使用了,循环次数的一半的滴呀,最大化的利用我们的循环效果滴呀;这里我们分额是两个区,当然也可以额分多个区,但是,分多了,就没多大意义了;
static void FindMax() { //基本思想就是讲数组分成两个区, //分别求出每个区的最大值,然后进行各种比较滴呀; //这里我们都求正整数滴呀; //效果还是不错滴哦; var arr = new int[6] { 40, 320, 32110, 2432, 3450 ,2}; var len = arr.Length; var half = len / 2; var rightMax = 0; var leftMax = 0; var max = 0; for(var i = 0; i < half; i++) { if (arr[i]> rightMax) { rightMax = arr[i]; } if(arr[half + i]> leftMax) { leftMax=arr[half+i]; } } //循环结束后,我们来进行两个区之间的各种比较滴呀; if (rightMax > leftMax) { max = rightMax; } else { max = leftMax; } Console.WriteLine("the max value:{0}",max); }
接续优化
static void FindMax1() { //这种做法并没改变原始数组的大小,或则叫值吧; var arr = new int[6] { 40, 320, 10, 24342, 3450, 2 }; var len = arr.Length; var rightMax = 0; var leftMax = 0; var max = 0; for(var i = 0; i < len/2; i++) { if (arr[i] > leftMax) { leftMax = arr[i]; //相邻的两个数进行比较,始终留下最大的一个数据滴哎呀; } if (arr[len - 1 - i] > rightMax) { rightMax = arr[len - 1 - i];//相邻的两个数进行比较,始终留下最大的一个数据滴哎呀; } } //结束之后,再进行比较; if (rightMax > leftMax) { max = rightMax; }else { max = leftMax; } Console.WriteLine("the max value:{0}",max); }
很快就有了我们的方式五滴呀;
ps:记录一下,一种不太完善的方式;也就是错误的一种方式,不过思路在异步的走向成熟滴呀;
static void FindMax3() { //我们快速排序就是基于这种方式实现滴呀; var arr = new int[6] { 40, 320, 10, 24342, 3450, 2 }; var list = new List<int>(); var len = arr.Length; var left = 0; var right = len - 1; var max = 0; for (var i = 0; i < len ; i++) { if (arr[left+i] > arr[right+i]) { //这种做法逻辑不完善 pass list.Add(arr[left]); } } Console.WriteLine("the max value:{0}", max); }
最终完整版:
你会发现,我们的额数组是偶数个的,如果是奇数个数组呢??
别小看求出数组中的最大一个值,很多排序算法都是从这里衍生出来滴哎呀;
然后,我们将算法,进行一些基本的优化滴哎呀,效果是非常好的滴呀,最大的利用了我们的一次for循环滴呀;
如果是求出数组中第二大的数呢
如果有事求出数组中前三个最大的数呢,排出一个1 2 3 来呢;
卧槽,各种联想有木有滴呀
//先来一个笨重的方法
static void GetSecondVlue() { var arr = new int[5] { 40, 20, 30, 40, 50 }; //求出第二大的数据,首先你还得找出第一大的数据,谁是第一,有了参照物,你才知道谁是第二大的数据滴啊; var arrLen = arr.Length; var max = arr[0]; for (var i = 0; i < arrLen; i++) { if (arr[i]>max) { max = arr[i]; } } //这样我们就求出了第一大的数据滴呀; //方式一,第一反应就能想到额;//这个方法之后先tolist之后再进行移除滴呀; ////然后再比较一次 var list = arr.ToList(); list.Remove(max); var second = list[0]; for (var j=0;j< list.Count;j++) { if (list[j] > second) { second = list[j]; } } //方式二,如果遇到max就不参与比较 Console.WriteLine("the seconde value is:{0}",second); }
接下来就是我们的第二种方式地啊;
static void GetSecondVlue2() { var arr = new int[5] { 40, 20, 30, 40, 50 }; //求出第二大的数据,首先你还得找出第一大的数据,谁是第一,有了参照物,你才知道谁是第二大的数据滴啊; var arrLen = arr.Length; var max = arr[0]; var second = 0; for (var i = 0; i < arrLen; i++) { if (arr[i] > max) { max = arr[i]; } } //第二种方法就是,再次比较,当我们遇到指定的值(max),我们就不参与比较低啊 for (var j = 0; j < arrLen; j++) { //自动过滤掉我们的之前的max地呀; if (arr[j] != max) //因为已经参数过了比较,这里我们就不参与比较了地呀 { if (arr[j] > second) { second = arr[j]; } } } Console.WriteLine("the seconde value is:{0}", second); }
第三种方式
static void GetMaxSecond() { var arr = new int[5] { 40, 20, 30, 42, 50 }; var arrLen = arr.Length; for (var j = 0; j < 2; j++)//找出第二大的数据,我找两次,不就得了吗? { for (var i = 0; i < arrLen - 1-j; i++) { if (arr[i] > arr[i + 1]) //把前面的一个数据和后面的一个数进行比较 { int temp = arr[i + 1];//中间变量 arr[i + 1] = arr[i]; //位置交换,大的数据排在前面 arr[i] = temp; //小的数据排在后面; } } } //这样同样能够找出我们的最大的数滴呀; //当然,如果是有序的结果集合的话,我们当然能够使用我们 折半查找的方式滴呀; //这个不是就很自然的引出了,我们的额冒泡排序的方式滴呀; Console.WriteLine("the seconde value is:{0}", arr[arrLen-1-1]); }
如果求两个数组中的最大值呢;
static void GetMaxInt() { var arr = new int [5] {40,20,30,40,50 }; var arrLen = arr.Length; int max = arr[0]; //在开始的第一步,我们自然认为:第一个数值最大的值; for (var i = 0; i < arrLen; i++) { if (arr[i] > max) //与第二个数据比较 { max = arr[i]; //这里隐藏着一个copy的操作; //始终保持手中的数 是最大的一个; } else { } } Console.WriteLine("max value={0}",max); } static void GetMax() { //如果求两个数组中的最大值呢; var arr = new int[5] { 40, 20, 30, 40, 50 }; var arr1 = new int[5] { 41, 21, 301, 140, 150 }; //先求出A中的最大 //再求B中的最大值 var arrLen = arr.Length; var arrlen1 = arr1.Length; var max = arr[0]; var max1 = arr1[0]; var finalMax = 0; //求一个数组的最大值 for (var i = 0; i < arrLen; i++) { if (arr[i] > max) { max = arr[i]; } } //求第二个数组的最大值; for(var j=0;j< arrlen1; j++) { if (arr1[j] > max1) { max1 = arr1[j]; } } //然后最终的结果比较 if (max > max1) { finalMax = max; }else { finalMax = max1; } Console.WriteLine("finalMax is :{0}",finalMax);//这个就是我们的最终结果滴啊; //效果还是听不错滴呀; //这种事分两步走的方式滴哎呀; //这种方式,我们就可以充分的利用我们的异常处理;或则叫做并发触发处理方式; //来解决我们的基本方式滴呀; } static void GetMax1() { var arr = new int[5] { 40, 20, 30, 40, 50 }; var arr1 = new int[5] { 41, 21, 301, 140, 150 }; var arrLen = arr.Length; var arrlen1 = arr1.Length; var max = arr[0]; //始终保持最大的变量计算值滴呀; //最终的效果还是挺不错滴哎呀; for (var i = 0; i < arrLen; i++) { if (arr[i] > max) { max = arr[i]; } } //将第一组中的最大数据 与我们的第二组,进行各种比较滴呀; //这种有一点同步滴感觉滴滴呀; for (var j = 0; j < arrlen1; j++) { if (arr1[j] > max) { max = arr1[j]; } } Console.WriteLine("finalMax is :{0}", max);//这个就是我们的最终结果滴啊; } static void GetMax2() { var arr = new int[5] { 40, 20, 30, 40, 50 }; var arr1 = new int[5] { 41, 21, 301, 140, 150 }; var max = 0; //我觉得肯定有方法就行优化滴呀; //进行两次循环比较 //第一个数,与每一数进行比较滴呀; for (var i = 0; i < arr.Length; i++) { for (var j=0;j<arr1.Length;j++) //是外层的n倍,相比之下,这种方式可能要麻烦一些滴哎呀; { //这样只是两个循环的交叉遍历; //内层循环受到外层循环的制约滴呀; //两个嵌套循环滴呀;敲好可以将我们的两个数组都走一遍滴哎呀;两个数组都走了一遍了,应该能找出我们的最大值滴哎呀; if (arr[i] > arr1[j]) { max = arr[i]; }else { max = arr1[j]; } } } } //双重循环的方式; //效果还是不错滴呀; static void DoubleLoop() { var outer = 10; var inner = 10; for (var i = 0; i <outer; i++) { Console.Write("外层循环"); //外层循环1次,内层要完整的循环N次滴呀; for(var j = 0; j < inner; j++) { Console.Write("[内层循环]"); //两种之间没有相对的制约滴呀; } Console.WriteLine(); } Console.WriteLine("-----"); //还有一种是由制约的方式滴呀 for(var i = 0; i < outer; i++) { Console.Write("外层循环"); for(var j = 0; j < inner-i; j++) { Console.Write("[内层循环]"); //受到我们外层的制约滴呀,因为我们每次都减少了循环次数i //内存循环再不断的减少 //这个就是我们基本的操作地哎呀; } Console.WriteLine(); } //这里呈现递增的趋势滴呀; for (var i = 0; i < outer; i++) { Console.Write("外层循环"); for (var j = 0; j < 0 + i; j++) { Console.Write("[内层循环]"); //受到我们外层的制约滴呀,因为我们每次都减少了循环次数i //内存循环再不断的减少 //这个就是我们基本的操作地哎呀; //这样就可以搞一个99 乘法表出来滴啊; } Console.WriteLine(); } }
然后接着就是我们基本的冒泡算法滴呀;
static void BubbleList() { Console.WriteLine("从小到大的排列滴哎呀"); var arr = new int[5] { 40, 210, 30, 42, 50 }; var arrLen = arr.Length; for (var j = 0; j < arrLen; j++)//找出第二大的数据,我找两次,不就得了吗? { for (var i = 0; i < arrLen - 1 - j; i++) { if (arr[i] > arr[i + 1]) //把前面的一个数据和后面的一个数进行比较 { int temp = arr[i + 1];//中间变量 arr[i + 1] = arr[i]; //位置交换,大的数据排在前面 arr[i] = temp; //小的数据排在后面; } } } foreach(var i in arr) { Console.WriteLine("the value is:{0}",i); //最终的排序结果还是出来了滴呀; } Console.WriteLine("从大到小的排列滴哎呀"); //上面的结果是小到大的排列滴哎呀; //那么如果从大到小额拍列呢; // 数组是引用类型的值滴呀; var newArr = new int[5] { 40, 20, 310, 42, 50 }; var len = newArr.Length; for (var i = 0; i < len; i++) { for (var j = len- 1; j >i ; j--) //从后面忘前面排滴呀; { if (newArr[j]>newArr[j-1]) { int temp = newArr[j-1]; newArr[j - 1] = newArr[j]; newArr[j] = temp; } } } foreach (var a in newArr) { Console.WriteLine("the value is:{0}", a); //最终的排序结果还是出来了滴呀; } }
顺便总结中两种for循环的方式;
static void FuckingLife() { var arr = new int[5] { 10, 20, 30, 40, 50 }; for(var i = 0; i < arr.Length; i++) { Console.Write(" {0} ",arr[i]); } Console.WriteLine(); for(var j = arr.Length - 1; j >= 0; j--) { Console.Write(" {0} ", arr[j]); } }
当然还有这样额结果;
static void FuckLife() { var outer = 10; var inner = 10; Console.WriteLine("这个是【叠加】的效果"); for(var i = 0; i < 10; i++) { Console.Write("外部循环"); for(var j = 0; j < inner; j++) { Console.Write("【内部循环】"); } Console.WriteLine(); } Console.WriteLine("内部循环【递减】的方式"); for (var i = outer; i >0; i--) { Console.Write("外部循环"); for (var j = inner; j >0; j--) { Console.Write("【内部循环】"); } Console.WriteLine(); } Console.WriteLine("内部循环递减的方式【另外一种写法;】"); for (var i = 0; i < outer; i++) { Console.Write("外部循环"); for (var j = inner - i-1; j >0 ; j--) { Console.Write("【内部循环】"); } Console.WriteLine(); } Console.WriteLine("---------------------内部循环递增的方式"); for (var i = 0; i < 10; i++) { Console.Write("外部循环"); for (var j = 0; j <i; j++) { Console.Write("【内部循环】"); } Console.WriteLine(); } }
结果:
总结:手指好痛~~~,一重循环:两种结果:正序和反序;
两种循环,2*2 中的组合方式;
内部可以递减和递增滴哎呀;
算了,手指好痛,不写;