数据结构之【线性表】--复习

时间:2021-03-29 10:30:41

一、线性表简介

 

线性表简单地说就是数据元素的序列,即一对一关系;

 

二、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指针,指向前驱;

数据结构之【线性表】--复习