数据结构经典算法20篇.docx
《数据结构经典算法20篇.docx》由会员分享,可在线阅读,更多相关《数据结构经典算法20篇.docx(53页珍藏版)》请在冰豆网上搜索。
![数据结构经典算法20篇.docx](https://file1.bdocx.com/fileroot1/2022-11/27/eb282aba-9a68-49dd-b4ea-011da43f7669/eb282aba-9a68-49dd-b4ea-011da43f76691.gif)
数据结构经典算法20篇
1:
最大字段问题
/**
*
*/
packagecom.gaohongming.acm;
/**
*@authorgaohongming
*
*/
publicclassNMSum{
publicstaticvoidSum(int[]a,intm){
intn=a.length;//n为数组中的个数
int[][]b=newint[n+1][m+1];
int[][]SUM=newint[n+1][m+1];
for(intp=0;p<=n;p++){//一个子段获数字都不取时//
b[p][0]=0;
SUM[p][0]=0;
}
//for(intp=0;p<=m;p++){//当p>0时并无意义,此部分不会被用到,注释掉
//b[0][p]=0;
//SUM[0][p]=0;
//}
for(intj=1;j<=m;j++){
for(inti=j;i<=n-m+j;i++){
//n=1m=1此时最大1子段为a[0]java数组为从0开始的需要注意后面所有的第i个数为a[i-1];
if(i==1){
b[i][j]=a[i-1];
SUM[i][j]=a[i-1];
}else
{
//先假设第i个数作为最后一个子段的一部分
b[i][j]=b[i-1][j]+a[i-1];
//若第i个数作为单独子段时b[i][j]更大则把a[i-1]作为单独子段
//考虑特殊情况若第一个数字为负数b[1][1]为负数在求b[2][1]SUM[1][0]=0>b[1][1]则舍去第一个数字此处合理
if(SUM[i-1][j-1]+a[i-1]>b[i][j])b[i][j]=SUM[i-1][j-1]+a[i-1];
//填写SUM[i][j]供以后使用
if(j
if(b[i][j]>SUM[i-1][j]){//用b[i][j]与之前求的比较
SUM[i][j]=b[i][j];
}else{
SUM[i][j]=SUM[i-1][j];
}
}else//i=j
{
SUM[i][j]=SUM[i-1][j-1]+a[i-1];
}
}
}//endfor
}//endfor
System.out.println(SUM[n][m]);//输出结果
}//endofmethod
publicstaticvoidmain(String[]args){
int[]a=newint[]{1,-2,3,4,-5,-6,7,18,-9};
Sum(a,3);
}
}
2:
Dijkstra算法
/**
*
*/
packagecom.gaohongming.acm;
/**
*@authorgaohongming
*
*/
publicclassDijkstra{
privatestaticintN=1000;
privatestaticint[][]Graph={
{0,1,5,N,N,N,N,N,N},
{1,0,3,7,5,N,N,N,N},
{5,3,0,N,1,7,N,N,N},
{N,7,N,0,2,N,3,N,N},
{N,5,1,2,0,3,6,9,N},
{N,N,7,N,3,0,N,5,N},
{N,N,N,3,6,N,0,2,7},
{N,N,N,N,9,5,2,0,4},
{N,N,N,N,N,N,7,4,0}};
publicstaticvoidmain(String[]args){
dijkstra(0,Graph);
}
/**
*Dijkstra最短路径。
*即图中"节点vs"到其它各个节点的最短路径。
*@paramvs起始节点
*@paramGraph图
*/
publicstaticvoiddijkstra(intvs,int[][]Graph){
intNUM=Graph[0].length;
//前驱节点数组
int[]prenode=newint[NUM];
//最短距离数组
int[]mindist=newint[NUM];
//该节点是否已经找到最短路径
boolean[]find=newboolean[NUM];
intvnear=0;
for(inti=0;iprenode[i]=i;
mindist[i]=Graph[vs][i];
find[i]=false;
}
find[vs]=true;
for(intv=1;v//每次循环求得距离vs最近的节点vnear和最短距离min
intmin=N;
for(intj=0;jif(!
find[j]&&mindist[j]min=mindist[j];
vnear=j;
}
}
find[vnear]=true;
//根据vnear修正vs到其他所有节点的前驱节点及距离
for(intk=0;kif(!
find[k]&&(min+Graph[vnear][k])prenode[k]=vnear;
mindist[k]=min+Graph[vnear][k];
}
}
}
for(inti=0;iSystem.out.println("v"+vs+"...v"+prenode[i]+"->v"+i+",s="+mindist[i]);
}
}
}
3:
深度优先遍历和广度优先遍历
/**
*
*/
packagecom.gaohongming.acm;
importjava.util.ArrayDeque;
/**
*@authorgaohongming
*广度优先遍历和神父优先遍历
*/
publicclassBinaryTree{
staticclassTreeNode{
intvalue;
TreeNodeleft;
TreeNoderight;
publicTreeNode(intvalue){
this.value=value;
}
}
TreeNoderoot;
publicBinaryTree(int[]array){
root=makeBinaryTreeByArray(array,1);
}
/**
*采用递归的方式创建一颗二叉树
*传入的是二叉树的数组表示法
*构造后是二叉树的二叉链表表示法
*/
publicstaticTreeNodemakeBinaryTreeByArray(int[]array,intindex){
if(indexintvalue=array[index];
if(value!
=0){
TreeNodet=newTreeNode(value);
array[index]=0;
t.left=makeBinaryTreeByArray(array,index*2);
t.right=makeBinaryTreeByArray(array,index*2+1);
returnt;
}
}
returnnull;
}
/**
*深度优先遍历,相当于先根遍历
*采用非递归实现
*需要辅助数据结构:
栈
*/
publicvoiddepthOrderTraversal(){
if(root==null){
System.out.println("emptytree");
return;
}
ArrayDequestack=newArrayDeque();
stack.push(root);
while(stack.isEmpty()==false){
TreeNodenode=stack.pop();
System.out.print(node.value+"");
if(node.right!
=null){
stack.push(node.right);
}
if(node.left!
=null){
stack.push(node.left);
}
}
System.out.print("\n");
}
/**
*广度优先遍历
*采用非递归实现
*需要辅助数据结构:
队列
*/
publicvoidlevelOrderTraversal(){
if(root==null){
System.out.println("emptytree");
return;
}
ArrayDequequeue=newArrayDeque();
queue.add(root);
while(queue.isEmpty()==false){
TreeNodenode=queue.remove();
System.out.print(node.value+"");
if(node.left!
=null){
queue.add(node.left);
}
if(node.right!
=null){
queue.add(node.right);
}
}
System.out.print("\n");
}
/**
*13
*/\
*655
*/\\
*972537
*//\/
*2242832
*/
publicstaticvoidmain(String[]args){
int[]arr={0,13,65,5,97,25,0,37,22,0,4,28,0,0,32,0};
BinaryTreetree=newBinaryTree(arr);
tree.depthOrderTraversal();
tree.levelOrderTraversal();
}
}
4:
线性查找
/**
*
*/
packagecom.gaohongming.acm;
/**
*@authorgaohongming
*线性查找
*/
publicclassLineSearch{
publicstaticvoidmain(String[]args){
//TODOAuto-generatedmethodstub
//输入数据数组
int[]a={12,76,29,22,15,62,29,58,35,67,58,33,28,89,90,
28,64,48,20,77};
LineSearchline=newLineSearch();
line.lineSearch(a,22);
}
/**
*线性查找
*@parama
*@parame
*/
privatevoidlineSearch(int[]a,inte){
//TODOAuto-generatedmethodstub
//数据索引计数变量
intcount=1;
for(inti=0;i//输出数据
System.out.println("当前数据是:
"+a[i]);
if(e==a[i]){
System.out.println("共比较次数为:
"+count+"在数组中的索引是:
"+i);
break;
}
if(i==a.length-1&&e!
=a[i]){
System.out.println("数据不存在!
");
System.out.println("共比较次数为:
"+count);
}
count++;
}
}
}
5:
二分查找算法
/**
*
*/
packagecom.gaohongming.acm;
/**
*@authorgaohongming
*
*/
publicclassBinarySearch{
/**
*二分查找算法
*
*@paramsrcArray有序数组
*@paramkey查找元素
*@returnkey的数组下标,没找到返回-1
*/
publicstaticvoidmain(String[]args){
intsrcArray[]={3,5,11,17,21,23,28,30,32,50,64,78,81,95,101};
System.out.println(binSearch(srcArray,0,srcArray.length-1,81));
}
//二分查找递归实现
publicstaticintbinSearch(intsrcArray[],intstart,intend,intkey){
intmid=(end-start)/2+start;
if(srcArray[mid]==key){
returnmid;
}
if(start>=end){
return-1;
}elseif(key>srcArray[mid]){
returnbinSearch(srcArray,mid+1,end,key);
}elseif(keyreturnbinSearch(srcArray,start,mid-1,key);
}
return-1;
}
//二分查找普通循环实现
publicstaticintbinSearch(intsrcArray[],intkey){
intmid=srcArray.length/2;
if(key==srcArray[mid]){
returnmid;
}
intstart=0;
intend=srcArray.length-1;
while(start<=end){
mid=(end-start)/2+start;
if(keyend=mid-1;
}elseif(key>srcArray[mid]){
start=mid+1;
}else{
returnmid;
}
}
return-1;
}
}
6:
堆排序
/**
*
*/
packagecom.gaohongming.acm;
/**
*@authorgaohongming
*堆排序
*/
publicclassHeapSortTest{
publicstaticvoidmain(String[]args){
int[]data5=newint[]{5,3,6,2,1,9,4,8,7};
print(data5);
heapSort(data5);
System.out.println("排序后的数组:
");
print(data5);
}
publicstaticvoidswap(int[]data,inti,intj){
if(i==j){
return;
}
data[i]=data[i]+data[j];
data[j]=data[i]-data[j];
data[i]=data[i]-data[j];
}
publicstaticvoidheapSort(int[]data){
for(inti=0;icreateMaxdHeap(data,data.length-1-i);
swap(data,0,data.length-1-i);
print(data);
}
}
publicstaticvoidcreateMaxdHeap(int[]data,intlastIndex){
for(inti=(lastIndex-1)/2;i>=0;i--){
//保存当前正在判断的节点
intk=i;
//若当前节点的子节点存在
while(2*k+1<=lastIndex){
//biggerIndex总是记录较大节点的值,先赋值为当前判断节点的左子节点
intbiggerIndex=2*k+1;
if(biggerIndex//若右子节点存在,否则此时biggerIndex应该等于lastIndex
if(data[biggerIndex]//若右子节点值比左子节点值大,则biggerIndex记录的是右子节点的值
biggerIndex++;
}
}
if(data[k]//若当前节点值比子节点最大值小,则交换2者得值,交换后将biggerIndex值赋值给k
swap(data,k,biggerIndex);
k=biggerIndex;
}else{
break;
}
}
}
}
publicstaticvoidprint(int[]data){
for(inti=0;iSystem.out.print(data[i]+"\t");
}
System.out.println();
}
}
7:
快速排序
/**
*
*/
packagecom.gaohongming.acm;
/**
*@authorgaohongming
*快速排序
*/
publicclassFastSort{
publicstaticvoidmain(String[]args){
System.out.println("HelloWorld");
int[]a={12,20,5,16,15,1,30,45,23,9};
intstart=0;
intend=a.length-1;
sort(a,start,end);
for(inti=0;iSystem.out.println(a[i]);
}
}
publicstaticvoidsort(int[]a,intlow,inthigh){
intstart=low;
intend=high;
intkey=a[low];
while(end>start){
//从后往前比较
while(end>start&&a[end]>=key)//如果没有比关键值小的,比较下一个,直到有比关键值小的交换位置,然后又从前往后比较
end--;
if(a[end]<=key){
inttemp=a[end];
a[end]=a[start];
a[start]=temp;
}
//从前往后比较
while(end>start&&a[start]<=key)//如果没有比关键值大的,比较下一个,直到有比关键值大的交换位置
start++;
if(a[start]>=key){
inttemp=a[start];
a[start]=a[end];
a[end]=temp;
}
//此时第一次循环比较结束,关键值的位置已经确定了。
左边的值都比关键值小,右边的值都比关键值大,但是两边的顺序还有可能是不一样的,进行下面的递归调用
}
//递归
if(start>low)sort(a,low,start-1