單鏈表實現多項式的加法運算
最近學習數據結構的線性表,有順序存儲和鏈表兩種,多項式的表示和運算,最能鞏固學習成果,現在提供詳細代碼,來實現多項式的加法運算。
多項式用單鏈表最為合適,不會造成更多的資源浪費。
如果你恰好用的這本書--數據結構(Java版)(第4版)(葉核亞),推薦你去下面這個鏈接下載書本源代碼,將更助你學的輕松。
http://download.csdn.net/detail/wang______jing/9907538
1 //單鏈表類,實現一些基本單鏈表的操作 2 public class SinglyList<T> extends Object { 3 public Node<T> head; // 頭指針,指向單鏈表的頭結點 4 5 public SinglyList() { 6 this.head = new Node<T>(); 7 } 8 9 public SinglyList(T[] values) { // values數組中的值構成結點 10 this(); 11 Node<T> rear = this.head; 12 for (int i = 0; i < values.length; i++) { 13 rear.next = new Node<T>(values[i], null); 14 rear = rear.next; 15 } 16 } 17 18 public boolean isEmpty() { 19 return this.head.next == null; 20 } 21 22 public T get(int i) { 23 Node<T> p = this.head.next; 24 for (int j = 0; p != null && j < i; j++) { 25 p = p.next; 26 } 27 return (i >= 0 && p != null) ? p.data : null; 28 } 29 30 public void set(int i, T x) { 31 if (i < 0 || i > size()) 32 throw new IndexOutOfBoundsException(i + ""); 33 if (x == null) 34 throw new NullPointerException("x==null"); 35 Node<T> p = this.head.next; 36 for (int j = 0; p != null && j < i; j++) { 37 p = p.next; 38 } 39 p.data = x; 40 41 } 42 43 public int size() { 44 int len = 0; 45 Node<T> p = this.head.next; 46 if (p == null) 47 return -1; 48 while (p != null) { 49 len++; 50 p = p.next; 51 52 } 53 return len; 54 } 55 56 public Node<T> insert(int i, T x) { 57 if (x == null) 58 throw new NullPointerException("x==null"); 59 Node<T> front = this.head; 60 for (int j = 0; front.next != null && j < i; j++) { 61 front = front.next; 62 } 63 front.next = new Node<T>(x, front.next); 64 return front.next; 65 66 } 67 68 public Node<T> insert(T t) { 69 return insert(Integer.MAX_VALUE, t); 70 } 71 72 public T remove(int i) { 73 Node<T> front = this.head; 74 for (int j = 0; front.next != null && j < i; j++) { 75 front = front.next; 76 } 77 if (i >= 0 && front.next != null) { 78 T old = front.next.data; 79 front.next = front.next.next; 80 return old; 81 } 82 return null; 83 84 } 85 86 public void clear() { 87 this.head.next = null; 88 } 89 90 } 91 // 排序單鏈表,對於一些結點可以實現按順序插入排序 92 public class SortedSinglyList<T extends Comparable<? super T>> extends 93 SinglyList<T> { 94 public SortedSinglyList() { 95 super(); 96 } 97 98 public SortedSinglyList(T[] values) { // values的數組中的對象按值插入 99 super(); 100 for (int i = 0; i < values.length; i++) { 101 this.insert(values[i]); 102 } 103 } 104 105 public SortedSinglyList(SinglyList<T> list) { // 單鏈表的深拷貝 106 super(); 107 for (Node<T> p = list.head.next; p != null; p = p.next) 108 this.insert(p.data); 109 } 110 111 public Node<T> insert(T x) { // 覆蓋父類的insert方法 112 Node<T> front = this.head, p = front.next; 113 while (p != null && x.compareTo(p.data) > 0) { 114 front = p; 115 p = p.next; 116 } 117 front.next = new Node<T>(x, p); // 在front之后,p之前插入x節點 118 return front.next; 119 } 120 121 } 122 123 //可相加接口 124 public interface Addible<T> { 125 public void add(T t); // 兩元素相加 126 127 public boolean removable(); // 刪除元素 128 129 } 130 //比較大小接口 131 public interface Comparable<T> { 132 int compareTo(T obj); 133 134 } 135 136 /* 137 * 一元多項式節點類 存儲多項式的系數(coefficient)和指數(exponential) 138 */ 139 public class PolyNode implements Comparable<PolyNode>, Addible<PolyNode> { 140 private int coef;// 系數 141 private int expo;// 指數 142 143 protected PolyNode next; 144 145 public PolyNode() { 146 this(0, 0); 147 } 148 149 public PolyNode(int coef, int expo) { // 帶參數的構造函數 150 151 this.coef = coef; 152 this.expo = expo; 153 // this.next = null; 154 } 155 156 public PolyNode(PolyNode po) { // 拷貝構造函數 157 this(po.coef, po.expo); 158 } 159 160 public boolean equals(Object obj) // 比較兩項是否相等 161 { 162 if (this == obj) 163 return true; 164 if (!(obj instanceof PolyNode)) 165 return false; 166 PolyNode term = (PolyNode) obj; 167 return this.coef == term.coef && this.expo == term.expo; 168 } 169 170 public PolyNode(String str) { // 參數為一個項時,得到項的系數和指數 171 if (str.charAt(0) == '+') 172 str = str.substring(1); // 去掉‘+’號 173 int i = str.indexOf('x'); 174 if (i == -1) { 175 this.coef = Integer.parseInt(str); // 沒有x,指數就為0 176 this.expo = 0; 177 } else { 178 if (i == 0) { // x在開頭,系數為1 179 this.coef = 1; 180 } else { 181 String str1 = str.substring(0, i);// 截取x符號之前的系數 182 if (str1.equals("-")) { // 為‘-’,系數為-1 183 this.coef = -1; 184 } else { 185 this.coef = Integer.parseInt(str1); 186 } 187 i = str.indexOf('^');// 找^符號 188 if (i == -1) 189 this.expo = 1; 190 else 191 this.expo = Integer.parseInt(str.substring(i + 1)); 192 } 193 } 194 } 195 196 public String toString() { // 顯示多項式的樣式 197 String sy = this.coef > 0 ? "+" : "-"; 198 if (this.expo == 0 || this.expo > 0 && this.coef != 1 199 && this.coef != -1) { 200 sy += Math.abs(this.coef); // 系數絕對值,系數為-1或1不能顯示 201 } 202 if (this.expo > 0) 203 sy += "x";// 指數為0不能輸出x 204 if (this.expo > 1) 205 sy += "^" + this.expo;// 指數為1不能輸出^ 206 return sy; 207 } 208 209 public int compareTo(PolyNode a) { // 比較兩項的大小 210 return (this.expo < a.expo ? -1 : (this.expo == a.expo ? 0 : 1)); 211 } 212 213 public void add(PolyNode po) { // 相加 214 if (this.compareTo(po) == 0) 215 this.coef += po.coef; 216 217 } 218 219 public boolean removable() { // 刪除 220 return this.coef == 0; 221 } 222 223 public int getCoef() { 224 return coef; 225 } 226 227 public void setCoef(int coef) { 228 this.coef = coef; 229 } 230 231 public int getExpo() { 232 return expo; 233 } 234 235 public void setExpo(int expo) { 236 this.expo = expo; 237 } 238 239 } 240 /* 241 * 一元多項式排序鏈表類,提供排序單鏈表的多項式相加運算; 242 */ 243 public class PolySort<T extends Comparable<? super T> & Addible<T>> extends 244 SortedSinglyList<T> { 245 246 public PolySort() { 247 super(); // 構造空單鏈表 248 } 249 250 public PolySort(T value[]) { // 構造方法,項的組來指定各項的值 251 super(value); 252 } 253 254 public PolySort(PolySort<T> list) {// 調用父類的深拷貝函數,復制所有結點 255 super(list); 256 } 257 258 // 多項式相加函數 259 public void addAll(PolySort<T> list) { 260 Node<T> front = this.head, p = front.next; 261 Node<T> q = list.head.next; 262 while (p != null && q != null) { 263 if (p.data.compareTo(q.data) == 0) { // 兩項大小相同 264 p.data.add(q.data); 265 if (p.data.removable()) { // 刪除系數為0的結點 266 front.next = p.next; 267 p = front.next; 268 } else { 269 front = p; 270 p = p.next; 271 272 } 273 q = q.next; 274 } else if (p.data.compareTo(q.data) < 0) { 275 front = p; 276 p = p.next; 277 } else { 278 front.next = new Node<T>(q.data, p); 279 q = q.next; 280 } 281 } 282 while (q != null) // 將list單鏈表中剩余結點復制並插入到當前鏈表尾 283 { 284 front.next = new Node<T>(q.data, null); 285 front = front.next; 286 q = q.next; 287 } 288 } 289 290 } 291 // 多項式類,使用多項式排序單鏈表類作為成員變量,提供多項式相加運算 292 public class Polynomial { 293 private PolySort<PolyNode> list; // 多項式排序單鏈表 294 295 public Polynomial() // 構造方法 296 { 297 this.list = new PolySort<PolyNode>(); // 創建空單鏈表,執行排序單鏈表默認構造方法 298 } 299 300 public Polynomial(PolyNode terms[]) // 構造方法,由項數組指定多項式各項值 301 { 302 this.list = new PolySort<PolyNode>(terms); 303 } 304 305 public Polynomial(String polystr) // 構造方法,參數指定多項式表達式字符串 306 { 307 this(); 308 if (polystr == null || polystr.length() == 0) 309 return; 310 Node<PolyNode> rear = this.list.head; 311 int start = 0, end = 0; // 序號start~end的子串為一項 312 while (start < polystr.length() && end < polystr.length()) { 313 int i = polystr.indexOf('+', end + 1); // 返回字符+在字符串中從end+1開始的序號 314 if (i == -1) // 未找到指定字符 315 i = polystr.length(); 316 int j = polystr.indexOf('-', end + 1); 317 if (j == -1) 318 j = polystr.length(); 319 end = i < j ? i : j; // end為下一個+或-號的序號 320 rear.next = new Node<PolyNode>(new PolyNode(polystr.substring( 321 start, end)), null); 322 // 尾插入,以序號start~end的子串作為一項,創建結點,創建元素對象 323 rear = rear.next; 324 start = end; 325 } 326 } 327 328 public Polynomial(Polynomial poly) // 深度拷貝構造方法,復制所有結點和對象 329 { 330 this(); // 創建空單鏈表,只有頭結點 331 Node<PolyNode> rear = this.list.head; 332 for (Node<PolyNode> p = poly.list.head.next; p != null; p = p.next) // p遍歷poly單鏈表 333 { 334 rear.next = new Node<PolyNode>(new PolyNode(p.data), null);// 復制結點,復制對象 335 rear = rear.next; 336 } 337 } 338 339 public String toString() // 返回多項式的描述字符串 340 { 341 String str = ""; 342 for (Node<PolyNode> p = this.list.head.next; p != null; p = p.next) 343 str += p.data.toString(); 344 return str; 345 } 346 347 public void addAll(Polynomial poly) // 多項式相加,this+=poly 348 { 349 this.list.addAll(poly.list); 350 } 351 352 public Polynomial union(Polynomial poly) // 加法+,C=this+poly 353 { 354 Polynomial polyc = new Polynomial(this); // 深度拷貝,復制所有結點和對象 355 polyc.addAll(poly); // polyc+=poly 356 return polyc; // 返回對象引用 357 } 358 359 public boolean equals(Object obj) // 比較兩個多項式是否相等 360 { 361 return this == obj || obj instanceof Polynomial 362 && this.list.equals(((Polynomial) obj).list); 363 // 比較兩條單鏈表是否相等 364 } 365 } 366 // 測試類,完成多項式的相加結果並顯示 367 public class Poly extends PolySort { 368 369 public static void main(String[] args) { 370 371 System.out.println("//一元多項式"); 372 PolyNode aterms[] = { new PolyNode(-7, 9), new PolyNode(2, 7), 373 new PolyNode(-9, 4), new PolyNode(1, 2), new PolyNode(-1, 1), 374 new PolyNode(2, 0) }; 375 Polynomial apoly = new Polynomial(aterms); 376 377 PolyNode bterms[] = { new PolyNode(9, 11), new PolyNode(5, 10), 378 new PolyNode(-3, 8), new PolyNode(10, 4), new PolyNode(-1, 2), 379 new PolyNode(1, 1), new PolyNode(-1, 0) }; 380 Polynomial bpoly = new Polynomial(bterms); 381 382 // Polynomial bpoly = new Polynomial("-1+x-x^2+10x^4-3x^8+5x^10+9x^11"); 383 System.out.println("A=" + apoly.toString() + "\nB=" + bpoly.toString()); 384 385 Polynomial cpoly = apoly.union(bpoly); 386 System.out.println("C=A+B,C=" + cpoly.toString()); 387 apoly.addAll(bpoly); 388 System.out.println("A+=B,A=" + apoly.toString()); 389 390 } 391 }