Java经典问题算法大全


Java经典问题算法大全 /*【程序1】 题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少?  1.程序分析: 兔子的规律为数列1,1,2,3,5,8,13,21....  */ package cn.com.flywater.FiftyAlgorthm; public class FirstRabbit { public static final int MONTH = 15; public static void main(String[] args) {    long f1 = 1L, f2 = 1L;    long f;    for(int i=3; ik,但n能被k整除,则应打印出k的值,并用n除以k的商,作为新的正整数你n,重复执行第一步。  (3)如果n不能被k整除,则用k+1作为k的值,重复执行第一步。 */ package cn.com.flywater.FiftyAlgorthm; import java.util.Scanner; public class FourthPrimeFactor { static int n, k = 2; public static void main(String[] args) {    Scanner s = new Scanner(System.in);    n = s.nextInt();    System.out.print(n + "=" );    FourthPrimeFactor fpf = new FourthPrimeFactor();    fpf.f(n); } public void f(int n) {    while(k <= n) {     if(k == n) {      System.out.println(n);      break;     } else if(n > k && n % k == 0) {      System.out.print(k + "*");      n = n / k;       f(n);      break;     } else if(n > k && n % k != 0) {      k++;      f(n);      break;     }    } }   } /*【程序5】   题目:利用条件运算符的嵌套来完成此题:学习成绩>=90分的同学用A表示,60-89分之间的用B表示,60分以下的用C表示。  1.程序分析:(a>b)?a:b这是条件运算符的基本例子。 */ package cn.com.flywater.FiftyAlgorthm; import java.util.Scanner; public class FifthCondition { //public static final int S1 = 90; //public static final int S2 = 60; static int grade; public static void main(String[] args) {    Scanner str = new Scanner(System.in);    int s = str.nextInt();    FifthCondition fc = new FifthCondition();    grade = fc.compare(s);    if(grade == 1) {     System.out.print('A');    } else if(grade == 2) {     System.out.print('B');    } else {     System.out.println('C');    } } public int compare(int s) {    return s > 90 ? 1      : s > 60 ? 2      :3; } } /*【程序6】   题目:输入两个正整数m和n,求其最大公约数和最小公倍数。  1.程序分析:利用辗除法。 */ /*  * 在循环中,只要除数不等于0,用较大数除以较小的数,将小的一个数作为下一轮循环的大数,取得的余数作为下一轮循环的较小的数,如此循环直到较小的数的值为0,返回 * 较大的数,此数即为最小公约数,最小公倍数为两数之积除以最小公倍数。 * */ package cn.com.flywater.FiftyAlgorthm; import java.util.Scanner; public class SixthCommonDiviser { public static void main(String[] args) {    int a, b;    Scanner s1 = new Scanner(System.in);    Scanner s2 = new Scanner(System.in);    a = s1.nextInt();    b = s2.nextInt();    SixthCommonDiviser scd = new SixthCommonDiviser();    int m = scd.division(a, b);    int n = a * b / m;    System.out.println("最大公约数: " + m);    System.out.println("最小公倍数: " + n); }   public int division(int x, int y) {    int t;    if(x < y) {     t = x;     x = y;     y = t;    }        while(y != 0) {     if(x == y) return 1;     else {      int k = x % y;      x = y;      y = k;     }    }    return x; } }   /*【程序7】   题目:输入一行字符,分别统计出其中英文字母、空格、数字和其它字符的个数。  1.程序分析:利用while语句,条件为输入的字符不为 '/n '. */   package cn.com.flywater.FiftyAlgorthm; import java.util.*; public class SeventhCharacterStatistics { static int digital = 0; static int character = 0; static int other = 0; static int blank = 0; public static void main(String[] args) {    char[] ch = null;    Scanner sc = new Scanner(System.in);    String s = sc.nextLine();    ch = s.toCharArray();          for(int i=0; i= '0' && ch[i] <= '9') {      digital ++;     } else if((ch[i] >= 'a' && ch[i] <= 'z') || ch[i] > 'A' && ch[i] <= 'Z') {      character ++;     } else if(ch[i] == ' ') {      blank ++;     } else {      other ++;     }        }      System.out.println("数字个数: " + digital);    System.out.println("英文字母个数: " + character);    System.out.println("空格个数: " + blank);    System.out.println("其他字符个数:" + other ); }   }   /*【程序8】   题目:求s=a+aa+aaa+aaaa+aa...a的值,其中a是一个数字。例如2+22+222+2222+22222(此时共有5个数相加),几个数相加有键盘控制。  */ /* * 算法: 定义一个变量b, 赋初值为0;定义一变量sum, 赋初值为0, * 进入循环后,将a + b 的值赋给b,将sum + b 的值赋给sum; * 同时,将a 增加十倍, ++ i; 继续循环; * 循环结束后,输出sum 的值。 */ package cn.com.flywater.FiftyAlgorthm; import java.util.Scanner; public class EightPlus { static long a = 2, b = 0; public static void main(String[] args) {    Scanner s = new Scanner(System.in);    int n = s.nextInt();    int i = 0;    long sum = 0;    while(i < n) {     b = b + a;     sum = sum + b;     a = a * 10;     ++ i;    }    System.out.println("input number: " + n);    System.out.println(sum); } }   /*【程序9】  题目:一个数如果恰好等于它的因子之和,这个数就称为 "完数 "。例如6=1+2+3.编程 找出1000以内的所有完数。  */ package cn.com.flywater.FiftyAlgorthm; public class NinthWanshu {   public static void main(String[] args) {       System.out.println("1到1000的完数有: ");    for(int i=1; i<1000; i++) {     int t = 0;     for(int j=1; j<= i/2; j++) {      if(i % j == 0) {       t = t + j;      }     }     if(t == i) {      System.out.print(i + " ");     }    } } }   /*【程序10】   题目:一球从100米高度自由落下,每次落地后反跳回原高度的一半;再落下, 求它在 第10次落地时,共经过多少米?第10次反弹多高?  */ package cn.com.flywater.FiftyAlgorthm; public class TenthTreeFall { static double height = 100; static double distance = 100; public static void main(String[] args) {    for(int i=1; i<10; i++) {     distance = distance + height;     height = height / 2;    }       System.out.println("路程:" + distance);    System.out.println("高度:" + height / 2); } } /*【程序11】  *  题目:有1、2、3、4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少?  1.程序分析:可填在百位、十位、个位的数字都是1、2、3、4。组成所有的排列后再去 掉不满足条件的排列。  */ /*算法:3个for循环加一个if语句; *  */ package cn.com.flywater.FiftyAlgorthm; public class EleventhNumberRange { public static void main(String[] args) {    int count = 0;    for(int x=1; x<5; x++) {     for(int y=1; y<5; y++) {      for(int z=1; z<5; z++) {       if(x != y && y != z && x != z) {        count ++;        System.out.print(x*100 + y*10 + z + "   ");        if(count % 4 == 0) {         System.out.println();        }       }      }     }    }    System.out.println("共有" + count + "个三位数"); } }   /*【程序12】  *  题目:企业发放的奖金根据利润提成。利润(I)低于或等于10万元时,奖金可提10%; 利润高于10万元,低于20万元时,低于10万元的部分按10%提成,高于10万元的部分, 可可提成7.5%;20万到40万之间时,高于20万元的部分, 可提成5%;40万到60万之间时高于40万元的部分,可提成3%; 60万到100万之间时,高于60万元的部分,可提成1.5%,高于100万元时,超过100万元的部分按1%提成, 从键盘输入当月利润I,求应发放奖金总数?  1.程序分析:请利用数轴来分界,定位。注意定义时需把奖金定义成长整型。  */ /*注意: 要精确到小数点后多少位,用 DecimalFormat df = new DecimalFormat("#0.0000"); *  */ package cn.com.flywater.FiftyAlgorthm; import java.text.DecimalFormat; import java.util.*; public class TwelfthProfitAward { static double profit = 0; static double award = 0; public static void main(String[] args) {    Scanner s = new Scanner(System.in);    profit = s.nextInt();    System.out.println("输入的利润是" + profit + "万");    if(profit > 0 && profit <= 10) {     award = profit * 0.1;    } else if(profit > 10 && profit <= 20) {     award = 10 * 0.1 + (profit - 10) * 0.075;    } else if(profit > 20 && profit <= 40) {     award = 10 * 0.1 + 10 * 0.075 + (profit - 20) * 0.05;    } else if(profit > 40 && profit <= 60) {     award = 10 * 0.1 + 10 * 0.075 + 20 * 0.05 + (profit - 40) * 0.03;    } else if(profit > 60 && profit <= 100) {     award = 20 * 0.175 + 20 * 0.05 + 20 * 0.03 + (profit - 60) * 0.015;     } else if(profit > 100) {     award = 20 * 0.175 + 40 * 0.08 + 40 * 0.015 + (profit - 100) * 0.01;    }    DecimalFormat df = new DecimalFormat("#0.00000");       System.out.println("应该提取的奖金是 " + df.format(award) + "万"); } }   /*【程序13】  *  题目:一个整数,它加上100后是一个完全平方数,再加上168又是一个完全平方数,请问该数是多少?  1.程序分析:在10万以内判断,先将该数加上100后再开方,再将该数加上268后再开方, 如果开方后的结果满足如下条件,即是结果。请看具体分析: */ package cn.com.flywater.FiftyAlgorthm; public class ThirteenthTwiceSqrt { public static void main(String[] args) {    for(long l=1L; l<100000; l++) {     if(Math.sqrt((long)(l+100)) % 1 == 0) {      if(Math.sqrt((long)(l+268)) % 1 == 0) {       System.out.println(l + "加100是一个完全平方数,再加168又是一个完全平方数");      }     }    } } }   *【程序14】 *   题目:输入某年某月某日,判断这一天是这一年的第几天?  1.程序分析:以3月5日为例,应该先把前两个月的加起来, 然后再加上5天即本年的第几天,特殊情况,闰年且输入月份大于3时需考虑多加一天。  */ package cn.com.flywater.FiftyAlgorthm; import java.util.Scanner; import java.io.*; public class FourteenthYearMonthDay { public static void main(String[] args) {    int year, month, day;    int days = 0;    int d = 0;       FourteenthYearMonthDay fymd = new FourteenthYearMonthDay();       System.out.print("Input the year:");    year =fymd.input();    System.out.print("Input the month:");    month = fymd.input();    System.out.print("Input The Day:");    day = fymd.input();          if (year < 0 || month < 0 || month > 12 || day < 0 || day > 31) {     System.out.println("Input error, please run this program again!");     System.exit(0);    }    for (int i=1; i y则将x与y的值进行交换,然后再用x与z进行比较,如果x> z则将x与z的值进行交换,这样能使x最小。  */ package cn.com.flywater.FiftyAlgorthm; import java.util.*; public class FifteenthNumberCompare { public static void main(String[] args) {    FifteenthNumberCompare fnc = new FifteenthNumberCompare();    int a, b, c;       System.out.println("Input 3 numbers:");    a = fnc.input();    b = fnc.input();    c = fnc.input(); //   //   fnc.compare(a, b);//方法调用不能通过改变形参的值来改变实参的值 //   fnc.compare(b, c);// 这种做法是错的 //   fnc.compare(a, c);    //System.out.println("result:" + a +" " + b + " " + c);// 没有改变       if(a > b) {     int t = a;     a = b;     b = t;    }       if(a > c) {     int t = a;     a = c;     c = t;    }       if(b > c) {     int t = b;     b = c;     c = t;    }    System.out.println( a + " " + b + " " + c); } public int input() {    int value = 0;    Scanner s = new Scanner(System.in);    value = s.nextInt();    return value; } public void compare(int x, int y) {//此方法没用    if(x > y) {     int t = x;     x = y;     y = t;    } } }   /*【程序16】  *  *题目:输出9*9口诀。  *1.程序分析:分行与列考虑,共9行9列,i控制行,j控制列。  **/ package cn.com.flywater.FiftyAlgorthm; public class SixteenthMultiplicationTable { public static void main(String[] args) {    for(int i=1; i<10; i++) {     for(int j=1; j<=i; j++) {      System.out.print(j + "*" + i + "=" + j*i + " " );     }     System.out.println();    } } }   //【程序17】  // //题目:猴子吃桃问题:猴子第一天摘下若干个桃子,当即吃了一半,还不瘾, //又多吃了一个 第二天早上又将剩下的桃子吃掉一半,又多吃了一个。 //以后每天早上都吃了前一天剩下 的一半零一个。到第10天早上想再吃时, //见只剩下一个桃子了。求第一天共摘了多少。  //1.程序分析:采取逆向思维的方法,从后往前推断。   package cn.com.flywater.FiftyAlgorthm; public class SeventeenthMonkeyPeach { public static void main(String[] args) {    int lastdayNum = 1;    for(int i=2; i<=10; i++) {     lastdayNum = (lastdayNum+1) * 2;    }    System.out.println("猴子第一天摘了 " + lastdayNum + " 个桃子"); } } /*【程序18】  *  题目:两个乒乓球队进行比赛,各出三人。甲队为a,b,c三人,乙队为x,y,z三人。 已抽签决定比赛名单。有人向队员打听比赛的名单。a说他不和x比,c说他不和x,z比,请编程序找出三队赛手的名单。 */ /* * 这个程序写得很不好,是知道结果后拼凑起来的,还不如直接写输出语句加上结果来的好。 */ package cn.com.flywater.FiftyAlgorthm; public class EighteenthPingpong { static char[] m = { 'a', 'b', 'c' }; static char[] n = { 'x', 'y', 'z' }; public static void main(String[] args) {    for (int i = 0; i < m.length; i++) {     for (int j = 0; j < n.length; j++) {      if (m[i] == 'a' && n[j] == 'x') {       continue;      } else if (m[i] == 'a' && n[j] == 'y') {       continue;      } else if ((m[i] == 'c' && n[j] == 'x')        || (m[i] == 'c' && n[j] == 'z')) {       continue;      } else if ((m[i] == 'b' && n[j] == 'z')        || (m[i] == 'b' && n[j] == 'y')) {       continue;      } else       System.out.println(m[i] + " vs " + n[j]);     }    } } }   题目:打印出如下图案(菱形)     *   ***  ***** *******  *****   ***    * 1.程序分析:先把图形分成两部分来看待,前四行一个规律,后三行一个规律,利用双重 for循环, 第一层控制行,第二层控制列。 */ /*上半部分循环变量的控制方法是 * for(int i=0; i<(HEIGHT+1) / 2; i++) {    for(int j=1; j 1) {     value = n * recursion(n-1);    }    return value; } } /*【程序23】  *  :  题目:有5个人坐在一起,问第五个人多少岁?他说比第4个人大2岁。 问第4个人岁数,他说比第3个人大2岁。问第三个人,又说比第2人大两岁。 问第2个人,说比第一个人大两岁。最后问第一个人,他说是10岁。请问第五个人多大?  1.程序分析:利用递归的方法,递归分为回推和递推两个阶段。 要想知道第五个人岁数,需知道第四人的岁数,依次类推,推到第一人(10岁),再往回推。 **/ package cn.com.flywater.FiftyAlgorthm; public class Twenty_thirdPeopleAge { public static void main(String[] args) {    int age = 10;       for(int i=2; i<=5; i++) {     age += 2;    }    System.out.println(age); } } /*【程序24】  *  题目:给一个不多于5位的正整数, 要求:一、求它是几位数,二、逆序打印出各位数字。  说明: 这个算法实现虽然实现了这个功能,但不健壮,当输入字符是,会出现异常。 */ package cn.com.flywater.FiftyAlgorthm; import java.util.Scanner; public class Twenty_fourthNumber {   public static void main(String[] args) {       Twenty_fourthNumber tn = new Twenty_fourthNumber();    Scanner s = new Scanner(System.in);    long a = s.nextLong();    if(a < 0 || a > 100000) {     System.out.println("Error Input, please run this program Again");     System.exit(0);    }       if(a >=0 && a <=9) {     System.out.println( a + "是一位数");     System.out.println("按逆序输出是" + '/n' + a);    } else if(a >= 10 && a <= 99) {     System.out.println(a + "是二位数");     System.out.println("按逆序输出是" );     tn.converse(a);    } else if(a >= 100 && a <= 999) {     System.out.println(a + "是三位数");     System.out.println("按逆序输出是" );     tn.converse(a);    } else if(a >= 1000 && a <= 9999) {     System.out.println(a + "是四位数");     System.out.println("按逆序输出是" );     tn.converse(a);    } else if(a >= 10000 && a <= 99999) {     System.out.println(a + "是五位数");     System.out.println("按逆序输出是" );     tn.converse(a);    } } public void converse(long l) {    String s = Long.toString(l);    char[] ch = s.toCharArray();    for(int i=ch.length-1; i>=0; i--) {     System.out.print(ch[i]);        } } } 这个算法实在太土了,也许只有我才会这样写,  下面写一个优雅一点的 import java.util.Scanner;  public class Twenty_fourthNumber { public static void main(String[] args) {       Twenty_fourthNumber tn = new Twenty_fourthNumber();    Scanner s = new Scanner(System.in);    long a = s.nextLong();       String s = Long.toString(l);    char[] ch = s.toCharArray();  System.out.println(a + "是" + ch.length + “位数”);    for(int i=ch.length-1; i>=0; i--) {     System.out.print(ch[i]); }  }  } /*【程序25】  *  题目:一个5位数,判断它是不是回文数。即12321是回文数,个位与万位相同,十位与千位相同。 **/ package cn.com.flywater.FiftyAlgorthm; import java.util.Scanner; public class Twenty_fifthPalindrom { static int[] a = new int[5]; static int[] b = new int[5]; public static void main(String[] args) {       boolean is =false;    Scanner s = new Scanner(System.in);    long l = s.nextLong();       if (l > 99999 || l < 10000) {     System.out.println("Input error, please input again!");     l = s.nextLong();    }       for (int i = 4; i >= 0; i--) {     a[i] = (int) (l / (long) Math.pow(10, i));     l =(l % ( long) Math.pow(10, i));    }    System.out.println();    for(int i=0,j=0; i<5; i++, j++) {      b[j] = a[i];    }          for(int i=0,j=4; i<5; i++, j--) {     if(a[i] != b[j]) {      is = false;      break;     } else {      is = true;     }    }    if(is == false) {     System.out.println("is not a Palindrom!");    } else if(is == true) {     System.out.println("is a Palindrom!");    } } } 这个更好,不限位数  public static void main(String[] args) {    Scanner s = new Scanner(System.in);    System.out.print("请输入一个正整数:");    long a = s.nextLong();    String ss = Long.toString(a);     char[] ch = ss.toCharArray();     boolean is =true;    int j=ch.length;    for(int i=0; i'Z') {     System.out.println("Input error, please input a capital letter");     getChar();    }    return ch; } } /*【程序27】  *  题目:求100之内的素数  1.程序分析:判断素数的方法:用一个数分别去除2到sqrt(这个数), 如果能被整除, 则表明此数不是素数,反之是素数。 **/   package cn.com.flywater.FiftyAlgorthm; public class Twenty_seventhPrimeNumber { public static void main(String[] args) {    boolean b =false;    int count = 0;    for(int i=2; i<100; i+=1) {     for(int j=2; j<=Math.sqrt(i); j++) {      if(i % j == 0) {       b = false;       break;      } else{       b = true;      }     }         if(b == true) {      count ++;      System.out.print(i + " ");     }    }    System.out.println('/n' + "The number of PrimeNumber is :" + count); } }   /*【程序28】  *  题目:对10个数进行排序  1.程序分析:可以利用选择法,即从后9个比较过程中, 选择一个最小的与第一个元素交换, 下次类推, 即用第二个元素与后8个进行比较,并进行交换。 **/ package cn.com.flywater.FiftyAlgorthm; import java.util.Scanner; public class Twehty_eighthNumberSort {   public static void main(String[] args) {    Scanner s = new Scanner(System.in);    int[] a = new int[10];    for(int i=0; i<10; i++) {     a[i] = s.nextInt();    }    for(int i=0; i<10; i++) {     for(int j=i+1; j<10; j++) {      if(a[i] > a[j]) {       int t = a[i];       a[i] = a[j];       a[j] = t;      }     }    }       for(int i=0; i<10; i++) {     System.out.print(a[i] + " ");    }    }   } /*【程序29】  *      * 按程序分析,好像只是求主对角线的和 题目:求一个3*3矩阵对角线元素之和  1.程序分析:利用双重for循环控制输入二维数组,再将a[i][i]累加后输出。  **/ package cn.com.flywater.FiftyAlgorthm; import java.util.Scanner; public class Twenty_ninthCrossSum {   public static void main(String[] args) {    Scanner s = new Scanner(System.in);    int[][] a = new int[3][3];       for(int i=0; i<3; i++) {     for(int j=0; j<3; j++) {      a[i][j] = s.nextInt();     }    }       System.out.println("输入的3 * 3 矩阵是:");    for(int i=0; i<3; i++) {     for(int j=0; j<3; j++) {      System.out.print(a[i][j] + " ");     }     System.out.println();    }       int sum = 0;    for(int i=0; i<3; i++) {     for(int j=0; j<3; j++) {      if(i == j) {       sum += a[i][j];      }     }    }    System.out.println("对角线和是 " + sum); } } /*【程序30】  *  题目:有一个已经排好序的数组。现输入一个数,要求按原来的规律将它插入数组中。  1. 程序分析:首先判断此数是否大于最后一个数, 然后再考虑插入中间的数的情况,插入后此元素之后的数,依次后移一个位置。 **/ package cn.com.flywater.FiftyAlgorthm; import java.util.Scanner; public class ThirtiethInsert { public static void main(String[] args) {       int[] a = new int[]{1, 2, 3, 4, 5, 6, 7};    int[] b = new int[a.length+1];    int t1 =0, t2 = 0;                                               int i =0;    Scanner s= new Scanner(System.in);    int num = s.nextInt();       /*    * 定义两个数组a,b,一个a的长度比另一个b大1, a看做是    * 已经排好序的。    * 接下来的过程是    * 1: 如果num 比最后一个数大,把num赋值给数组b的最后一个数    *    再按顺序把a 的每个元素赋给b    * 2: 否则(num 不比a 的最后一个数大),     *     如果a 的元素比num 小,则将这些元素按顺序赋给b    *     将num 赋给比num大的b数组的元素,    *     跳出第一个for循环。    * 3: 定义一个循环控制变量,从num传给数组后num的下标值加一开始;    *    直到b的结尾,将剩下的a 的值赋给b,赋值的过程是b[j] = a[i-1];    *         */       if(num >= a[a.length-1]) {     b[b.length-1] = num;     for(i=0; i= a[i]) {       b[i] = a[i];      } else {            b[i] = num;       break;      }     }     for(int j=i+1; j max) {      max = a[i];      index1 = i;     }      if(a[i] < min) {      min = a[i];      index2 = i;     }    }       if(index1 != 0) {     int temp = a[0];     a[0] = a[index1];     a[index1] = temp;    }       if(index2 != a.length-1) {     int temp = a[a.length-1];     a[a.length-1] = a[index2];     a[index2] = temp;    }    System.out.println("after swop:");    for(int i=0; i 1) {     if(arr[index] == true) {//当在圈里时      countNum ++; //报数递加      if(countNum == 3) {//报道3时       countNum =0;//从零开始继续报数       arr[index] = false;//此人退出圈子       leftCount --;//剩余人数减一      }     }     index ++;//每报一次数,下标加一         if(index == n) {//是循环数数,当下标大于n时,说明已经数了一圈,      index = 0;//将下标设为零重新开始。     }    }       for(int i=0; i 0) {       temp = s[i];       s[i] = s[j];       s[j] = temp;      }     }    }*/       for(int i=0; i s2.charAt(i)) {      result = false;      break;     } else if(s1.charAt(i) curr){}" 很多方法都与它俩有关系!! 下面的代码是个双向循环链表,在LinkedList里抄的...   package LinkedList; import java.util.Iterator; import java.util.ListIterator; import java.util.NoSuchElementException; public class MyLinkedList {     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~     private DNode header;     private int listSize;     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~     public MyLinkedList() {         header = new DNode();         listSize = 0;     }     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~     private static class DNode {         T nodeValue;         DNode prev;         DNode next;         public DNode() { // for header             nodeValue = null;             prev = this; // left             next = this; // right         }         public DNode(T item) {             nodeValue = item;             prev = this;             next = this;         }     }     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~     public boolean isEmpty() {         return (header.prev == header || header.next == header);     }         public int size() {         return listSize;     }     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~     private DNode addBefore(DNode curr, T item) {         DNode newNode, prevNode;         newNode = new DNode(item);                 prevNode = curr.prev;                 newNode.prev = prevNode;         newNode.next = curr;                 prevNode.next = newNode;         curr.prev = newNode;         return newNode;     }     public boolean add(T item) {         addBefore(header, item);         listSize++;         return true;     }         public void addFirst(T item) {         addBefore(header.next, item);         listSize++;     }         public void addLast(T item) {         addBefore(header, item);         listSize++;     }     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~     private void remove(DNode curr) {         if(curr.next == curr) return;                 DNode prevNode = curr.prev, nextNode = curr.next;                 prevNode.next = nextNode;         nextNode.prev= prevNode;     }         public boolean remove(Object o) {         for(DNode p = header.next; p != header; p = p.next) {             if(o.equals(p.nodeValue)) {                 remove(p);                 listSize--;                 return true;             }         }         return false;     }     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~     public void printList() {         for(DNode p = header.next; p != header; p = p.next)             System.out.println(p.nodeValue);     }     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~     private class MyIterator implements Iterator {                 public DNode nextNode = header.next;         public DNode lastReturned = header;                 public boolean hasNext() {             return nextNode != header;         }                 public T next() {             if(nextNode == header)                 throw new NoSuchElementException("");                         lastReturned = nextNode;             nextNode = nextNode.next;             return lastReturned.nodeValue;         }         public void remove() {             if(lastReturned == header)                 throw new IllegalStateException("");                         MyLinkedList.this.remove(lastReturned);             lastReturned = header;             listSize--;         }     }     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~     private class MyListIterator extends MyIterator implements ListIterator {                 private int nextIndex;                 MyListIterator(int index) {             if(index < 0 || index > listSize)                 throw new IndexOutOfBoundsException("");                         //如果index小于listSize/2,就从表头开始查找定位,否则就从表尾开始查找定位             if(index < (listSize >> 1)) {                 nextNode = header.next;                 for(nextIndex = 0; nextIndex < index; nextIndex++)                     nextNode = nextNode.next;             }else {                 nextNode = header;                 for(nextIndex = listSize; nextIndex > index; nextIndex--)                     nextNode = nextNode.prev;             }         }         public boolean hasPrevious() {             return nextIndex != 0;             //return nextNode.prev != header;         }                 public T previous() {             if (nextIndex == 0)                 throw new NoSuchElementException("no");                         lastReturned = nextNode = nextNode.prev;             nextIndex--;             return lastReturned.nodeValue;         }                 public void remove() {             if(lastReturned == header)                 throw new IllegalStateException("");                         MyLinkedList.this.remove(lastReturned);             nextIndex--;             listSize--;                         if(lastReturned == nextNode)                 nextNode = nextNode.next;             lastReturned = header;         }                 public void add(T item) {             MyLinkedList.this.addBefore(nextNode, item);             nextIndex++;             listSize++;             lastReturned = header;         }                 public void set(T item) {              if (lastReturned == header)                  throw new IllegalStateException();                           lastReturned.nodeValue = item;         }                 public int nextIndex() {             return nextIndex;         }         public int previousIndex() {             return nextIndex - 1;         }     }         //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~     public Iterator iterator() {         return new MyIterator();     }     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~     public ListIterator listIterator(int index) {         return new MyListIterator(index);     }     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~     public static void main(String[] args) {         MyLinkedList t = new MyLinkedList();         t.add("A");         t.add("B");         t.add("C");         t.add("D");         //t.remove("B");         //t.addFirst("AA");         //t.addLast("BB");         //t.printList();                         ListIterator it = t.listIterator(t.size());                 while(it.hasPrevious()) {             System.out.println(it.previous()); // D C B A         }     } }// MyLinkedList end~   ArrayList 底层数组实现的,当实例化一个ArrayList是也相当实例化了一个数组 所以对元素的随即访问较快,而增加删除操作慢 LinkedList 底层实现是一个双向链表,没一个结点都包含了前一个元素的引用和后一个元素的引用和结点值 所以对元素的随即访问很慢,而增删较快 java 实现链表和c实现一样。 就是指针变成了引用。 【参考资料】JAVA的链表(2009-05-11 01:35:49)标签:java 链表   分类:学习资料  又是个不错的地方:http://blog.sina.com.cn/s/articlelist_1282789430_0_1.html   链表是一种重要的数据结构,在程序设计中占有很重要的地位。C语言和C++语言中是用指针来实现链表结构的,由于Java语言不提供指针,所以有人认为在Java语言中不能实现链表,其实不然,Java语言比C和C++更容易实现链表结构。Java语言中的对象引用实际上是一个指针(本文中的指针均为概念上的意义,而非语言提供的数据类型),所以我们可以编写这样的类来实现链表中的结点。    class Node   {   Object data;   Node next;//指向下一个结点   }   将数据域定义成Object类是因为Object类是广义超类,任何类对象都可以给其赋值,增加了代码的通用性。为了使链表可以被访问还需要定义一个表头,表头必须包含指向第一个结点的指针和指向当前结点的指针。为了便于在链表尾部增加结点,还可以增加一指向链表尾部的指针,另外还可以用一个域来表示链表的大小,当调用者想得到链表的大小时,不必遍历整个链表。下图是这种链表的示意图:   链表的数据结构   我们可以用类List来实现链表结构,用变量Head、Tail、Length、Pointer来实现表头。存储当前结点的指针时有一定的技巧,Pointer并非存储指向当前结点的指针,而是存储指向它的前趋结点的指针,当其值为null时表示当前结点是第一个结点。那么为什么要这样做呢?这是因为当删除当前结点后仍需保证剩下的结点构成链表,如果Pointer指向当前结点,则会给操作带来很大困难。那么如何得到当前结点呢,我们定义了一个方法cursor(),返回值是指向当前结点的指针。类List还定义了一些方法来实现对链表的基本操作,通过运用这些基本操作我们可以对链表进行各种操作。例如reset()方法使第一个结点成为当前结点。insert(Object d)方法在当前结点前插入一个结点,并使其成为当前结点。remove()方法删除当前结点同时返回其内容,并使其后继结点成为当前结点,如果删除的是最后一个结点,则第一个结点变为当前结点。   链表类List的源代码如下:   import java.io.*;   public class List   {     private Node Head=null;   private Node Tail=null;   private Node Pointer=null;   private int Length=0;   public void deleteAll()     {   Head=null;   Tail=null;   Pointer=null;   Length=0;   }   public void reset()     {   Pointer=null;   }   public boolean isEmpty()     {   return(Length==0);   }   public boolean isEnd()     {   if(Length==0)    throw new java.lang.NullPointerException();   else if(Length==1)    return true;   else    return(cursor()==Tail);   }   public Object nextNode()     {   if(Length==1)    throw new java.util.NoSuchElementException();   else if(Length==0)    throw new java.lang.NullPointerException();   else   {    Node temp=cursor();    Pointer=temp;    if(temp!=Tail)     return(temp.next.data);    else     throw new java.util.NoSuchElementException();   }   }   public Object currentNode()     {   Node temp=cursor();   return temp.data;   }     public void insert(Object d)     {   Node e=new Node(d);   if(Length==0)   {    Tail=e;    Head=e;   }   else   {    Node temp=cursor();    e.next=temp;    if(Pointer==null)     Head=e;    else     Pointer.next=e;   }   Length++;   }   public int size()     {   return (Length);   }   public Object remove()     {   Object temp;   if(Length==0)    throw new java.util.NoSuchElementException();   else if(Length==1)   {    temp=Head.data;    deleteAll();   }   else   {    Node cur=cursor();    temp=cur.data;    if(cur==Head)     Head=cur.next;    else if(cur==Tail)    {     Pointer.next=null;     Tail=Pointer;     reset();    }    else     Pointer.next=cur.next;     Length--;   }   return temp;   }   private Node cursor()     {   if(Head==null)    throw new java.lang.NullPointerException();   else if(Pointer==null)    return Head;   else    return Pointer.next;   }   public static void main(String[] args)     {   List a=new List ();   for(int i=1;i<=10;i++)    a.insert(new Integer(i));    System.out.println(a.currentNode());    while(!a.isEnd())     System.out.println(a.nextNode());     a.reset();     while(!a.isEnd())     {      a.remove();     }     a.remove();     a.reset();     if(a.isEmpty())      System.out.println("There is no Node in List /n");      System.in.println("You can press return to quit/n");     try     {      System.in.read();      //确保用户看清程序运行结果     }     catch(IOException e)     {}    }   }   class Node     {    Object data;    Node next;    Node(Object d)    {     data=d;     next=null;    }   }