算法的学习1Word格式.docx
《算法的学习1Word格式.docx》由会员分享,可在线阅读,更多相关《算法的学习1Word格式.docx(18页珍藏版)》请在冰豆网上搜索。
for(intj=0;
j<
list.Length-i;
j++)
if(list[j]>
list[j+1])
inttemp=list[j];
list[j]=list[j+1];
list[j+1]=temp;
}
inti=list.Length;
while(i>
1)
intlastExchangeIndex=1;
for(intj=1;
i;
if(list[j]<
list[j-1])
list[j-1]=temp;
lastExchangeIndex=j;
i=lastExchangeIndex;
三。
C#算法选择排序
(总是选择一个最小的数字放到第一位)
intmin;
for(inti=0;
min=i;
for(intj=i+1;
list[min])
min=j;
intt=list[min];
list[min]=list[i];
list[i]=t;
四。
C#算法(四)快速排序
publicstaticvoidSort(int[]list,intlow,inthigh)
if(low<
high)
intpivot=list[low];
inti=low,j=high;
while(i<
j)
while(i<
j&
list[j]>
=pivot)
j--;
list[i]=list[j];
list[i]<
=pivot)
i++;
list[j]=list[i];
list[i]=pivot;
Sort(list,low,i-1);
Sort(list,i+1,high);
五。
C#算法(五)希尔排序
(就是在插入排序的基础上使用了一个增量inc,把一个数字分成了如干组进行插入排序,就是把插入排序中的1开始换成了inc开始)
先取一个小于n的整数d1作为第一个增量,把文件的全部记录分成d1个组。
所有距离为dl的倍数的记录放在同一个组中。
先在各组内进行直接插人排序;
然后,取第二个增量d2<
d1重复上述的分组和排序,直至所取的增量
dt=1(dt<
dt-l<
…<
d2<
d1),即所有记录放在同一组中进行直接插入排序为止。
该方法实质上是一种分组插入方法
intinc=1;
while(inc<
=list.Length/9)
inc=3*inc+1;
for(;
inc>
0;
inc/=3)
for(inti=inc;
i+=inc)
(list[j-inc]>
list[j]=list[j-inc];
j=j-inc;
六、C#中的堆排序(0.0)
1
/*
2
堆排序
3
(1)用大根堆排序的基本思想
4
①
先将初始文件R[1..n]建成一个大根堆,此堆为初始的无序区
5
②
再将关键字最大的记录R[1](即堆顶)和无序区的最后一个记录R[n]交换,
6
由此得到新的无序区R[1..n-1]和有序区R[n],且满足R[1..n-1].keys≤R[n].key
7
③
由于交换后新的根R[1]可能违反堆性质,故应将当前无序区R[1..n-1]调整为堆。
8
然后再次将R[1..n-1]中关键字最大的记录R[1]和该区间的最后一个记录R[n-1]交换,
9
由此得到新的无序区R[1..n-2]和有序区R[n-1..n],且仍满足关系R[1..n-
2].keys≤R[n-1..n].keys,
10
同样要将R[1..n-2]调整为堆。
11
……
12
直到无序区只有一个元素为止。
13
(2)大根堆排序算法的基本操作:
14
初始化操作:
将R[1..n]构造为初始堆;
15
每一趟排序的基本操作:
将当前无序区的堆顶记录R[1]和该区间的最后一个记录交换,然后将新的无序区调整为堆(亦称重建堆)。
16
注意:
17
①只需做n-1趟排序,选出较大的n-1个关键字即可以使得文件递增有序。
18
②用小根堆排序与利用大根堆类似,只不过其排序结果是递减有序的。
19
堆排序和直接选择排序相反:
在任何时刻,堆排序中无序区总是在有序区之前,
20
且有序区是在原向量的尾部由后往前逐步扩大至整个向量为止。
21
*/
22
23
//生成大根堆
24
publicstaticvoidHeapAdjust(int[]SortData,intStartIndex,intLength)
while(2*StartIndex+1<
Length)
intMinChildrenIndex=2*StartIndex+1;
if(2*StartIndex+2<
Length)
//比较左子树和右子树,记录最大值的Index
if(SortData[2*StartIndex+1]<
SortData[2*StartIndex+2])
MinChildrenIndex=2*StartIndex+2;
if(SortData[StartIndex]<
SortData[MinChildrenIndex])
//交换i与MinChildrenIndex的数据
inttmpData=SortData[StartIndex];
SortData[StartIndex]=SortData[MinChildrenIndex];
SortData[MinChildrenIndex]=tmpData;
//堆被破坏,需要重新调整
StartIndex=MinChildrenIndex;
//比较左右孩子均大则堆未破坏,不再需要调整
break;
return;
//堆排序
publicstaticvoidHeapSortData(int[]SortData)
{
inti=0;
intLength=SortData.Length;
//将Hr[0,Lenght-1]建成大根堆
for(i=Length/2-1;
i>
=0;
i--)
HeapAdjust(SortData,i,Length);
for(i=Length-1;
0;
//与最后一个记录交换
inttmpData=SortData[0];
SortData[0]=SortData[i];
SortData[i]=tmpData;
//将H.r[0..i]重新调整为大根堆
HeapAdjust(SortData,0,i);
}
七、C#中的归并算法
publicstaticvoidSort(int[]list,intlow,inthigh)
if(low>
intmid=(low+high)/2;
Sort(list,low,mid);
Sort(list,mid+1,high);
Merge(list,low,mid,high);
publicstaticvoidMerge(int[]list,intlow,intmid,inthigh)
int[]array=newint[high-low+1];
intindex=0;
intleft=low;
intright=mid+1;
while(left<
=mid&
right<
if(list[left]<
list[right])
array[index++]=list[left++];
array[index++]=list[right++];
=mid)
while(right<
for(index=0;
index<
array.Length;
index++)
list[low+index]=array[index];
第二大类:
线性表(一般的线性表,栈,队列)的插入和删除
一、线性表的插入、删除
二、栈的插入、删除
三、队列的插入、删除
第三大类:
二叉树的遍历(前序,中序,后序)
一、二叉树的前序排列(递归、非递归)
二、二叉树的中序排列(递归、非递归)
三、二叉树的后序排列(递归、非递归)
第四大类:
图的遍历(深度优先,广度优先)
一、图的深度遍历
二、图的广度优先
第五大类:
线性查找(顺序查找),二分法查找(代码五行以内),散列查找,排序二叉树,Hash查找(处理冲突的方法)。
第六大类:
KMP算法、BFS、DFS、同时熟练hash表(要熟,要灵活,代码要简)
第一阶段:
练经典常用算法,下面的每个算法给我打上十到二十遍,同时自己精简代码,
因为太常用,所以要练到写时不用想,10-15分钟内打完,甚至关掉显示器都可以把程序打
出来.
1.最短路(Floyd、Dijstra,BellmanFord)
2.最小生成树(先写个prim,kruscal要用并查集,不好写)
3.大数(高精度)加减乘除
4.叉乘、判线段相交、然后写个凸包.
5.数学上的有:
辗转相除(两行内),线段交点、多角形面积公式.
6.调用系统的qsort,技巧很多,慢慢掌握.
7.任意进制间的转换
第二阶段:
练习复杂一点,但也较常用的算法。
如:
1.二分图匹配(匈牙利),最小路径覆盖
2.网络流,最小费用流。
3.线段树.
4.并查集。
5.熟悉动态规划的各个典型:
LCS、最长递增子串、三角剖分、记忆化dp
6.博弈类算法。
博弈树,二进制法等。
7.最大团,最大独立集。
8.判断点在多边形内。
9.差分约束系统.
10.双向广度搜索、A*算法,最小耗散优先.
求一个数组的最大子数组之和?
//Description:
求一个数组的子数组的最大的和
//============================================================================
#include<
iostream>
usingnamespacestd;
/**
*两者的最大值
*/
intmax(intx,inty){
return(x>
y)?
x:
y;
*求一个数组的子数组的最大的和
*@description:
动态规划(将N规模的降低到N-1)
*@detail:
假设已经知道(A[1],A[2]...A[n-1])中和最大的一段之和为All[1],且知道(A[1],A[2]...A[n-1])
*包含A[1]的和最大的一段和为Start[1],那么ALL[0]=max(A[0],A[0]+Start[1],All[1]);
符合动态规划的
*无后效性,可以使用动态规划
intmaxSum(int*A,intn){
intnStart=A[n-1];
intnAll=A[n-1];
for(inti=n-2;
i>
-0;
i--){
nStart=max(A[i],nStart+A[i]);
nAll=max(nStart,nAll);
returnnAll;
intmain(){
intA[]={1,-2,3,5,5,9,-3,-2};
intsum=maxSum(A,sizeof(A)/sizeof(A[0]));
cout<
<
sum<
endl;
return0;
穷举搜索法
求解“百钱买百鸡”,公鸡每只5钱,母鸡每只3钱,小鸡每3只1钱
分析:
x+y+z=100
5*x+3*y+z/3=100
1.voidmain()
intx,y,z;
for(x=0;
x<
=100;
x++)
for(y=0;
y<
y++)
for(z=0;
z<
z++)
if(x+y+z=100&
5*x+3*y+z/3=100)
printf("
%d%d%d\n"
x,y,z)
2.voidmain()
=20;
=33;
{z=100-x-y;
if(z%3=0&
六。
递归法
汉诺塔问题
(n阶汉诺塔问题)假设有三个分别命名为A,B和C的塔座,在塔座A上插有n个直径大小各不相同,按小到大编号为1,2,。
。
,n的圆盘。
现要求将A轴上的n个圆盘移至C上并按同样顺序叠排,圆盘移动时必须遵循下列规则:
1)每次只能移动一个圆盘;
2)圆盘可以插在A,B和C中的任一塔座上;
3)任何时刻都不能将一个较大的圆盘压在较小的圆盘之上。
studio.h>
voidmove(intn,chara,charc)
staticintstep=1;
step%2d:
disk%d%c------->
%c\n"
step,n,a,c)
step++;
}
voidHanoi(intn,chara,charb,charc)
if(n>
1)
Hanoi(n-1,a,c,b);
//先将前n-1个盘子从a通过c搬到b
move(n,a,c);
//将第n个盘子从a搬到c
Hanoi(n-1,b,a,c);
//再将这前n-1个盘子从b通过a搬到c
//将这1个盘子从a搬到c
voidmain()
{Hanoi(3,'
A'
'
B'
C'
);
七。
回溯法
求解迷宫问题。
迷宫用一个二维数组表示,其元素值有两个:
0和1,0表示通路,1表示阻塞,数组左上房[0][0]元素为迷宫入口,右下房[m-1][n-1]元素为迷宫的出口,现在寻找一条从入口到出口的通路(并不一定是最短的)。
#defineM12
#defineN15
voidmaze(intp[][],intm,intn)
intis[8]={0,1,1,1,0,-1,-1,-1};
//行前进方向:
右,右下,下,左下,左,左上,上,右上
intjs[8]={1,1,0,-1,-1,-1,0,-1};
//列前进方向:
intstack[3*M*N],*top;
inti,j,v,g,h,jt;
top=stack;
i=j=v=0;
if(p[0][0]!
=0)//入口无路可走,提示无路,返回;
p[0][0]=4;
printf("
nopath!
\n"
;
return;
)
while(top!
=stack||v!
=7)
g=i+is[v];
h=j+js[v];
jt=0;
if(g>
-1&
g<
m&
h>
h<
n)
{if(g==m-1&
h==n-1&
p[m-1][n-1]==0)
p[i][j]=8;
p[g][h]=8;
//找到路径,停止返回;
if(p[g][h]==0)
p[g][h]=4;
//前一步位置上置8
top+=3;
top[0]=i;
top[1]=j;
top[2]=v;
//入栈,记录下前一步
i=g;
j=h;
v=0;
jt=1;
if(jt==0)
if(v<
7)v++;
//换一个方向
stack&
top[2]==7)
p[top[0]][top[1]]=4;
//无路,栈中元素置为4,并弹栈
top-=3;
if(top!
=stack)
i=top[0];
j=top[1];
v=top[2];
//回溯,弹栈
p[i][j]=4;
top-=3;
//无路可走,提示无路,返回
inti,j;
intp[M][N]={
{0,1,0,0,0,1,1,0,0,0,1,1,1,1,1}
{1,0,0,0,1,1,0,1,1,1,0,0,1,1,1}
{0,1,1,0,0,0,0,1,1,1,1,0,0,1,1}
{1,1,0,1,1,1,1,0,1,1,0,1,1,0,0}
{1,1,0,1,1,1,1,0,1,1,0,1,1,0,0}
{1,1,0,1,0,0,1,0,1,1,1,1,1,1,1}
{0,0,1,1,0,1,1,1,0,1,0,0,1,1,1}
{0,1,1,1,1,0,0,1,1,1,1,1,1,1,1}
{0,0,1,1,0,1,1,0,1,1,1,1,1,0,1}
{1,1,0,0,0,1,1,0,1,1,0,0,0,0,0}
{0,0,1,1,1,1,1,0,0,0,1,1,1,1,0}
{0,1,0,0,1,1,1,1,1,0,1,1,1,1,0}
maze(p,12,15)
结果:
{8,1,0,0,0,1,1,4,4,4,1,1,1,1,1}
{1,8,8,8,1,1,4,1,1,1,4,4,1,1,1}
{0,1,1,8,8,4,4,1,1,1,1,4,4,1,1}
{1,1,8,1,1,1,1,4,1,1,4,1,1,4,4}
{1,1,8,1,1,1,1,4,1,1,4,1,1,4,4}
{1,1,8,1,0,0,1,4,1,1,1,1,1,1,1}
{0,8,1,1,1,1,1,1,4,1,0,0,1,1,1}
{8,1,1,1,1,8,8,1,1,1,1,1,1,1,1}
{0,8,1,1,8,1,1,8,1,1,1,1,1,0,1}
{1,1,8,8,8,1,1,8,1,1,8,8,8,8,8}
{0,0,1,1,1,1,1,0,8,8,1,1,1,1,8}
{0,1,0,0,1,