排序
- 插入排序
插入排序是把一个记录插入到已排序的有序序列中,使整个序列在插入该记录后仍然有序。插入排序中比较简单的一种方法是直接插入排序,其插入位置的确定方法是将待插入的记录与有序区中的各记录自右向左依次比较其关键字值得大小。
void insort(int s[],int n)
{
int i,j;
for(i=2;i<=n;i++)
{
s[0]=s[i];
j=i-1;
while(s[0]<s[j])
{
s[j+1]=s[j];
j--;
}
s[j+1]=s[0];
}
}
- 希尔排序
希尔排序是在直接插入排序得基础上做得改进,也就是将要排序得序列按照固定增量分成若干组,等距离者在同一组中,然后再在组内进行直接插入排序。这里面得固定增量从 n/2 开始,以后每次缩小到原来得一半。
void shsort(int s[],int n)
{
int i,j,d;
d=n/2;
while(d>=1)
{
for(i=d+1;i<=n;i++)
{
s[0]=s[i];
j=i-d;
while((j>0) && (s[0]<s[j]))
{
s[j+d]=s[j];
j=j-d;
}
s[j+d]=s[0];
}
d=d/2;
}
}
- 冒泡排序
冒泡排序基本思路是,如果要对 n 个数进行冒泡排序,那么要进行 n-1 趟比较,在 1 趟比较中要进行 n-1 次两两比较,在第 j 趟比较要进行 n-j 次两两比较。
void busort(int s[],int n)
{
int x;
for(int i=0;i<n;i++)
{
for(int j=0;j<n-i-1;j++)
{
if(s[j+1]<s[j])
{
x=s[j];
s[j]=s[j+1];
s[j+1]=x;
}
}
}
}
- 快速排序
快速排序是冒泡排序得一种改进,主要思想是在待排序得 n 个数据中取第 1 个数据作为基准值,将所有记录分为 3 组,第 1 组数据值均小于或等于基准值,第 2 组做基准值得数据,第 3 组中各数据均大于或等于基准值。这便实现了第 1 趟分割,然后再对第 1 组和第 3 组分别重复上述方法,依此类推,直到每组中只有 1 个记录为止。
void qusort(int s[],int start,int end)
{
int i,j;
i=start;
j=end;
s[0]=s[start];
while(i<j)
{
while(i<j && s[0]<s[j])
j--;
if(i<j)
{
s[i]=s[j];
i++;
}
while(i<j && s[i]<=s[0])
i++;
if(i<j)
{
s[j]=s[i];
j--;
}
}
s[i]=s[0];
if(start<i)
qusort(s,start,j-1);
if(i<end)
qusort(s,j+1,end);
}
- 选择排序
选择排序的思想是从待排序的区间中经过选择和交换后选出最小的数值存放到 a[0] 中,再从剩余的未排序区间中经过选择和交换后选择出最小的数值放到 a[1] 中,a[1] 中的数值仅大于 a[0],以此类推,即可实现排序。
void sesort(int s[],int n)
{
int x;
for(int i=0;i<n;i++)
{
for(int j=i+1;j<=n;j++)
{
if(s[i]>s[j])
{
x=s[i];
s[i]=s[j];
s[j]=x;
}
}
}
}
- 归并排序
归并排序是将两个或多个有序记录序列合并成一个有序序列。归并方法有多种,1 次对两个有序记录序列进行归并,称为二路归并排序,也有三路归并排序及多路归并排序,二路归并排序基本方法如下:
(1)将 n 个记录看成是 n 个长度为 1 的有序子表;
(2)将两两相邻的有序子表进行归并;
(3)重复执行步骤(2),直到归并成 1 个长度为 n 的有序表。
void merge(int r[],int s[],int x1,int x2,int x3)
{
int i,j,k;
i=x1;
j=x2+1;
k=x1;
while(i<=x2 && j<=x3)
if(r[i]<=r[j])
{
s[k]=r[i];
i++;
k++;
}
else
{
s[k]=r[j];
j++;
k++;
}
while(i<=x2)
s[k++]=r[i++];
while(j<=x3)
s[k++]=r[j++];
}
void merge_sort(int r[],int s[],int m,int n)
{
int p;
int t[20];
if(m==n)
s[m]=r[m];
else
{
p=(m+n)/2;
merge_sort(r,t,m,p);
merge_sort(r,t,p+1,n);
merge(t,s,m,p,n);
}
}
查找
- 二分查找
二分查找就是折半查找,其基本思想是:首先选取表中间位置的记录,将其关键字与给定关键字 key 进行比较,若相等,则查找成功;若 key 值比该关键字值大,则要查找的元素一定在右子表中,则继续对右子表进行折半查找;若 key 值比该关键字值小,则要查找的元素一定在左子表中,继续对左子表进行折半查找。以此类推,直到查找成功或查找失败(查找范围为 0)。
void binary_search(int key,int a[],int n)
{
int low,mid,hight,count=0,count1=0;
low=0;
hight=n-1;
while(low<=hight) //一定不能写成low<hight
{
count++;
mid=(hight+low)/2;
if(key<a[mid])
{
hight=mid-1;
}
else if(key>a[mid])
low=mid+1;
else if(key==a[mid])
{
printf("查找成功!\n查找 %d 次!a[%d]",count,mid,key);
count1++;
break;
}
}
if(count1==0)
printf("查找失败!");
}
- 分块查找
分块查找也称为索引顺序查找,要求将待查的元素均匀地分成块,块间按大小排序,块内不排序,所以要建立一个块的最大(或最小)关键字表,称为索引表。当要查找关键字为 key 的元素时,先用顺序查找已建好的索引表中查出 key 所在的块中,再在对应的块中顺序查找 key,若 key 存在,则输出其相应位置,否则查找失败。
struct index
{
int key;
int start;
int end;
} index_table[4];
int block_search(int key, int a[])
{
int i, j;
i = 1;
while (i <= 3 && key > index_table[i].key)
{
i++;
}
if (i < 3)
{
return 0;
}
j = index_table[i].start;
while (j <= index_table[i].end && a[j] != key)
{
j++;
}
if (j > index_table[i].end)
{
j = 0;
}
return j;
}
字符串匹配
- Brute Force
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-svkjpKJ1-1620748213859)(http://192.168.3.157:10010/wp-content/uploads/2020/06/0ffa29c2-6c73-427f-8c21-ea1c527934eb-300x24.png)]
- Robin-Karp
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-L33WMXiV-1620748213862)(http://192.168.3.157:10010/wp-content/uploads/2020/06/fd46b8be-7067-4ce2-b7d3-2abb173029d3-300x34.png)]
-
Knuth-Morris-Pratt
-
BoyerMoore
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZH4IvbJa-1620748213866)(http://192.168.3.157:10010/wp-content/uploads/2020/06/d04a708e-f7df-4208-935e-9f1da7dce3dd-300x275.png)]
-
Horspool
-
Sunday
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gYhEA5Ob-1620748213868)(http://192.168.3.157:10010/wp-content/uploads/2020/06/371b1a53-ca2c-42ef-a225-f836ff28b1a1-272x300.png)]
其他
- 水仙花数
一个 3 位数,它的每个位上的数字的 3次幂之和等于它本身,1^3 + 5^3+ 3^3 = 153。
static void Main(string[] args)
{
for (int i = 100; i < 999; i++)
{
int hundred = i / 100;
int ten = (i % 100) / 10;
int one = i % 10;
if (Math.Pow(hundred, 3) + Math.Pow(ten, 3) + Math.Pow(one, 3) == i)
{
Console.WriteLine(i + " = " + hundred + "^3 + " + ten + "^3 + " + one + "^3");
}
}
}
- 斐波那契数列
斐波那契数列指的是这样一个数列:1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144...
这个数列从第3项开始,每一项都等于前两项之和。
public static void Main()
{
foreach (var i in Fibonacci().Take(20))
{
Console.WriteLine(i);
}
}
private static IEnumerable<int> Fibonacci()
{
int current = 1, next = 1;
while (true)
{
yield return current;
next = current + (current = next);
}
}
- 求素数
素数是只能被1和本身整除的数。
static void Main(string[] args)
{
for (int i = 1; i < 100; i++)
{
bool flag = true;
for (int j = 2; j <= (int)Math.Sqrt(i); j++)
{
if (i % j == 0)
{
flag = false;
break;
}
}
if (flag)
{
Console.WriteLine("I:" + i);
}
}
}