1. 程式人生 > >陣列和連結串列的區別及使用場景

陣列和連結串列的區別及使用場景

學習一門語言我們基本都會用到陣列和連結串列,那麼這兩種結構肯定是有各自的優缺點的,俗話說沒有對比就沒有傷害哈(大笑),不管是一個什麼東西都 是如此,接下來我就來分析分析他們各自的特點(沒有分析到位的話不要見怪哈,請盡情下評論區留言,一起交流交流)

陣列:我們知道不管是一維陣列還是二維陣列培訓它們在記憶體裡面的地址都 必須是連續的

優點:既然地址是連續的那麼必然給我查詢資料提供了極大的方便,讓我們很容易的就能根據下標找到你需要的資料,提高了我們的效率

缺點:我們剛剛在它的優點中只講到提高我們查詢資料的效率,因為畢竟我們對陣列的運用不只是查詢資料,還有增加資料,插入資料,刪除資料等一些操作;由於陣列的特殊性,使得我們在進行這些操作的時候不能對其進行直接操作,還要重新開闢一個新的陣列並使其長度增加來存放資料,這樣的工作模式給我們帶來了很大的不便,影響了效率

連結串列:連結串列的地址不是連續的,可以隨意存放,刪除等操作,通過引用來關聯資料,連結串列可以分為單向的和雙向的

優點:連結串列和陣列的差別就在於連結串列在對資料進行插入和刪除的時候可以不用開闢新的空間,只需要找到需要操作的結點就可以了,大大提高了人我們的效率

缺點:陣列利於了查詢,那連結串列就不利於查詢咯

下面是我們上課的時候做的關於一個雙向連結串列的練習

/**
 * 雙向連結串列
 * @author Administrator
 *
 * @param <E>
 */
public class MyLinkList<E> {


	public Node<E>head=null;
	public Node<E>last=null;
	public int num=0;
	
	//增加資料
	public void add(E e){
		//建立一個新結點
		Node<E> node=new Node<E>(e);
		//判斷連結串列中是否有結點,如果有就將node作為連結串列的最後一個結點
		if(last!=null){
			last.next=node;
			node.front=last;
			last=node;
		}//如果沒 有那麼node既是頭結點也是尾結點
		else{
			head=node;
			last=node;
		}
		num++;
	}
	
	//插入資料
	public void insert(int index,E e){
		//建立一個新的結點
				Node<E> node=new Node<E>(e);
				//找到index的結點位置
				Node<E> n1=getNode(index);
				//找到n1的前一個結點
				Node<E> n2=n1.front;
				
				n2.next=node;
				node.front=n2;
				
				node.next=n1;
				n1.front=node;
				
				num++;
	}
	
	//根據下標刪除資料
	public void delete(int index){
		Node<E> node=getNode(index);
		Node<E> n1=node.front;
		Node<E> n2=node.next;
		n1.next=n2;
		n2.front=n1;
		num--;
	}
	
	//根據內容刪除資料
	public void delete(E e){
		int index=getIndex(e);
		delete(index);
		
	}
	
	//修改資料
	public void updata(int index, E e){
		Node<E> node=getNode(index);
		node.data=e;
	}
	
	//取出資料
	public E get(int index){
		Node<E> node=getNode(index);//建立結點呼叫根據下標找結點的函式
		return node.data;
	}
	
	//根據內容確定下標
	private int getIndex(E e){
		int index=-1;
		Node<E> n=head;
		while(n!=null){
			index++;
			//判斷n所指向的結點的值是否和我們要找的那個值相等,相等退出,否則將n指向下一個結點
			if(n.data.equals(e)){
				break;
			}
			n=n.next;
		}
		return index;//返回找到的結點的下標
	}
	
	//根據下標確定結點
	private Node<E> getNode(int index){
		//定義一個變數為一個不存在的值
		int t=-1;
		//判斷index是否在結點資料內
		if(index>=0&&index<num){
			//定義一個n指向頭結點
			Node<E> n=head;
			//判斷n所指向的結點的值是否為空
			while(n!=null){
				t++;
				//判斷t是否和我們要查詢的下標相等,如果相等就說明找到了我們要找的結點,就返回結點n
				//否則就將n指向它的下一個結點
				if(t==index){
					break;
				}
				n=n.next;
			}
			return n;
		}
		else{
			// 丟擲異常
			throw new IndexOutOfBoundsException("下標超出邊界!index:" + index
			+ ",size:" + num);
		}
	}
	
	//結點的個數
	public int size(){
		return num;
	}
}

//內部的結點類,主要是為MyLinkList服務
class Node<E> {
	//連結串列的三大基本屬性
	//結點的資料
	E data;
	//對下一個結點的引用
	Node<E> next;
	//對上一個結點的引用
	Node<E> front;
	
	//建立結點物件的時候必須指定資料
	public Node(E e){
		data=e;
	}
}

 主函式

public static void main(String[] args) {
		MyLinkList<String> list = new MyLinkList<String>();

		//增加資料
		list.add("aa");
		list.add("bb");
		list.add("cc");
		list.add("dd");
		list.add("ee");
		
		//插入資料
		list.insert(2,"nana");
		
		//修改資料
		list.updata(1, "tx");
		
		//根據下標刪除資料
		list.delete(3);
		
		//根據內容刪除資料
		list.delete("tx");
		
		//輸出
		for(int i=0;i<list.size();i++){
			String s=list.get(i);
			System.out.println(s);
		}
	}