数据结构实现分享(1)
1.数组实现可以扩容的顺序表
1 /** 2 * 利用数组实现可以自动扩容的顺序表,顺序表下标从1开始 3 * 对于线性表来说,插入的新的数据不能使表的中间出现空隙,所以插入位置在1-length之间 4 * @author ZW 5 * @param <T> 6 * @version 1.1 7 */ 8 public class list<T> { 9 10 final int inisize = 10;// 线性表的初始大小 11 12 private int length;// 线性表的实时长度 13 14 private T[] listArray;// 利用泛型数组来实现线性表 15 16 /** 17 * 线性表具有的方法:初始化,新增元素,删除元素,查找元素,获取元素,修改元素等。 18 */ 19 public list() { 20 this.length = 0; 21 listArray = (T[]) new Object[inisize]; 22 } 23 24 public list(int n) { 25 if (n < 0) { 26 System.out.println("error"); 27 System.exit(1); 28 } else { 29 this.length = 0; 30 listArray = (T[]) new Object[n]; 31 } 32 } 33 34 public boolean add(T obj, int pos) { 35 // 如果插入的位置不合法 36 if (pos < 1 || pos > length + 1) { 37 System.out.println("pso值不合法"); 38 return false; 39 } 40 // list容量不足,对数组扩容 41 if (length == listArray.length) { 42 T[] p = (T[]) new Object[length * 2];// 扩容 43 for (int i = 0; i < length; i++) { 44 p[i] = listArray[i]; 45 } 46 listArray = p; 47 } 48 for (int i = length; i >= pos; i--) { 49 listArray[i] = listArray[i - 1]; 50 } 51 listArray[pos - 1] = obj; 52 length++; 53 return true; 54 } 55 56 public Object delete(int pos) { 57 if (isEmpty()) { 58 System.out.println("error,顺序表为空"); 59 return null; 60 } else if (pos < 1 || pos > length) { 61 System.out.println("error,pos值不合法"); 62 return null; 63 } 64 T x = listArray[pos - 1]; 65 for (int i = pos; i <= length; i++) { 66 listArray[i - 1] = listArray[i]; 67 } 68 length--; 69 return x; 70 } 71 72 public int find(Object obj) { 73 if (isEmpty()) { 74 System.out.println("error,线性表为空"); 75 return -1; 76 } else { 77 for (int i = 0; i < length; i++) { 78 if (obj.equals(listArray[i])) { 79 return i + 1; 80 } 81 } 82 return -1; 83 } 84 } 85 86 public Object get(int pos) { 87 if (isEmpty()) { 88 System.out.println("error,线性表为空"); 89 return null; 90 } else if (pos < 1 || pos > length) { 91 System.out.println("error,pos值错误"); 92 return null; 93 } 94 return listArray[pos - 1]; 95 } 96 97 public boolean modify(T obj, int pos) { 98 if (isEmpty()) { 99 System.out.println("error,线性表为空"); 100 return false; 101 } else if (pos < 1 || pos > length) { 102 System.out.println("error,pos值错误"); 103 return false; 104 } 105 listArray[pos - 1] = obj; 106 return true; 107 } 108 109 public boolean isEmpty() { 110 return length == 0; 111 } 112 113 public int size() { 114 // TODO 自动生成的方法存根 115 return length; 116 } 117 118 public void nextOrder() { 119 for (int i = 0; i < length; i++) { 120 System.out.println(listArray[i]); 121 } 122 123 } 124 125 public void clear() { 126 length = 0; 127 128 } 129 130 }
2.链表实现顺序表
/*关于链表的注意事项:链表的位置从头元素的下一元素开始为1,但是链表的位置不代表链表中节点的实际地址(引用) * 因此,无论增删改都需要从第一个节点开始对链表进行依次查找,找到需要操作的节点地址(引用)*/ public class linkList<T> { private Node<T> head;// 头结点 private int length;// 链表长度 /* 单链表的无参构造 */ public linkList() { this.length = 0; this.head = new Node<T>(null); // 该处不采用this.head=null; 其原因:链表创建时头结点是存在的,只不过其指向下个节点的引用为null。 } /* 获取头结点地址 */ public Node<T> getHead() { return this.head; } /* 向链表中插入一个元素 */ public boolean insert(T obj, int pos) { if (pos < 1 || pos > length + 1) { // 单链表并非通过数组实现,其长度受限于其上一个节点是否存在,故其插入位置不因>length+1 System.out.println("pos值不合法"); return false; } int num = 1; Node<T> p = head; Node<T> q = head.next; /* * 算法总结: 1.利用p q来表示两个相邻链表,while遍历到要插入的位置。 * 2.将前一节点P的next引用到要插入的元素,利用插入节点的构造方法将next引用到Q节点 */ while (num < pos) { p = q; q = q.next; num++; } p.next = new Node<T>(q, obj); length++; return true; } /* 删除链表中的一个元素 */ public T remove(int pos) { if (empty()) { System.out.println("链表为空,无法删除!"); return null; } else if (pos < 1 || pos > length + 1) { System.out.println("pos值不合法"); return null; } else { int num = 1; Node<T> p = head; Node<T> q = head.next; while (num < pos) { p = q; q = q.next; num++; } p.next = q.next; length--; return q.data; } } /* 获取链表中的一个元素 */ public T get(int pos) { if (empty()) { System.out.println("链表为空,无法找到元素!"); return null; } else if (pos < 1 || pos > length + 1) { System.out.println("pos值不合法"); return null; } else { int num = 1; Node<T> p = head; Node<T> q = head.next; while (num < pos) { p = q; q = q.next; num++; } return q.data; } } /* 在链表中查找某个元素 */ public int find(T obj) { if (empty()) { System.out.println("链表为空"); return -1; } else { Node<T> q = head; for (int i = 1; i <= length; i++) { q = q.next; if (q.data.equals(obj)) { return i; } } return -1; } } /* 在链表中更新某个元素 */ public boolean modify(T obj, int pos) { if (empty()) { System.out.println("链表为空,无法更新元素!"); } else if (pos < 1 || pos > length + 1) { System.out.println("链表为空,无法更新元素!"); return false; } int num = 1; Node<T> q = head.next; while (num < pos) { q = q.next; num++; } q.data = obj; return true; } /* 判断链表是否为空 */ public boolean empty() { return length == 0; } /* 求链表中的元素数 */ public int size() { return length; } /* 遍历表中所有元素并向控制台输出 */ public void printAll() { Node<T> p = head.next; while (p != null) { System.out.println(p.data); p = p.next; } } /* 销毁链表 */ public void clear() { length = 0; head.next = null; } }
链表节点的实现:
/** * 链表的节点类 */ public class Node<T> { T data;// 节点的数据部分 Node<T> next;// 节点的引用部分 /* 节点的构造方法,参数为下个节点引用 */ public Node(Node<T> n) { this.next = n; } /* 节点的构造方法,参数N初始化引用,参数data初始化数据 */ public Node(Node<T> n, T data) { this.data = data; this.next = n; } /* 获取节点类数据的方法 */ public T getdata() { return this.data; } /* 获取节点引用的方法 */ public Node<T> getNext() { return this.next; } }