一些常见算法的java实现.docx
《一些常见算法的java实现.docx》由会员分享,可在线阅读,更多相关《一些常见算法的java实现.docx(61页珍藏版)》请在冰豆网上搜索。
一些常见算法的java实现
packageAbout4Algorithm;
importjava.util.ArrayList;
//解决方案1
//测试一个链表是否是循环链表java实现
//当一个链表的尾节点的下一个节点和头节点一样时,此链表即为循环链表
//解决方案2
//例如N1->N2->N3->N4->N5->N2就是一个有环的链表,
//环的开始结点是N5这里有一个比较简单的解法。
//设置两个指针p1,p2。
每次循环p1向前走一步,p2向前走两步。
//直到p2碰到NULL指针或者两个指针相等结束循环。
如果两个指针相等则说明存在环。
classListItem{
ListItemprevoius;
ListItemnext;
Stringdata;
//构造器,可传入参数对链表进行初始化;
publicListItem(ListItemprevious,Stringdata,ListItemnext){
this.prevoius=previous;
this.data=data;
this.next=next;
}
publicListItemgetPrevoius(){
returnprevoius;
}
publicvoidsetPrevoius(ListItemprevoius){
this.prevoius=prevoius;
}
publicListItemgetNext(){
returnnext;
}
publicvoidsetNext(ListItemnext){
this.next=next;
}
publicStringgetData(){
returndata;
}
publicvoidsetData(Stringdata){
this.data=data;
}
}
publicclassCircularLinkedListTest{
publicstaticvoidmain(String[]args){
//初始化List
ListItema=newListItem(null,"a",null);
ListItemb=newListItem(null,"b",null);
ListItemc=newListItem(null,"c",null);
ListItemd=newListItem(null,"d",null);
a.setPrevoius(d);
a.setNext(b);
b.setPrevoius(a);
b.setNext(c);
c.setPrevoius(b);
c.setNext(d);
d.setPrevoius(c);
d.setNext(a);
//新建存放链表的数组
ArrayListlist=newArrayList();
list.add(a);
list.add(b);
list.add(c);
list.add(d);
//判断是否为循环链表
booleancircular=false;
//ListItemstart=a;
ListItemcurrent1=a;
ListItemcurrent2=a;
for(inti=0;i//current2.next.next中为null时,表示链表不是循环的.
if(current2.next.next!
=null){
current1=current1.next;
current2=current2.next.next;
if(current1.equals(current2)){
circular=true;
}
}
}
if(circular){
System.out.println("是循环链表");
}
else{
System.out.println("不是循环链表");
}
}
}
packageAbout4Algorithm;
importjava.util.ArrayList;
//找出单链表的中间节点
//这道题和解判断链表是否存在环,我用的是非常类似的方法,只不过结束循环的条件和函数返回值不一样罢了。
//设置两个指针p1,p2。
每次循环p1向前走一步,p2向前走两步。
当p2到达链表的末尾时,p1指向的时链表的中间。
//创建一个链表的类
classLink{
privateLinknext;
privateStringdata;
Link(Linknext,Stringdata){
this.next=next;
this.data=data;
}
publicLinkgetNext(){
returnnext;
}
publicvoidsetNext(Linknext){
this.next=next;
}
publicStringgetData(){
returndata;
}
publicvoidsetData(Stringdata){
this.data=data;
}
}
publicclassFindMidNodeOfLinkedList{
publicstaticvoidmain(String[]args){
//对链表进行初始化
Linkl1=newLink(null,"a");
Linkl2=newLink(null,"b");
Linkl3=newLink(null,"c");
Linkl4=newLink(null,"d");
Linkl5=newLink(null,"e");
Linkl6=newLink(null,"f");
l1.setNext(l2);
l2.setNext(l3);
l3.setNext(l4);
l4.setNext(l5);
l5.setNext(l6);
l6.setNext(null);
//将链表保存在ArrayList中
ArrayListlist=newArrayList();
list.add(l1);
list.add(l2);
list.add(l3);
list.add(l4);
list.add(l5);
list.add(l6);
Linkcurrent1=null;
current1=l1;
Linkcurrent2=l1;
//每次循环p1向前走一步,p2向前走两步。
当p2到达链表的末尾时,p1指向的时链表的中间。
for(inti=0;iif(current2.getNext().getNext()!
=null){
current1=current1.getNext();
current2=current2.getNext().getNext();
}
}
System.out.println(current1.getData());
}
}
packageAbout4Algorithm;
//求解约瑟环问题
//15个教徒和15个非教徒在深海上遇险,必须将一半的人投入海中,其余的人才能幸免遇难
//30个人围成一个圆圈,从第一个人开始一次报数,每数到第九个人,就将他扔入大海
//如此循环,直到仅余15人为止
//方案1
//使用一个boolean数组,一开始,全部位置为true
//每数到9时,就将其设为false,则此位置为非教徒的位置
//如果该位置已经为false,则设置下一个true位置为false
//如果已经循环到底,则从第一个开始
publicclassJosephRing{
publicstaticvoidmain(String[]args){
//有一个boolean数组记录当前的30个人,扔下还的人为false,还留下的人为true
boolean[]flag=newboolean[30];
//try{
for(inti=0;iflag[i]=true;
}
//}catch(ArrayIndexOutOfBoundsExceptione){
////System.out.println("异常!
");
//e.printStackTrace();
//e.getStackTrace();
//}
//记录当前还剩下的人
intleftPeople=flag.length;
//记录每数到9的时候,这个人就该被扔下海
intcountNum=0;
//记录当前指向的人
intindex=0;
while(leftPeople>15){
//计数器+1
countNum++;
//当计数器数到9时,进入
if(countNum==9){
//如果当前的数已经为false了,证明这个人已经被扔进了大海
//那么就找其下一个为true的人扔进大海
while(flag[index]!
=true){
countNum++;
index++;
}
//计数器清零,把当前人设为false,leftPeople-1
countNum=0;
flag[index]=false;
leftPeople--;
}
//指针向下移动,当index和数组大小一致时,从头开始
index++;
if(index==flag.length){
index=0;
}
}
intcount=0;
for(inti=0;icount++;
System.out.print(flag[i]+"");
if(count%5==0){
System.out.println();
}
}
}
}
packageAbout4Algorithm;
importjava.util.ArrayList;
//单链表反转问题
//单向链表的反转是一个经常被问到的一个面试题,也是一个非常基础的问题。
//比如一个链表是这样的:
1->2->3->4->5通过反转后成为5->4->3->2->1。
//最容易想到的方法遍历一遍链表,利用一个辅助指针,存储遍历过程中当前指针指向的下一个元素,
//然后将当前节点元素的指针反转后,利用已经存储的指针往后面继续遍历
classLinkItem1{
LinkItem1next;
Stringdata;
publicLinkItem1(){
//TODOAuto-generatedconstructorstub
}
publicLinkItem1getNext(){
returnnext;
}
publicvoidsetNext(LinkItem1next){
this.next=next;
}
publicStringgetData(){
returndata;
}
publicvoidsetData(Stringdata){
this.data=data;
}
}
publicclassLinkedListReverse{
publicstaticvoidreverse(){
//初始化链表
LinkItem1a=newLinkItem1();
LinkItem1b=newLinkItem1();
LinkItem1c=newLinkItem1();
LinkItem1d=newLinkItem1();
LinkItem1e=newLinkItem1();
LinkItem1f=newLinkItem1();
a.setData("a");
a.setNext(b);
b.setData("b");
b.setNext(c);
c.setData("c");
c.setNext(d);
d.setData("d");
d.setNext(e);
e.setData("e");
e.setNext(f);
f.setData("f");
f.setNext(null);
//新建存放链表的数组
ArrayListlist=newArrayList();
list.add(a);
list.add(b);
list.add(c);
list.add(d);
list.add(e);
list.add(f);
//定义链表的前驱为previous;
LinkItem1previous=a;
//定义链表的当前节点为current;
LinkItem1current=previous.next;
//定义链表的后继节点为next;
LinkItem1next;
for(inti=0;iif(current.next!
=null){
//当前节点的后继传给next
next=current.next;
//将前驱的节点传给当前的后继
current.next=previous;
//将
previous=current;
current=next;
}
}
//a.next=null;
//a=previous;
//System.out.println(previous.next.getData());
//for(intj=0;j//System.out.println(previous.getData());
//previous=previous.next;
//}
}
publicstaticvoidmain(String[]args){
reverse();
}
}
packageAbout4Algorithm;
//单例模式
publicclassSingleton{
privatestaticSingletoninstance=null;
//私有构造函数,不允许在外部被实例化
privateSingleton(){
}
//静态公有函数,只会实例化一次
publicstaticSingletongetInstance(){
if(instance==null){
instance=newSingleton();
}
returninstance;
}
publicstaticvoidmain(String[]args){
Singletons1=Singleton.getInstance();
Singletons2=Singleton.getInstance();
System.out.println(s1==s2);
System.out.println(s1);
System.out.println(s2);
}
}
packageAbout4Algorithm;
//java实现折半查找问题
publicclassBinarySearch{
//实现二分查找函数
publicstaticbooleanbinarySearch(int[]a,intx){
intmin=0;
intmid=0;
intmax=0;
max=a.length-1;
while(min<=max){
mid=(min+max)/2;
if(a[mid]min=mid+1;
}
elseif(a[mid]>x){
max=mid-1;
}
else{
returntrue;
}
}
returnfalse;
}
//给出的a数列必须是有序的..如果想算法更加完美可以对a先进行排序再查找
publicstaticvoidmain(String[]args){
int[]a={-5,-4,-2,11,13};
intx=11;
booleanresult=binarySearch(a,x);
System.out.println(result);
}
}
packageAbout4Algorithm;
//最大子序列和问题
publicclassTest1{
//联机算法复杂度求解最大自序列和问题函数
publicstaticintmaxSubSum(int[]a){
intmaxSum=0;
intthisSum=0;
for(intj=0;jthisSum+=a[j];
if(thisSum>maxSum){
maxSum=thisSum;
}elseif(thisSum<0){
thisSum=0;
}
}
returnmaxSum;
}
publicstaticvoidmain(String[]args){
int[]a={-2,11,-4,13,-5,-2};
intresult=maxSubSum(a);
System.out.println("Result="+result);
}
}
packageAbout4Algorithm;
//计算最大公因数
publicclassTest3{
publicstaticintgcb(intm,intn){
while(n!
=0){
inttemp=m%n;
m=n;
n=temp;
}
returnm;
}
publicstaticvoidmain(String[]args){
intresult=gcb(200,57);
System.out.println(result);
}
}
packageAbout4Algorithm;
importjava.util.ArrayList;
//对文件进行遍历
classFolder{
privateArrayListlist=newArrayList();
//当发现是文件夹是,遍历文件夹里的所有内容
publicvoidscan(){
System.out.println("遍历文件夹...");
for(Folderf:
list){
((Folder)f).scan();
}
}
publicvoidadd(Foldere){
list.add(e);
}
}
classFileextendsFolder{
publicvoidscan(){
System.out.println("遍历文件...");
}
}
publicclassTest4{
publicstaticvoidmain(String[]args){
Folderfolder1,folder2,folder3;
folder1=newFolder();
folder2=newFolder();
folder3=newFolder();
Filef1,f2,f3;
f1=newFile();
f2=newFile();
f3=newFile();
folder1.add(f1);
folder2.add(folder1);
folder3.add(f2);
folder3.add(f3);
folder3.add(f2);
folder3.add(folder2);
folder3.scan();
}
}
packageAbout4Algorithm;
//判断两个数组中是否有相同的数字
//方案1
//给定两个排好序的数组,怎样高效得判断这两个数组中存在相同的数字?
//这个问题首先想到的是一个O(nlogn)的算法。
//就是任意挑选一个数组,遍历这个数组的所有元素,
//遍历过程中,在另一个数组中对第一个数组中的每个元素进行binarysearch。
public