1.线性表的顺序存储,需要在内存中找到一块连续的空间,容易造成空间冗余,但由于是利用数组实现的关系,根据数组的下标可以精确快速的进行查询操作,但在进行增删操作时需要对其余元素进行移动,且涉及扩容,所以增删操作效率较低,在进行注重查询的业务时建议使用。
public Object [] elements;
private int size;
private final int DEFULT_CAPACITY = 8;
public MyArrayList(){
elements = new Object[DEFULT_CAPACITY];
}
@Override
public int getSize() {
return size;
}
@Override
public boolean isEmpty() {
if (size == 0){
return true;
}else {
return false;
}
}
@Override
public void insert(Object e){
if (size == elements.length){
expand();
}
elements[size] = e;
size++;
}
@Override
public void insertOfIndex(int i, Object e) {
if (i < 0 || i >size){
throw new ArrayIndexOutOfBoundsException("插入失败");
}
if (size == elements.length){
expand();
}
for (int j = size; j > i ; j--){
elements[j] = elements[j-1];
}
elements[i] = e;
size++;
}
@Override
public int indexOf(Object e) {
for (int i = 0; i < elements.length; i++){
if (elements[i] == e){
return i ;
}
}
return -1;
}
@Override
public void get(int index) {
System.out.println(elements[index]);
}
@Override
public boolean contains(Object e) {
for (int i = 0; i < size; i++){
if (elements[i] == e){
return true;
}
}
return false;
}
@Override
public Object replace(int index, Object e) {
if (index < 0| index >= size){
throw new ArrayIndexOutOfBoundsException();
}
Object old = elements[index];
elements[index] = e;
System.out.println(Arrays.toString(elements));
return old;
}
@Override
public Object remove(int index) {
//判断是否越界
if (index < 0 || index >= size){
throw new ArrayIndexOutOfBoundsException("越界");
}
Object O = elements[index];
for (int i = index; i < size-1; i++){
elements[i] = elements[i+1];
}
elements[size - 1] = null;
size--;
return O;
}
@Override
public void insertFrom(int index,Object e) {
insertOfIndex(index,e);
}
@Override
public void insertAfter(int index,Object e) {
insertOfIndex(index+1,e);
}
private void expand() {
Object [] newelements = new Object[elements.length * 2];
for (int i = 0; i <= elements.length; i++){
newelements[i] = elements[i];
}
this.elements = newelements;
}
@Override
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append('[');
for (int i =0; i < size ; i++){
sb.append(elements[i]);
if (i < size - 1){
sb.append(',');
}
}
sb.append(']');
return sb.toString();
}
2.线性表的链式存储,由多个节点构成,每一个节点包含了数据域,后继域,或前驱域,存储时,不需要是连续的空间,不容易造成空间冗余,在插入删除时不需要移动元素,只需要更改相邻元素的前驱后继即可,但在查询时由于没有数组的下标优势,每次查询都需要进行遍历,查询效率较低,在进行注重增删的业务时建议使用
单链表的实现
private Node head;
private int size;
@Override
public int getSize() {
return size;
}
@Override
public boolean isEmpty() {
return size == 0;
}
@Override
public void insert(Object e) {
insertOfIndex(size,e);
}
@Override
public void insertOfIndex(int i, Object e) {
if (i < 0 || i > size){
throw new IndexOutOfBoundsException("越界");
}
Node node = new Node(e,null);
//链表为空时
if (head == null){
head = node;
size++;
}
//插入零号位
else if (i == 0){
node.next = head;
head = node;
size++;
}else {
Node pnode = head; //创建指针节点
//插入中间
for (int j = 1; j <= i - 1; j++) {
pnode = pnode.next;
}
node.next = pnode.next;
pnode.next = node;
size++;
}
}
@Override
public int indexOf(Object e) {
Node pnode = head;
for (int i = 0; i < size; i++){
if (e == null && pnode.data == null){
return i;
}else if (pnode != null && pnode.data == e){
return i;
}
pnode = pnode.next;
}
return -1;
}
@Override
public Node get(int index) {
if (index < 0 || index >= size){
System.out.println("元素不存在");
}
return findNode(index);
}
@Override
public boolean contains(Object e) {
if (indexOf(e) != -1){
return true;
}else {
return false;
}
}
@Override
public Node replace(int index, Object e) {
Node pnode = head;
for (int i = 1; i <= index;i++){
pnode = pnode.next;
}
Node oldNode= pnode;
pnode.data = e;
return oldNode;
}
@Override
public Node remove(int i) {
if (i < 0 || i >= size){
throw new IndexOutOfBoundsException("yuejie");
}
Node oldnode = null;
if (i == 0){
oldnode = head;
head = head.next;
size--;
return oldnode;
}
Node pnode = head;
for (int j = 1 ; j < i; j++){
pnode = pnode.next;
}
oldnode = pnode.next;
pnode.next = pnode.next.next;
size--;
return oldnode;
}
@Override
public boolean insertFrom(Object p, Object e) {
int i = indexOf(p);
if (i < 0){
return false;
}
insertOfIndex(i,e);
return true;
}
@Override
public boolean insertAfter(Object p, Object e) {
int i = indexOf(p);
if (i < 0){
return false;
}
insertOfIndex(i+1,e);
return true;
}
public Node findNode(int index){
Node node = head;
for (int i = 1; i <= index; i++ ){
node = node.next;
}
return node;
}
class Node{
private Object data;
private Node next;
public Node(Object e, Node next) {
this.data = e;
this.next = next;
}
@Override
public String toString() {
return data.toString();
}
}
@Override
public String toString() {
Node pnode = head;
StringBuilder sb = new StringBuilder();
sb.append("[");
for (int i = 0; i < size; i++){
int j = i+1;
sb.append("{");
sb.append("node"+j+": e = "+ pnode.data + ",next = "+pnode.next + "\tsize ="+size);
sb.append("}\t");
pnode = pnode.next;
}
sb.append("]");
return sb.toString();
}
双向链表的实现
Link head;
Link tail;
int size;
@Override
public int getSize() {
return size;
}
@Override
public boolean isEmpty() {
return size == 0;
}
@Override
public boolean contain(Object o) {
return indexOf(o)>=0;
}
@Override
public int indexOf(Object o) {
Link plink = head;
for (int i = 0 ; i < size; i++){
if (plink.data.toString().equals(o.toString())){
return i;
}
plink=plink.next;
}
return -1;
}
@Override
public Object get(int index) {
return findLink(index).data;
}
@Override
public Object insertOfIndex(int index, Object o) {
Link link = new Link(null,o,null);
if (index < 0 || index >size){
throw new IndexOutOfBoundsException("越界");
}
if (index == 0){
addFirst(o);
}else if (index == size) {
link.prev = tail;
tail.next = link;
tail = link;
size++;
}else {
Link link1 = findLink(index);
link.next = link1;
link.prev = link1.prev;
link1.prev.next = link;
link1.prev = link;
size++;
}
return o;
}
private void addFirst(Object o) {
Link link = new Link(null, o, null);
if (head == null){
head = link;
tail = link;
}else{
link.next = head;
head.prev = link;
head = link;
}
size++;
}
@Override
public Object remove(int index) {
if (index > size||index<0){
throw new IndexOutOfBoundsException("越界");
}else if (index == 0){
head = head.next;
head.prev = null;
}else if (index ==size-1){
tail = tail.prev;
tail.next = null;
}else {
Link link1 = findLink(index);
link1.prev.next = link1.next;
link1.next.prev = link1.prev;
}
size--;
return null;
}
@Override
public Object replace(int index, Object o) {
Link newLink = new Link(null, o, null);
Link link = findLink(index);
if (index == 0) {
newLink.next = link.next;
link.next.prev = newLink;
head = newLink;
}else if (index == size-1){
newLink.prev = link.prev;
link.prev.next = newLink;
tail = newLink;
}else {
link.prev.next = newLink;
link.next.prev = newLink;
newLink.next = link.next;
newLink.prev = link.prev;
}
return o;
}
@Override
public Object insertAfter(Object p, Object o) {
int index = indexOf(p);
if (index == size-1){
insertOfIndex(size,o);
tail = tail.next;
}else {
insertOfIndex(index + 1, o);
}
return o;
}
private Link findLink(int index){
Link plink = head;
for (int i =0; i < index;i++){
plink=plink.next;
}
return plink;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
Link plink = head;
sb.append("{");
for (int i = 0; i < size ; i++){
sb.append("[");
sb.append(plink);
sb.append("]");
plink = plink.next;
}
sb.append("}");
return sb.toString();
}
class Link{
Link prev;
Object data;
Link next;
public Link(Link prev, Object data, Link next) {
this.prev = prev;
this.data = data;
this.next = next;
}
@Override
public String toString() {
return data.toString();
}
}