一、线性表简介
线性表简单地说就是数据元素的序列,即一对一关系;
二、ArrayList简单实现
读取:O(1)
插入、删除:O(n)
代码实现:
package org.xiazdong.list;
public class MyArrayList<T> {
private static final int DEFAULT_LENGTH = 10;
private T[]t;
private int length;
public MyArrayList(){
t = (T[])new Object[DEFAULT_LENGTH];
length = 0;
}
public MyArrayList(int length){
t = (T[])new Object[length];
length = 0;
}
public MyArrayList(T[]arr){
this(arr.length*2);
for(int i=0;i<arr.length;i++){
t[i] = arr[i];
}
}
public boolean isEmpty(){
return length == 0;
}
public void makeEmpty(){
t = (T[])new Object[t.length];
length = 0;
}
public T get(int i)throws ArrayIndexOutOfBoundsException{
if(i<0||i>=length){
throw new ArrayIndexOutOfBoundsException("数组越界");
}
else{
return t[i];
}
}
public boolean contains(T e){
for(T elem:t){
if(elem.equals(e)){
return true;
}
}
return false;
}
public boolean insert(T e){
if(e==null){
return false;
}
//如果容量不够,则扩充
if(length>=t.length){
larger(length*2);
}
t[length++] = e;
return true;
}
public boolean remove(T e){
int pos = -1;
for(int i=0;i<length;i++){
if(t[i].equals(e)){
pos = i;
}
}
if(pos == -1){
return false;
}
else{
for(int j=pos;j<length-1;j++){
t[j] = t[j+1];
t[j+1] = null;
}
length--;
return true;
}
}
public boolean remove(int i){
if(i<0||i>=length){
throw new ArrayIndexOutOfBoundsException();
}
else{
for(int j=i;j<length-1;j++){
t[j]= t[j+1];
t[j+1] = null;
}
length--;
return true;
}
}
public boolean insert(int i,T e){
if(i<0||i>length){
throw new ArrayIndexOutOfBoundsException();
}
if(length>=t.length){
larger(length*2);
}
for(int j=t.length-1;j>=i;j--){
t[j+1]= t[j];
}
t[i] = e;
length++;
return true;
}
private void larger(int len){
T[]tmp = (T[])new Object[len];
for(int i=0;i<t.length;i++){
tmp[i] = t[i];
}
t = tmp;
}
public String toString(){
StringBuilder buf = new StringBuilder();
for(int i=0;i<length;i++){
buf.append(t[i]).append(" ");
}
return buf.toString();
}
public int find(T e){
for(int i=0;i<length;i++){
if(t[i].equals(e)){
return i;
}
}
return -1;
}
public int getSize(){
return length;
}
}
三、LinkedList简单实现
读取:O(n)
插入、删除:O(1)
头指针:第一个节点的存储地址;
头结点:在第一个数据节点前添加一个头结点,可以存储链表的长度,为了方便链表操作,因为比如:
代码实现:
package org.xiazdong.list;
/**
*
*
*
* @author xzdong
*
* @param <T>
*/
public class MyLinkedList<T> {
/**
* first.elem存储链表长度
*/
private BeginNode first;
public MyLinkedList(){
first = new BeginNode(0,null);
}
public void insert(T elem){
Node n = new Node(elem,null);
Node current = first;
while(current.next!=null){
current = current.next;
}
current.next = n;
first.elem++;
}
public void insert(int i,T elem){
if(i<0||i>first.elem){
throw new ArrayIndexOutOfBoundsException();
}
Node current = first;
Node n = new Node(elem,null);
int count = 0;
while(current.next!=null&&count<i){
current = current.next;
count++;
}
n.next = current.next;
current.next = n;
first.elem++;
}
public boolean remove(int i,T elem){
if(first.elem==0){
return false;
}
if(i<0||i>first.elem){
throw new ArrayIndexOutOfBoundsException();
}
//1.找到位置
Node current = first;
int count = 0;
while(current.next!=null&&count<i){
current = current.next;
count++;
}
//2.模版代码
current.next = current.next.next;
first.elem--;
return true;
}
public boolean isEmpty(){
return first.elem==0;
}
public void makeEmpty(){
first.next=null;
}
public int getSize(){
return first.elem;
}
public int find(T elem){
Node current = first;
int index = 0;
while(current.next!=null){
current = current.next;
if(current.elem.equals(elem)){
return index;
}
else{
index++;
}
}
return -1;
}
public boolean remove(T elem){
if(first.elem==0){
return false;
}
Node current = first.next;
Node beforeCurrent = first;
while(!current.elem.equals(elem)){
if(current.next==null){
return false;
}
beforeCurrent = current;
current = current.next;
}
if(current.elem.equals(elem)){
beforeCurrent.next = current.next;
first.elem--;
return true;
}
else{
return false;
}
}
public T get(int i){
if(i<0||i>first.elem){
throw new ArrayIndexOutOfBoundsException();
}
int count = 0;
Node current = first;
while(current.next!=null&&count<i){
current = current.next;
count++;
}
return current.next.elem;
}
public String toString(){
StringBuilder buf = new StringBuilder();
if(first.elem==0){
return "";
}
Node current = first.next;
while(current!=null){
buf.append(current.elem).append(" ");
current = current.next;
}
return buf.toString();
}
class Node{
public Node(){
elem = null;
next = null;
}
public Node(T elem,Node next){
this.elem = elem;
this.next = next;
}
private T elem;
Node next;
}
class BeginNode extends Node{
int elem;
public BeginNode(int elem,Node next){
this.elem = elem;
this.next = next;
}
}
}
四、两种实现的比较
数组实现 | 链表实现 | |
优点 | 读取快 | 不需要预先分配、插入删除方便 |
缺点 | 预先分配大小、插入删除麻烦 | 读取慢 |
循环链表实现
循环链表就是尾指针指向头指针,形成一个循环;
代码实现:
package org.xiazdong.list;
/**
*
*
*
* @author xzdong
*
* @param <T>
*/
public class MyCircularLinkedList<T> {
/**
* first.elem存储链表长度
*/
private BeginNode first;
public MyCircularLinkedList(){
first = new BeginNode(0,null);
first.next = first;
}
public void insert(T elem){
Node n = new Node(elem,first);
Node current = first;
while(current.next!=first){
current = current.next;
}
current.next = n;
first.elem++;
}
public void insert(int i,T elem){
if(i<0||i>first.elem){
throw new ArrayIndexOutOfBoundsException();
}
Node current = first;
Node n = new Node(elem,null);
int count = 0;
while(current.next!=null&&count<i){
current = current.next;
count++;
}
n.next = current.next;
current.next = n;
first.elem++;
}
public boolean remove(int i,T elem){
if(first.elem==0){
return false;
}
if(i<0||i>first.elem){
throw new ArrayIndexOutOfBoundsException();
}
//1.找到位置
Node current = first;
int count = 0;
while(current.next!=first&&count<i){
current = current.next;
count++;
}
//2.模版代码
current.next = current.next.next;
first.elem--;
return true;
}
public boolean isEmpty(){
return first.elem==0;
}
public void makeEmpty(){
first.next=first;
}
public int getSize(){
return first.elem;
}
public int find(T elem){
Node current = first;
int index = 0;
while(current.next!=first){
current = current.next;
if(current.elem.equals(elem)){
return index;
}
else{
index++;
}
}
return -1;
}
public boolean remove(T elem){
if(first.elem==0){
return false;
}
Node current = first.next;
Node beforeCurrent = first;
while(!current.elem.equals(elem)){
if(current.next==first){
return false;
}
beforeCurrent = current;
current = current.next;
}
if(current.elem.equals(elem)){
beforeCurrent.next = current.next;
first.elem--;
return true;
}
else{
return false;
}
}
public T get(int i){
if(i<0||i>first.elem){
throw new ArrayIndexOutOfBoundsException();
}
int count = 0;
Node current = first;
while(current.next!=first&&count<i){
current = current.next;
count++;
}
return current.next.elem;
}
public String toString(){
StringBuilder buf = new StringBuilder();
if(first.elem==0){
return "";
}
Node current = first.next;
while(current!=first){
buf.append(current.elem).append(" ");
current = current.next;
}
return buf.toString();
}
class Node{
public Node(){
elem = null;
next = null;
}
public Node(T elem,Node next){
this.elem = elem;
this.next = next;
}
private T elem;
Node next;
}
class BeginNode extends Node{
int elem;
public BeginNode(int elem,Node next){
this.elem = elem;
this.next = next;
}
}
}
双向链表介绍
在单链表的基础上,每个节点增加pre指针,指向前驱;