java一些必会算法

转载 https://blog.csdn.net/qq_23994787/article/details/77951244

经典算法的Java实现

(1)河内塔问题: 42

(2)费式数列 43

(3)巴斯卡(Pascal)三角形 44

(4)蒙地卡罗法求 PI 45

(5)最大公因数、最小公倍数 46

(6)阿姆斯壮数 47

(7)最大访客数 48

(8)洗扑克牌(乱数排列) 49

(9)约瑟夫问题(Josephus Problem) 50

(10)排列组合 52

(11)得分排行 53

(12)选择、插入、气泡排序 55

(13)快速排序(一) 58

(14)快速排序(二) 60

(15)快速排序(三) 61

(16)合并排序 62

(17)基数排序 63

(18)循序查找法(使用卫兵) 65

(19)二分查找法 66

(20)插补查找法 67

(21)费式查找法 68

(22)稀疏矩阵 71

(23)多维矩阵转一维矩阵 72

(24)上三角、下三角、对称矩阵 73

(25)奇数魔方阵 75

(26)4N魔方阵 76

(27)2(2n+1)魔方阵 78



1.大O表示法:粗略的量度方法即算法的速度是如何与数据项的个数相关的

 

算法                                                              大O表示法表示的运行时间

线性查找                                                              O(N)

二分查找                                                              O(logN)

无序数组的插入                                                        O(1)

有序数组的插入                                                        O(N)

无序数组的删除                                                        O(N)

有序数组的删除                                                        O(N)

O(1)是最优秀的,O(logN)良好,O(N)还可以,O(N2)稍差(在冒泡法中见到)

 

2. 排序


   
   
  1. public class JWzw {
  2.     //插入排序
  3.     public void insertArray(Integer[] in ) {
  4.         int tem = 0;
  5.         int num = 0;
  6.         int upnum = 0;
  7.         for ( int i = 0; i < in .length; i++) {
  8.             for ( int j = i - 1; j >= 0; j--) {
  9.                 num++;
  10.                 if ( in [j + 1] < in [j]) {
  11.                     tem = in [j + 1]; in [j + 1] = in [j]; in [j] = tem;
  12.                     upnum++;
  13.                 } else {
  14.                     break;
  15.                 }
  16.             }
  17.         }
  18.         for ( int i = 0; i < in .length; i++) {
  19.             System.out.print( in [i]);
  20.             if (i < in .length - 1) {
  21.                 System.out.print( ",");
  22.             }
  23.         }
  24.         System.out.println();
  25.         System.out.println( "插入排序循环次数:" + num);
  26.         System.out.println( "移动次数:" + upnum);
  27.         System.out.print( "\n\n\n");
  28.     }
  29.     //选择排序
  30.     public void chooseArray(Integer[] in ) {
  31.         int tem = 0;
  32.         int num = 0;
  33.         int upnum = 0;
  34.         for ( int i = 0; i < in .length; i++) {
  35.             for ( int j = 0; j < in .length - 1; j++) {
  36.                 num++;
  37.                 if ( in [j + 1] < in [j]) {
  38.                     tem = in [j + 1]; in [j + 1] = in [j]; in [j] = tem;
  39.                     upnum++;
  40.                 }
  41.             }
  42.         }
  43.         for ( int i = 0; i < in .length; i++) {
  44.             System.out.print( in [i]);
  45.             if (i < in .length - 1) {
  46.                 System.out.print( ",");
  47.             }
  48.         }
  49.         System.out.println();
  50.         System.out.println( "选择排序循环次数:" + num);
  51.         System.out.println( "移动次数:" + upnum);
  52.         System.out.print( "\n\n\n");
  53.     }
  54.     //冒泡排序
  55.     public void efferArray(Integer[] in ) {
  56.         int tem = 0;
  57.         int num = 0;
  58.         int upnum = 0;
  59.         for ( int i = 0; i < in .length; i++) {
  60.             for ( int j = i; j < in .length - 1; j++) {
  61.                 num++;
  62.                 if ( in [j + 1] < in [i]) {
  63.                     tem = in [j + 1]; in [j + 1] = in [i]; in [i] = tem;
  64.                     upnum++;
  65.                 }
  66.             }
  67.         }
  68.         for ( int i = 0; i < in .length; i++) {
  69.             System.out.print( in [i]);
  70.             if (i < in .length - 1) {
  71.                 System.out.print( ",");
  72.             }
  73.         }
  74.         System.out.println();
  75.         System.out.println( "冒泡排序循环次数:" + num);
  76.         System.out.println( "移动次数:" + upnum);
  77.         System.out.print( "\n\n\n");
  78.     }
  79.     //打印乘法口诀
  80.     public void printMulti() {
  81.         for ( int j = 1; j < 10; j++) {
  82.             for ( int i = 1; i <= j; i++) {
  83.                 System.out.print(i + " * " + j + " = " + j * i + "\t");
  84.             }
  85.             System.out.print( "\t\n");
  86.         }
  87.         System.out.print( "\n\n\n");
  88.     }
  89.     //打印N * 1 + N * 2 + N * 3 =num的所有组合
  90.     public void printNumAssemble(int num) {
  91.         for ( int i = 0; i < num + 1; i++) {
  92.             for ( int j = 0; j < num / 2 + 1; j++) {
  93.                 for ( int in = 0; in < num / 3 + 1; in ++) {
  94.                     if (i * 1 + j * 2 + in * 3 == num) {
  95.                         System.out.println( "小马" + i + ",\t中马" + j + ",\t大马" + in );
  96.                     }
  97.                 }
  98.             }
  99.         }
  100.     }
  101.     /**
  102.  * @param args
  103.  */
  104.     public static void main(String[] args) {
  105.         JWzw jwzw = new JWzw();
  106.         int num = 3;
  107.         jwzw.printMulti(); //打印乘法口诀
  108.         jwzw.printNumAssemble( 100); //打印N * 1 + N * 2 + N * 3 =num的所有组合
  109.         Integer in [] = {
  110.             8, 89, 5, 84, 3, 45, 12, 33, 77, 98, 456, 878, 654, 213, 897
  111.         };
  112.         jwzw.efferArray( in ); //冒泡排序
  113.         Integer in1[] = {
  114.             8, 89, 5, 84, 3, 45, 12, 33, 77, 98, 456, 878, 654, 213, 897
  115.         };
  116.         jwzw.insertArray(in1); //插入排序
  117.         Integer in2[] = {
  118.             8, 89, 5, 84, 3, 45, 12, 33, 77, 98, 456, 878, 654, 213, 897
  119.         };
  120.         jwzw.chooseArray(in2); //选择排序
  121.         //int i = num++;
  122.         //System.out.println(i);
  123.         System.out.println( 1000 >> 2);
  124.     }
  125. }

3. 优先级队列


   
   
  1. class PriorityQueue {
  2. private long[] a = null;
  3. private int nItems = 0;
  4. private int maxSize = 0;
  5. public PriorityQueue(int maxSize) {
  6. a = new long[maxSize];
  7. this.maxSize = maxSize;
  8. nItems = 0;
  9. }
  10. public void insert(long l) {
  11. //优先级队列的插入不是队尾,而是选择一个合适的按照某种顺序插入的
  12. //当队列长度为0时,如下
  13. //不为0时,将所有比要插入的数小的数据后移,这样大的数就在队列的头部了
  14. int i = 0;
  15. if (nItems == 0) {
  16. a[ 0] = l;
  17. } else {
  18. for (i = nItems - 1; i >= 0; i--) {
  19. if (l < a[i]) a[i + 1] = a[i];
  20. else break;
  21. }
  22. a[i + 1] = l;
  23. }
  24. nItems++;
  25. }
  26. public long remove() {
  27. //移出的是数组最上端的数,这样减少数组元素的移动
  28. return a[--nItems];
  29. }
  30. public boolean isEmpty() {
  31. return (nItems == 0);
  32. }
  33. public boolean isFull() {
  34. return (nItems == maxSize);
  35. }
  36. public int size() {
  37. return nItems;
  38. }
  39. }
  40. public class duilie { // 队列体类
  41. private duilie s;
  42. private String data;
  43. duilie(String data) {
  44. this.data = data;
  45. }
  46. public String getData() {
  47. return data;
  48. }
  49. public void setData(String data) {
  50. this.data = data;
  51. }
  52. public duilie getS() {
  53. return s;
  54. }
  55. public void setS(duilie s) {
  56. this.s = s;
  57. }
  58. }
  59. public class duiliecz { // 队列操作类
  60. /**
  61. * @param args
  62. */
  63. private int i = 0; // 队列长
  64. private duilie top = new duilie( ""); // 队列头
  65. private duilie end = new duilie( ""); // 队列尾
  66. public void add(String s) { // 添加队列
  67. duilie m = new duilie(s);
  68. if (i != 0) {
  69. m.setS(top.getS());
  70. top.setS(m);
  71. } else {
  72. top.setS(m);
  73. end.setS(m);
  74. }
  75. i++;
  76. }


4. 队列

 


   
   
  1. public void del() { // 删除队尾
  2. if (i == 0) {
  3. return;
  4. } else if (i == 1) {
  5. top.setS( null);
  6. end.setS( null);
  7. } else {
  8. duilie top1 = new duilie( ""); // 队列底查找用缓存
  9. top1.setS(top.getS());
  10. while (!top1.getS().getS().equals(end.getS())) {
  11. top1.setS(top1.getS().getS());
  12. }
  13. end.setS(top1.getS());
  14. }
  15. i--;
  16. }
  17. public static void main(String[] args) {
  18. // TODO Auto-generated method stub
  19. duiliecz m = new duiliecz();
  20. m.add( "1");
  21. m.add( "2");
  22. m.add( "3");
  23. m.add( "4");
  24. for ( int n = 0; n < 4; n++) {
  25. m.del();
  26. }
  27. }
  28. public int getI() {
  29. return i;
  30. }
  31. public duilie getEnd() {
  32. return end;
  33. }
  34. public duilie getTop() {
  35. return top;
  36. }
  37. }

5. 

 


   
   
  1. public class Stack {
  2. int[] arr;
  3. int len = 0;
  4. public Stack() {
  5. arr = new int[ 100];
  6. }
  7. public Stack(int n) {
  8. arr = new int[n];
  9. }
  10. public int size() {
  11. return len + 1;
  12. }
  13. // 扩大数组
  14. public void resize() {
  15. int[] b = new int[arr.length * 2];
  16. System.arraycopy(arr, 0, b, 0, arr.length);
  17. arr = b;
  18. }
  19. public void show() {
  20. for ( int i = 0; i < len; i++) {
  21. System.out.print(arr[i] + " ");
  22. }
  23. System.out.println();
  24. }
  25. // 进栈
  26. public void push(int a) {
  27. if (len >= arr.length) resize();
  28. arr[len] = a;
  29. len++;
  30. }
  31. // 出栈
  32. public int pop() {
  33. if (len == 0) {
  34. System.out.println();
  35. System.out.println( "stack is empty!");
  36. return - 1;
  37. }
  38. int a = arr[len - 1];
  39. arr[len - 1] = 0;
  40. len--;
  41. return a;
  42. }
  43. }

 

6. 链表


   
   
  1. class Node {
  2. Object data;
  3. Node next;
  4. public Node(Object data) {
  5. setData(data);
  6. }
  7. public void setData(Object data) {
  8. this.data = data;
  9. }
  10. public Object getData() {
  11. return data;
  12. }
  13. }
  14. class Link {
  15. Node head;
  16. int size = 0;
  17. public void add(Object data) {
  18. Node n = new Node(data);
  19. if (head == null) {
  20. head = n;
  21. } else {
  22. Node current = head;
  23. while ( true) {
  24. if (current.next == null) {
  25. break;
  26. }
  27. current = current.next;
  28. }
  29. current.next = n;
  30. }
  31. size++;
  32. }
  33. public void show() {
  34. Node current = head;
  35. if (current != null) {
  36. while ( true) {
  37. System.out.println(current);
  38. if (current == null) {
  39. break;
  40. }
  41. current = current.next;
  42. }
  43. } else {
  44. System.out.println( "link is empty");
  45. }
  46. }
  47. public Object get(int index) {
  48. // ....
  49. }
  50. public int size() {
  51. return size;
  52. }
  53. }


 

7. 单链表


   
   
  1. class Node // 节点类,单链表上的节点
  2. {
  3. String data; // 数据域,存放String类的数据
  4. Node next; // 指向下一个节点
  5. Node(String data) {
  6. this.data = data; // 构造函数
  7. }
  8. String get() {
  9. return data; // 返回数据
  10. }
  11. }
  12. class MyLinkList // 链表类
  13. {
  14. Node first; // 头节点
  15. int size; // 链表长度
  16. MyLinkList(String arg[]) {
  17. // Node first = new Node("head");//生成头节点
  18. first = new Node( "head"); // J.F. 这里不需要定义局部变量 first
  19. // 如果定义了局部变量,那成员变量 first 就一直没有用上
  20. // 所以,它一直为空
  21. size = 0;
  22. Node p = first;
  23. for ( int i = 0; i < arg.length; i++) // 将arg数组中的元素分别放入链表中
  24. {
  25. Node q = new Node(arg[i]);
  26. q.next = p.next; // 每一个节点存放一个arg数组中的元素
  27. p.next = q;
  28. p = p.next;
  29. size++;
  30. }
  31. }
  32. MyLinkList() // 无参数构造函数
  33. {
  34. // Node first = new Node("head");
  35. first = new Node( "head"); // J.F. 这里犯了和上一个构造方法同样的错误
  36. size = 0;
  37. }
  38. int size() // 返回链表长度
  39. {
  40. return size;
  41. }
  42. void insert(Node a, int index) // 将节点a 插入链表中的第index个位置
  43. {
  44. Node temp = first;
  45. for ( int i = 0; i < index; i++) {
  46. temp = temp.next; // 找到插入节点的前一节点
  47. }
  48. a.next = temp.next; // 插入节点
  49. temp.next = a;
  50. size++;
  51. }
  52. Node del(int index) // 删除第index个节点,并返回该值
  53. {
  54. Node temp = first;
  55. for ( int i = 0; i < index; i++) {
  56. temp = temp.next; // 找到被删除节点的前一节点
  57. }
  58. Node node = temp.next;
  59. temp.next = node.next;
  60. size--; // 删除该节点,链表长度减一
  61. return node;
  62. }
  63. void print() // 在屏幕上输出该链表(这段程序总是出错,不知道错在哪里)
  64. {
  65. Node temp = first;
  66. for ( int i = 1; i < size; i++) // 将各个节点分别在屏幕上输出
  67. {
  68. temp = temp.next;
  69. System.out.print(temp.get() + "->");
  70. }
  71. }
  72. void reverse() // 倒置该链表
  73. {
  74. for ( int i = 0; i < size; i++) {
  75. insert(del(size - 1), 0); // 将最后一个节点插入到最前
  76. // J.F. 最后一个节点的 index 应该是 size - 1
  77. // 因为第一个节点的 index 是 0
  78. }
  79. }
  80. String get(int index) // 查找第index个节点,返回其值
  81. {
  82. if (index >= size) {
  83. return null;
  84. }
  85. Node temp = first;
  86. for ( int i = 0; i < index; i++) {
  87. temp = temp.next; // 找到被查找节点的前一节点
  88. }
  89. return temp.next.get();
  90. }
  91. }
  92. class MyStack // 堆栈类,用单链表实现
  93. {
  94. MyLinkList tmp;
  95. Node temp;
  96. MyStack() {
  97. // MyLinkList tmp = new MyLinkList();
  98. tmp = new MyLinkList(); // J.F. 和 MyLinkList 构造方法同样的错误
  99. }
  100. void push(String a) // 压栈,即往链表首部插入一个节点
  101. {
  102. Node temp = new Node(a);
  103. tmp.insert(temp, 0);
  104. }
  105. String pop() // 出栈,将链表第一个节点删除
  106. {
  107. Node a = tmp.del( 0);
  108. return a.get();
  109. }
  110. int size() {
  111. return tmp.size();
  112. }
  113. boolean empty() // 判断堆栈是否为空
  114. {
  115. if (tmp.size() == 0) return false;
  116. else return true;
  117. }
  118. }
  119. public class MyLinkListTest // 测试程序部分
  120. {
  121. public static void main(String arg[]) // 程序入口
  122. {
  123. if ((arg.length == 0) || (arg.length > 10)) System.out.println( "长度超过限制或者缺少参数");
  124. else {
  125. MyLinkList ll = new MyLinkList(arg); // 创建一个链表
  126. ll.print(); // 先输出该链表(运行到这一步抛出异常)
  127. ll.reverse(); // 倒置该链表
  128. ll.print(); // 再输出倒置后的链表
  129. String data[] = new String[ 10];
  130. int i;
  131. for (i = 0; i < ll.size(); i++) {
  132. data[i] = ll.get(i); // 将链表中的数据放入数组
  133. }
  134. // sort(data);// 按升序排列data中的数据(有没有现成的排序函数?)
  135. for (i = 0; i < ll.size(); i++) {
  136. System.out.print(data[i] + ";"); // 输出数组中元素
  137. }
  138. System.out.println();
  139. MyStack s = new MyStack(); // 创建堆栈实例s
  140. for (i = 0; i < ll.size(); i++) {
  141. s.push(data[i]); // 将数组元素压栈
  142. }
  143. while (!s.empty()) {
  144. System.out.print(s.pop() + ";"); // 再将堆栈里的元素弹出
  145. }
  146. }
  147. }
  148. }


8. 双端链表


   
   
  1. class Link {
  2. public int iData = 0;
  3. public Link next = null;
  4. public Link(int iData) {
  5. this.iData = iData;
  6. }
  7. public void display() {
  8. System.out.print(iData + " ");
  9. }
  10. }
  11. class FirstLastList {
  12. private Link first = null;
  13. private Link last = null;
  14. public FirstLastList() {
  15. first = null;
  16. last = null;
  17. }
  18. public void insertFirst(int key) {
  19. Link newLink = new Link(key);
  20. if ( this.isEmpty()) last = newLink;
  21. newLink.next = first;
  22. first = newLink;
  23. }
  24. public void insertLast(int key) {
  25. Link newLink = new Link(key);
  26. if ( this.isEmpty()) first = newLink;
  27. else last.next = newLink;
  28. last = newLink;
  29. }
  30. public Link deleteFirst() {
  31. Link temp = first;
  32. if (first.next == null) last = null;
  33. first = first.next;
  34. return temp;
  35. }
  36. public boolean isEmpty() {
  37. return (first == null);
  38. }
  39. public void displayList() {
  40. System.out.print( "List (first-->last): ");
  41. Link current = first;
  42. while (current != null) {
  43. current.display();
  44. current = current.next;
  45. }
  46. System.out.println( "");
  47. }
  48. }
  49. class FirstLastListApp {
  50. public static void main(String[] args) {
  51. // TODO Auto-generated method stub
  52. FirstLastList theList = new FirstLastList();
  53. theList.insertFirst( 22); // insert at front
  54. theList.insertFirst( 44);
  55. theList.insertFirst( 66);
  56. theList.insertLast( 11); // insert at rear
  57. theList.insertLast( 33);
  58. theList.insertLast( 55);
  59. theList.displayList(); // display the list
  60. theList.deleteFirst(); // delete first two items
  61. theList.deleteFirst();
  62. theList.displayList(); // display again
  63. }
  64. }


9. 有序链表


   
   
  1. package arithmetic;
  2. class Link {
  3. public int iData = 0;
  4. public Link next = null;
  5. public Link(int iData) {
  6. this.iData = iData;
  7. }
  8. public void display() {
  9. System.out.print(iData + " ");
  10. }
  11. }
  12. class SortedList {
  13. private Link first = null;
  14. public SortedList() {
  15. first = null;
  16. }
  17. public void insert(int key) {
  18. Link newLink = new Link(key);
  19. Link previous = null;
  20. Link current = first;
  21. // while的第一个条件是没有到达链表的尾端,第二个是按顺序找到一个合适的位置
  22. while (current != null && key > current.iData) {
  23. previous = current;
  24. current = current.next;
  25. }
  26. // 如果是空表或者要插入的元素最小,则在表头插入key
  27. if (current == first) first = newLink;
  28. else previous.next = newLink;
  29. newLink.next = current;
  30. }
  31. /**
  32. * 删除表头的节点
  33. *
  34. * @return 要删除的节点
  35. */
  36. public Link remove() {
  37. Link temp = first;
  38. first = first.next;
  39. return temp;
  40. }
  41. public boolean isEmpty() {
  42. return (first == null);
  43. }
  44. public void displayList() {
  45. System.out.print( "List (first-->last): ");
  46. Link current = first; // start at beginning of list
  47. while (current != null) // until end of list,
  48. {
  49. current.display(); // print data
  50. current = current.next; // move to next link
  51. }
  52. System.out.println( "");
  53. }
  54. }
  55. class SortedListApp {
  56. public static void main(String[] args) { // create new list
  57. SortedList theSortedList = new SortedList();
  58. theSortedList.insert( 20); // insert 2 items
  59. theSortedList.insert( 40);
  60. theSortedList.displayList(); // display list
  61. theSortedList.insert( 10); // insert 3 more items
  62. theSortedList.insert( 30);
  63. theSortedList.insert( 50);
  64. theSortedList.displayList(); // display list
  65. theSortedList.remove(); // remove an item
  66. theSortedList.displayList(); // display list
  67. }
  68. }


 

10. 双向链表


   
   
  1. class Link {
  2. // 双向链表,有两个指针,一个向前,一个向后
  3. public int iData = 0;
  4. public Link previous = null;
  5. public Link next = null;
  6. public Link(int iData) {
  7. this.iData = iData;
  8. }
  9. public void display() {
  10. System.out.print(iData + " ");
  11. }
  12. }
  13. class DoublyLinked {
  14. // 分别指向链表的表头和表尾
  15. private Link first = null;
  16. private Link last = null;
  17. public boolean isEmpty() {
  18. return first == null;
  19. }
  20. /**
  21. * 在表头插入数据
  22. *
  23. * @param 要插入的节点的数据
  24. */
  25. public void insertFirst(int key) {
  26. Link newLink = new Link(key);
  27. // 如果开始链表为空,则插入第一个数据后,last也指向第一个数据
  28. if ( this.isEmpty()) last = newLink;
  29. else { // 表不为空的情况
  30. first.previous = newLink;
  31. newLink.next = first;
  32. }
  33. // 无论怎样,插入后都的让first重新指向第一个节点
  34. first = newLink;
  35. }
  36. public void insertLast(int key) { // 在尾端插入数据,同上
  37. Link newLink = new Link(key);
  38. if ( this.isEmpty()) first = newLink;
  39. else {
  40. last.next = newLink;
  41. newLink.previous = last;
  42. }
  43. last = newLink;
  44. }
  45. /**
  46. * 在指定的节点后插入数据
  47. *
  48. * @param key
  49. * 指定的节点的值
  50. * @param iData
  51. * 要插入的数据
  52. * @return 是否插入成功
  53. */
  54. public boolean insertAfter(int key, int iData) {
  55. Link newLink = new Link(key);
  56. Link current = first;
  57. // 从first开始遍历,看能否找到以key为关键字的节点
  58. while (current.iData != key) {
  59. current = current.next;
  60. // 若能找到就跳出循环,否则返回false,插入失败
  61. if (current == null) return false;
  62. }
  63. // 如果插入点在last的位置
  64. if (current == last) {
  65. last = newLink;
  66. } else { // 非last位置,交换各个next和previous的指针
  67. newLink.next = current.next;
  68. current.next.previous = newLink;
  69. }
  70. current.next = newLink;
  71. newLink.previous = current;
  72. return true;
  73. }
  74. /**
  75. * 删除表头的节点
  76. *
  77. * @return
  78. */
  79. public Link deleteFirst() {
  80. Link temp = first;
  81. // 如果表中只有一个元素,删除后则为空表,所以last=null
  82. if (first.next == null) last = null;
  83. else
  84. // 否则,让第二个元素的previous=null
  85. first.next.previous = null;
  86. // 删除头指针,则first指向原来的second
  87. first = first.next;
  88. return temp;
  89. }
  90. public Link deleteLast() { // 同上
  91. Link temp = last;
  92. if (last.previous == null) first = null;
  93. else last.previous.next = null;
  94. last = last.previous;
  95. return temp;
  96. }
  97. public Link deleteKey(int key) {
  98. Link current = first;
  99. // 遍历整个链表查找对应的key,如果查到跳出循环,否则...
  100. while (current.iData != key) {
  101. current = current.next;
  102. // ...否则遍历到表尾,说明不存在此key,返回null,删除失败
  103. if (current == null) return null;
  104. }
  105. if (current == first) first = first.next;
  106. else current.previous.next = current.next;
  107. if (current == last) last = last.previous;
  108. else current.next.previous = current.previous;
  109. return current;
  110. }
  111. public void displayForward() {
  112. Link current = first;
  113. while (current != null) {
  114. current.display();
  115. current = current.next;
  116. }
  117. System.out.println();
  118. }
  119. public void displayBackward() {
  120. Link current = last;
  121. while (current != null) {
  122. current.display();
  123. current = current.previous;
  124. }
  125. System.out.println();
  126. }
  127. }
  128. class DoublyLinkedApp {
  129. public static void main(String[] args) { // make a new list
  130. DoublyLinked theList = new DoublyLinked();
  131. theList.insertFirst( 22); // insert at front
  132. theList.insertFirst( 44);
  133. theList.insertFirst( 66);
  134. theList.insertLast( 11); // insert at rear
  135. theList.insertLast( 33);
  136. theList.insertLast( 55);
  137. theList.displayForward(); // display list forward
  138. theList.displayBackward(); // display list backward
  139. theList.deleteFirst(); // delete first item
  140. theList.deleteLast(); // delete last item
  141. theList.deleteKey( 11); // delete item with key 11
  142. theList.displayForward(); // display list forward
  143. theList.insertAfter( 22, 77); // insert 77 after 22
  144. theList.insertAfter( 33, 88); // insert 88 after 33
  145. theList.displayForward(); // display list forward
  146. }
  147. }


 

11. 实现二叉树前序遍历迭代器

 


   
   
  1. class TreeNode这个类用来声明树的结点,其中有左子树、右子树和自身的内容。
  2. class MyTree这个类用来声明一棵树,传入根结点。这里设计的比较简单
  3. class TreeEum这个类是树的迭代器,通过 MyTree类的方法获取,这里主要就是设计它了。代码如下:
  4. //TreeNode类,使用了泛型,由于比较简单,考试.大提示不作解释
  5.    class TreeNode < E > {
  6. E node;  
  7. private TreeNode < String > left;  
  8. private TreeNode < String > right;  
  9. public TreeNode(E e) {  
  10. this(e, null, null);
  11. }  
  12. public TreeNode(E e, TreeNode < String > left, TreeNode < String > right) {  
  13. this.node = e;  
  14. this.left = left;  
  15. this.right = right;
  16. }  
  17. public TreeNode < String > left() {  
  18. return left;
  19. }  
  20. public TreeNode < String > right() {  
  21. return right;
  22. }
  23. }
  24. // MyTree类,没什么功能,传入根结点构造,getEnumerator()方法获取迭代器。
  25.   
  26. class MyTree {
  27. TreeNode < String > root;  
  28. public MyTree(TreeNode < String > root) {  
  29. this.root = root;
  30. }  
  31. public TreeEnum getEnumerator() {  
  32. return new TreeEnum(root);
  33. }
  34. }
  35. // 这个类为迭代器,有详细解释,相信各位能看懂。在栈中用了两次泛型。
  36.   
  37. import java.util.Stack;  
  38. public class TreeEnum {  
  39. private TreeNode < String > root;  
  40. private Stack < TreeNode < String >> store; /* 保存遍历左子树但未遍历右子树的结点 */   
  41. private TreeNode < String > next;  
  42. public TreeEnum(TreeNode < String > root) {  
  43. this.root = root;
  44. store = new Stack < TreeNode < String >> ();
  45. next = root;
  46. }  
  47. public TreeNode < String > next() {
  48. TreeNode < String > current = next;  
  49. if (next != null) {
  50. /* 如果当前结点的左子树不为空,则遍历左子树,并标记当前结点未遍历右子树 */
  51.   
  52. if (next.left() != null) {
  53. store.push(next);
  54. next = next.left();
  55. }
  56. // 如果当前结点的左子树为空,则遍历右子树
  57.   
  58. else if (next.right() != null) {
  59. next = next.right();
  60. }
  61. /* 如果当前结点为叶子,则找未遍历右子树的结点并且遍历它的右子树 */
  62.   
  63. else {  
  64. if (!store.empty()) /* 判断是否还有结点的右子树未遍历 */ {
  65. TreeNode < String > tmp = store.pop();
  66. /* 如果有未遍历右子树的结点,但它的右子树为空,且还有结点的右子树未遍历, */
  67. /* 则一直往上取,直到取到未遍历右子树且右子树不为空的结点,遍历它的右子树. */
  68.   
  69. while ((tmp.right() == null) && !store.empty()) {
  70. tmp = store.pop();
  71. }
  72. next = tmp.right();
  73. }  
  74. else {
  75. /* 如果没有哪个结点右子树未遍历,则表示没有下一个结点了,设置next为null */
  76. next = null;
  77. }
  78. }
  79. }  
  80. return current;
  81. }  
  82. public boolean hasMoreElement() {  
  83. return next != null;
  84. }
  85. }  下面写个测试类,不作解释,相信大家看得懂  
  86. public class TreeReader {  
  87. public static void main(String[] args) {
  88. TreeNode < String > n1 = new TreeNode < String > ( "n1");
  89. TreeNode < String > n2 = new TreeNode < String > ( "n2");
  90. TreeNode < String > n3 = new TreeNode < String > ( "n3");
  91. TreeNode < String > n4 = new TreeNode < String > ( "n4");
  92. TreeNode < String > n5 = new TreeNode < String > ( "n5");
  93. TreeNode < String > n6 = new TreeNode < String > ( "n6", null, n1);
  94. TreeNode < String > n7 = new TreeNode < String > ( "n7", n2, null);
  95. TreeNode < String > n8 = new TreeNode < String > ( "n8", n7, null);
  96. TreeNode < String > n9 = new TreeNode < String > ( "n9", null, n5);
  97. TreeNode < String > n10 = new TreeNode < String > ( "n10", n4, n9);
  98. TreeNode < String > n11 = new TreeNode < String > ( "n11", n6, n8);
  99. TreeNode < String > n12 = new TreeNode < String > ( "n12", n3, n10);
  100. TreeNode < String > root = new TreeNode < String > ( "root", n11, n12);
  101. MyTree tree = new MyTree(root);
  102. TreeEnum eum = tree.getEnumerator();  
  103. while (eum.hasMoreElement()) {
  104. System.out.print(eum.next().node + "--");
  105. }
  106. System.out.println( "end");
  107. }
  108. }


 

12. 迭代器


   
   
  1. package TreeIterator;
  2. public interface Iterator {
  3. public boolean hasNext();
  4. public Object next();
  5. }这个接口我们有
  6. 2个方法, hasNext()是否还有下一条数据, next返回具体的 Object这里也就是树。我们先不必要忙着做他的实现类,我们现在要来做的是这个容器(不是 JAVA中容器,与 arraylist什么的无关),正所谓树的容器是什么,是山也!我们想想山应该具有什么呢!?首先它要有种植树的功能,这里可以看作添加树。我们可以想像山的功能是和树相互关联的,那么他们之间是什么关系呢,我们给他们一种聚合的关系,聚合的关系大家可以参考 UML图,我在这里给出它的一种程序表现形式。
  7. package TreeIterator;
  8. public class Hall {
  9. Tree[] tree; // 这里可以看作是聚合关系
  10. private int index; // 指向Tree[]的标签
  11. public Hall(int maxNumber) {
  12. tree = new Tree[maxNumber];
  13. index = 0;
  14. }
  15. public void add(Tree tree) {
  16. this.tree[index] = tree;
  17. index++;
  18. }
  19. public Iterator connectIterator() {
  20. return new TreeIterator( this);
  21. }
  22. }
  23. 这里我们定义的山可以抽象出
  24. Hall类来, Tree[] tree可以看作是山和树之间的一种聚合关系。 add方法就是添加树。问题来了,山和树有了关系,那么山和迭代器有什么关系呢。它们之间肯定有一种关系。我们有了这个容器(山),就要把这个容器来实现迭代的方法: hasNext()和 Next().恩这里我们可以看出,山和迭代器之间也是一种关联关系。我们就把它看成是一种聚合关系(TIP:聚合关系一种特殊的关联关系)。我们可以通过一个 connectIterator方法来链接山和迭代器,接下来我们要去做一个具体的迭代类,这个具体的类中间有了 hasNext()和 Next()的具体实现方法
  25. package TreeIterator;
  26. public class TreeIterator implements Iterator {
  27. private int last = 0;
  28. private Hall hall;
  29. public TreeIterator(Hall hall) {
  30. this.hall = hall;
  31. }
  32. public boolean hasNext() {
  33. if (last < hall.tree.length) return true;
  34. else return false;
  35. }
  36. public Tree next() {
  37. Tree t = hall.tree[last];
  38. last++;
  39. return t;
  40. }
  41. }
  42. 这里Hall hall就可以看作是一种关联关系,我们要把山和迭代器联系起来就通过构造函数来实现, hasNext和 next实现方法就体现出来了有了山,有了迭代器,可是树还没有定义,不过这个树的方法还很好解决!树不关联其他的事务,我们可以简单的这么写:
  43. package TreeIterator;
  44. public class Tree {
  45. private String name;
  46. public Tree(String name) {
  47. this.name = name;
  48. }
  49. public String getName() {
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值