C#常用的算法
一.二分法
注:一定是有序的数组,才可以使用这种算法,如果数组没有排序则先进行排序后再调用此方法。
二分顾名思义,就是将一组数据对半分开(比如左右两部分,下面用左右数组表示),从中间位置开始查找,
如果中间这个值正是咱们要找的值则直接返回这个值(或者索引),如果没有找到,那么去判断中间的这个值和咱们要找的值哪个大,
如果中间值比咱们要找的值大,则将之前分开的数组的左面的数组再进行对半分开,递归直到找到咱们要的那个值才会结束,反之亦然,
但是如果就是没有咱们找的值那么岂不是死循环了嘛,
所以要加判断,如果递归到开始索引大于结束索引,也就是查到最后了还是没有找到匹配的值,则退出。
这种搜索算法每一次比较都使搜索范围缩小一半,这样对于大数据量的数组,极大的提升了查找效率。
private void button1_Click(object sender, EventArgs e)
{
int[] arry = { 8, 15, 19, 23, 26, 31, 40, 65, 91 };
//测试 要找的数字是15
int key = 15;
//查找数并返回 若有,返回该数,没有则返回-1
int rr = BinarySearch(arry, 0, arry.Length - 1, key);
} /// <summary>
/// 二分法查找指定值
/// </summary>
/// <param name="arr">目标数组</param>
/// <param name="start">开始索引</param>
/// <param name="end">结束索引</param>
/// <param name="key">要查找的关键字</param>
/// <returns></returns>
public static int BinarySearch(int[] arr, int start, int end, int key)
{
int mid = (start + end) / 2;
if (start > end)
return -1;//查找不到返回-1
else
{
Console.WriteLine(arr[mid]);//监测查找了哪些数字
if (arr[mid] == key)
return mid;//若查找到,返回该数
else if (arr[mid] > key)
return BinarySearch(arr, start, mid - 1, key);
else return BinarySearch(arr, mid + 1, end, key);
}
}
二.递归
1.递归方法一直会调用自己直到某些条件满足,也就是说一定要有出口;
2.递归方法会有一些参数,而它会把这些新的参数值传递给自己;(自己调自己);
递归通常用于: ①.阶乘() ②.斐波拉切数列(公式如果F0=0并且F1=1那么Fn=F(n-1)+F(n-2);)
1.阶乘(从1到n的连续自然数相乘的积)
注意 最高支持到31阶乘:
static void Main(string[] args)
{
int n;
int.TryParse(Console.ReadLine(), out n);
Console.WriteLine(Factorial(n));
Console.ReadKey();
} static int Factorial(int n)
{
if (n == 0)
{
return 1;
}
return n * Factorial(n - 1);
}
2.斐波拉切数列(斐波那契数列指的是这样一个数列:1、1、2、3、5、8、13、21、……这个数列从第三项开始,每一项都等于前两项之和.)
public static int Foo(int i)
{
if (i <= 0)
{
return 0;
}
else if (i > 0 && i <= 2)
{
return 1;
}
else
{
return Foo(i - 1) + Foo(i - 2);
}
}
三.冒泡排序
思路:依次比较相邻的两个数,将小数放在前面,大数放在后面。即在第一趟:首先比较第1个和第2个数,将小数放前,大数放后。然后比较第2个数和第3个数,将小数放前,大数放后,如此继续,直至比较最后两个数,将小数放前,大数放后。重复第一趟步骤,直至全部排序完成。
int[] nums = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
for (int i = 0; i < nums.Length - 1; i++)
{
for (int j = 0; j < nums.Length-1-i; j++)
{
if (nums[j] > nums[j + 1])
{
int temp = nums[j];
nums[j] = nums[j + 1];
nums[j + 1] = temp;
}
}
}
//打印数组
for (int i = 0; i < nums.Length; i++)
{
Console.WriteLine(nums[i]); }
Console.ReadKey();
四.不使用中间变量交换两个数
常用的有三种方法,加减法,乘除法,异或法:
1.加减法,这个是最容易的想到的,不过需要注意的,如果在处理浮点型数字的时候可能会精度丢失:
a=a+b;
b=a-b;
a=a-b;
2.乘除法,和加减法类似,也会有精度丢失,不过出现的一个问题是除数不能为0:
a=a*b;
b=a/b;
a=a/b;
3.异或法,这个需要记住的一点就是变量a异或b的异或值异或b等于a:
a=a^b;
b=a^b;
a=a^b;
五.插入排序
插入排序实际上把待排序的数列分为了两部分,一部分已排好序,另一部分待排序。我们下面还是以一组实际数据为例进行讲解。例如采用直接插入排序算法将无序表{3,1,7,5,2,4,9,6}进行升序排序的过程为:
- 首先需要明确待排序的数列由两部分组成,一部分是已排好序的部分,另一部分是待排序的部分;
- 接着我们每次选择待排序的部分的第 1 个元素,分别与前面的元素进行比较。当大于前面的元素时,可以直接进入已排好序的部分;当小于前面的元素时,需要把这个元素拿出来,将前面的元素后移一位,继续与前面的元素相比,直到比较完数组的第 1 个元素或者出现一个元素小于我们拿出来的这个元素,这时停止比较、移动,直接把这个元素放到当时的空位上;
- 一直重复步骤 2,当待排序的部分已经没有元素可进行插入时,停止操作,当前的数列为已排好序的数列。
使用场景
- 在数组元素规模较小的时候,插入排序法的运行效率很高。其经常用在一些其他排序方法中(比如归并排序以及快速排序)来对排序进行优化。
- 不同于选择排序法,当一个数组几乎有序的时候,插入排序法所需要的时间要比其他的排序法快得多。因此插入排序法的排序时间取决于数组元素的初始顺序,在最好的情况下,插入排序法运行时间能达到线性级别。
class Program
{
//插入排序法
public static void insertSort(int[] array)
{
//for循环:i作为指针,进行从左到右扫描数据的工作
//指针i从1开始扫描,因为i=0时指针左侧无元素
for (int i = 1; i < array.Length; i++)
{
//temp作为指针键值
int temp = array[i]; //新建变量j,从i开始向左扫描已经有序的元素,并与temp比较
//若temp小于扫描元素,则将j指针元素向右移位腾出空间
int j = i;
while (j > 0 && array[j - 1] > temp)
{
array[j] = array[j - 1];
j--;
}
//循环完成后将temp放在j指针位置,完成本次插入
array[j] = temp;
} } //打印数组
public static void printArray(int[] array)
{
foreach (int item in array)
{
Console.Write(item + "\t");
}
Console.WriteLine();
} //主函数入口
static void Main(string[] args)
{
int[] array = new int[10] { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
printArray(array);
insertSort(array);
printArray(array);
Console.ReadKey(); }
}
六.选择排序
每次从后面找到最小或最大的数,进行位移排序。
数组 int [] array = [11, 39, 35, 30, 7, 36, 22, 13, 1, 38, 26, 18, 12, 5, 45, 32, 6, 21, 42, 23];
第一位 i=0
最小值下标 minIndex = 0,最小值 min=11
从后面查找比 11 小的数,找到第 下标位 8,值为1,
进行交换,交换后 [1, 39, 35, 30, 7, 36, 22, 13, 11, 38, 26, 18, 12, 5, 45, 32, 6, 21, 42, 23];
第二位 i=1,
最小值下标 minIndex = 1,最小值 min=39,
从后面查找比 39 小且最小的数,找到 下标为 13,值为 5,
进行交换,交换后 [1, 5, 35, 30, 7, 36, 22, 13, 11, 38, 26, 18, 12, 39, 45, 32, 6, 21, 42, 23];
public static void ReSort(ref int[] array)
{
for (int i = 0; i < array.Length; i++)
{
int min = array[i]; //设定第i位为最小值
int minIndex = i; //最小值下标
for (int j = i; j < array.Length; j++) //从第i为开始找出最小的数
{
if (array[j] < array[minIndex]) //重新存储最小值和下标
{
min = array[j];
minIndex = j;
}
} if (array[i] != array[minIndex]) //如果到比第i为更小的数,则发生交换。找不到则不改变
{
array[minIndex] = array[i];
array[i] = min;
}
}
}
七.快速排序
快速排序是从冒泡排序演变而来,快速排序之所以快,是因为使用了分治法。
同冒泡排序一样,快速排序也属于交换排序,通过元素之间的比较和交换位置来达到排序的目的。
快速排序是在每一轮挑选一个基准元素,并让其他比它大的元素移动到数列的一边,比它晓得元素移动到数列的另一边,从而把数列拆解成两个部分。
public class QuickSort
{
public static void Test()
{
int[] arr = { -9, 78, 0, 23, -567, 70 }; Sort(arr,0,arr.Length-1); System.Console.WriteLine(string.Join(",",arr));
} public static void Sort(int[] arr ,int left,int right)
{
int l = left; int r = right; //中间值
int middle = arr[(l + r) / 2]; //temp临时变量
int temp = 0; //while循环的目的是让比middle值小的放在左边 比middle大的值放在右边
while (l<r)
{
//在middle的左边一直找,找到大于等于middle的值才退出
while (arr[l]<middle)
{
l++;
}
//在middle的右边边一直找,找到小于等于middle的值才退出
while (arr[r]>middle)
{
r -= 1;
} //如果l>=说明middle的左边两边的值,已按照左边全是小于等于middle的值,右边都是大于middle的值
if (l>=r)
{
break;
} //交换 temp = arr[l]; arr[l] = arr[r]; arr[r] = temp; //如果交换完之后,发现这个arr[l]==middle这个值 ,-- 前移
if (arr[l]==middle)
{
r -= 1;
} //如果交换完之后,发现这个arr[r]==middle这个值 ,++ 后移
if (arr[r]==middle)
{
l++;
} } //如果l==r,必须l++,r--,否则会出现栈溢出
if (l==r)
{
l += 1; r -= 1;
} //向左递归
if (left<r)
{
Sort(arr, left, r);
} //向右递归
if (right>l)
{
Sort(arr, l, right);
} }
}
八.在一个给定的从1到100的整型数组中,如何快速找到缺失的数字
九如何找到一个给定的整型数组中的重复数字?
十在一个未排序的整型数组中,如何找到最大和最小的数字?
十一在一个整型数组中,如何找到一个所有成对的数字,满足它们的和等于一个给定的数字?
十二如果一个数组包含多个重复元素,如何找到这些重复的数字?
十三用C# 实现从一个给定数组中删除重复元素?
十四如何利用快速排序对一个整型数组进行排序?
十五如何从一个数组中删除重复元素?
十六用 C#如何实现数组反转?
十七如何输出字符串中的重复字符?
十八如何判断两个字符串是否互为回文?
十九如何从字符串中输出第一个不重复字符?
static void Main(string[] args)
{
string str = "ABCDCBAbbb";
var index = FirstUniqChar(str);
var charStr= str[index];
} public static int FirstUniqChar(String s)
{
char[] temp = s.ToCharArray();
int length = temp.Length;
int j, i;
int result = 0;
for (i = 0; i < length; i++)
{
for (j = 0; j < length; j++)
{
if (i == j) { continue; }
if (temp[i] == temp[j])
{
break;
}
}
if (j == length)
{
result = i;
break;
}
}
if (i == length)
{
result = -1;
}
return result;
}
二十如何使用递归实现字符串反转?
二十一如何在字符串中找到重复字符?
二十二如何计算给定字符传中特定字符出现的次数?
二十三如何找到一个字符串的全排列?
二十四在不使用任何库方法的情况下如何反转给定语句中的单词?
二十五如何判断两个字符串是否互为旋转?
/// <summary>
///a="cdab",b="abcd",返回true;
///a="1ab2",b="ab12",返回false;
///a="2ab1",b="ab12",返回true。
/// </summary>
/// <param name="args"></param>
static void Main(string[] args)
{
string a = "cdab";
string b = "abcd";
var aResult = IsRotation2(a, b);
a = "1ab2"; b = "ab12"; // 返回false;
var bResult = IsRotation2(a, b);
} public static bool IsRotation2(String a, String b)
{
if (a == null || b == null || a.Length != b.Length)
{
return false;
}
String b2 = b + b;
return IndexOf(b2, a, 0) > -1;
} private static int IndexOf(String b2, String a, int index)
{
char[] source = b2.ToCharArray();
char[] target = a.ToCharArray();
return Func(source, 0, source.Length, target, 0, target.Length, index);
} private static int Func(char[] source, int sourceOffset, int sourceCount,
char[] target, int targetOffset, int targetCount,
int fromIndex)
{
if (fromIndex >= sourceCount)
{
return (targetCount == 0 ? sourceCount : -1);
}
if (fromIndex < 0)
{
fromIndex = 0;
}
if (targetCount == 0)
{
return fromIndex;
}
char first = target[targetOffset];
int max = sourceOffset + (sourceCount - targetCount); for (int i = sourceOffset + fromIndex; i <= max; i++)
{
if (source[i] != first)
{
while (++i <= max && source[i] != first) ;
} if (i <= max)
{
int j = i + 1;
int end = j + targetCount - 1;
for (int k = targetOffset + 1; j < end && source[j]
== target[k]; j++, k++) ; if (j == end)
{
return i - sourceOffset;
}
}
}
return -1;
}
C#常用的算法的更多相关文章
- DotNet常用排序算法总结
数据结构和算法对一个程序来说是至关重要的,现在介绍一下几种算法,在项目中较为常用的算法有:冒泡排序,简单选择排序,直接插入排序,希尔排序,堆排序,归并排序,快速排序等7中算法. 现在介绍选择排序算法, ...
- Java常用排序算法+程序员必须掌握的8大排序算法+二分法查找法
Java 常用排序算法/程序员必须掌握的 8大排序算法 本文由网络资料整理转载而来,如有问题,欢迎指正! 分类: 1)插入排序(直接插入排序.希尔排序) 2)交换排序(冒泡排序.快速排序) 3)选择排 ...
- 转载部长一篇大作:常用排序算法之JavaScript实现
转载部长一篇大作:常用排序算法之JavaScript实现 注:本文是转载实验室同门王部长的大作,找实习找工作在即,本文颇有用处!原文出处:http://www.cnblogs.com/ywang172 ...
- 【学】常用hash算法的介绍
基本知识 Hash,一般翻译做“散列”,也有直接音译为“哈希”的,就是把任意长度的输入(又叫做预映射, pre-image),通过散列算法,变换成固定长度的输出,该输出就是散列值.这种转换是一种压缩映 ...
- Java 常用排序算法/程序员必须掌握的 8大排序算法
Java 常用排序算法/程序员必须掌握的 8大排序算法 分类: 1)插入排序(直接插入排序.希尔排序) 2)交换排序(冒泡排序.快速排序) 3)选择排序(直接选择排序.堆排序) 4)归并排序 5)分配 ...
- ACM 中常用的算法有哪些? 2014-08-21 21:15 40人阅读 评论(0) 收藏
ACM 中常用的算法有哪些?作者: 张俊Michael 网络上流传的答案有很多,估计提问者也曾经去网上搜过.所以根据自己微薄的经验提点看法. 我ACM初期是训练编码能力,以水题为主(就是没有任何算法, ...
- ACM 中常用的算法有哪些?
在网上看到别人ACM学习的心得,转载过来,源地址不记得了,当时是百度的.内容如下: 网络上流传的答案有很多,估计提问者也曾经去网上搜过.所以根据自己微薄的经验提点看法. 我ACM初期是训练编码能力,以 ...
- 常用排序算法的python实现和性能分析
常用排序算法的python实现和性能分析 一年一度的换工作高峰又到了,HR大概每天都塞几份简历过来,基本上一天安排两个面试的话,当天就只能加班干活了.趁着面试别人的机会,自己也把一些基础算法和一些面试 ...
- 面试中常用排序算法实现(Java)
当我们进行数据处理的时候,往往需要对数据进行查找操作,一个有序的数据集往往能够在高效的查找算法下快速得到结果.所以排序的效率就会显的十分重要,本篇我们将着重的介绍几个常见的排序算法,涉及如下内容: 排 ...
- 常用排序算法java实现
写在前面:纸上得来终觉浅.基本排序算法的思想,可能很多人都说的头头是到,但能说和能写出来,真的还是有很大区别的. 今天整理了一下各种常用排序算法,当然还不全,后面会继续补充.代码中可能有累赘或错误的地 ...
随机推荐
- jenkins、gitlab配置CI/CD
1. 在gitlab中创建好项目(gitlab的安装和基本使用这里不在说明) 2. 创建jenkins任务 jenkins 需要几个插件请先安装好 - Git plugin - GitLab Plug ...
- EdgeConnect: Structure Guided Image Inpainting using Edge Prediction
论文 pytorch 引言 语义分割获取边缘信息指导修复其二 存在的问题:之前方法能够生成具有有意义结构的缺失区域,但生成的区域往往模糊或边缘部分存在伪影. 提出问题:提出了一个两阶段的模型,将inp ...
- 04_ Broadcast Receiver
Broadcast是广播,和Android内的事件一样,它可以发出一个广播(事件),注册了该广播接收器(事件监听器)的所有组件都会接收到该广播,从而调用自己的响应方法(事件响应处理). 下面将详细的阐 ...
- 第3.8节 Python百分号占位符的字符串格式化方法
一. 概念 格式化字符串就是将一些变量转换为字符串并按一定格式输出字符串,包括指定字符的位置.对齐方式.空位补充方式等.Python提供了多种字符串格式设置方法.本节先介绍一种简 ...
- HTTP请求头和响应头详解【转】
最近老猿在开始学习爬虫相关的知识,由于老猿以前只做非web的后台应用,发现相关知识太过匮乏,导致学习很困难,为此不得不从一些基础知识恶补开始,对于这些知识,老猿会将网上找到的比较认可的内容直接转发. ...
- PyQt(Python+Qt)学习随笔:Model/View架构中的Model模型概念
老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 Model/View架构中的Model模型Model与数据源通信,为体系结构中的其他组件提供数据接口 ...
- PyQt(Python+Qt)学习随笔:QAbstractItemView的showDropIndicator属性
老猿Python博文目录 老猿Python博客地址 概述 QAbstractItemView的showDropIndicator属性用于控制在拖拽过程中显示当前拖拽到的位置,当释放时则在当前拖拽位置覆 ...
- Day7 【Scrum 冲刺博客】
每日会议总结 昨天已完成的工作 方晓莹(PIPIYIng) 对接车位管理接口 处理对接接口遇到的bug和错误 方子茵(Laa-L) 暂无 黄芯悦(Sheaxx) 完成住户车位查询页面 完成住户物业报修 ...
- OI知识点/得分技巧的归纳总结
网络流 拆点/拆边技巧 题目来源 bzoj1070 题目描述 同一时刻有\(N\)位车主带着他们的爱车来到了汽车维修中心.维修中心共有\(M\)位技术人员,不同的技术人员对不同 的车进行维修所用的时间 ...
- CentOS配置Nginx官方的Yum源
由于yum源中没有我们想要的nginx,那么我们就需要创建一个"/etc/yum.repos.d/nginx.repo"的文件,其实就是新增一个yum源. [root@niaoyu ...