線性結構主要表示一個接一個的關係,或者沒有什麼關係,可是位置上若是表示一個接一個,那麼也方便查詢的集合關係。
主要有4種:
順序存儲結構
主要查詢,少刪除的話用順序存儲,由於是物理順序。因此查詢起來用下標,內存地址只須要作加法就能夠。可是元素不少的話,須要從新申請內存。刪除要移動很大塊。
鏈表存儲結構
刪除,插入大部分的話,那麼用鏈表,由於只須要修改幾個節點就能夠。添加也不須要從新申請內存。 可是查詢就效率低,須要一個一個檢索過去。由於位置不是放在一塊。
棧
後進先出。
隊列
先進先出。
環形緩衝區
順序表
5個注意點: 1.java.Cannot create a generic array of T. java 不能創建泛型數組。通常採用這種方式 (T[]) new Object[mDEFAULTSIZE]; 2.高級語言,數組能夠得到長度length,不須要本身額外多一個長度字段。 3.java 的數組,對於非基礎類型來講,其實放置的是指針們。吃鯨。另外關於插入和刪除數據,沒有去找是否有整段移動內存的代碼,一個一個效率仍是慢了。 4.內部類是否用靜態,原則上默認static.除非從關係上來講 和具體對象是一對一的,須要使用具體對象的數據和方法 5.迭代器的有個方法名hasnext? 分明代碼是表達的是isValidate. java命名嚴謹性真是無語。 數組結構比較簡單,沒有必要複習。作一次就能夠了。
arraylist 的內存結構是這樣。html
爲何會這樣,是由於java庫中數組的內存佈局就已經成這樣了java
代碼:node
package com.linson.datastrcture; public interface IList<T> { public boolean add(T item); public boolean insert(int index,T item); public boolean remove(T item); public boolean clear(); public T get(int index); public int contain(T item);///-1 not exist. otherwize : index. public int size(); public boolean isEmpty(); }
package com.linson.datastrcture; import java.util.Iterator; //5個注意點: 1.java.Cannot create a generic array of T. java 不能創建泛型數組。通常採用這種方式 (T[]) new Object[mDEFAULTSIZE]; // 2.高級語言,數組能夠得到長度length,不須要本身額外多一個長度字段。 // 3.java 的數組,對於非基礎類型來講,其實放置的是指針們。吃鯨。另外關於插入和刪除數據,沒有去找是否有整段移動內存的代碼,一個一個效率仍是慢了。 // 4.內部類是否用靜態,原則上默認static.除非從關係上來講 和具體對象是一對一的,須要使用具體對象的數據和方法 // 5.迭代器的有個方法名hasnext? 分明代碼是表達的是isValidate. java命名嚴謹性真是無語。 //數組結構比較簡單,沒有必要複習。作一次就能夠了。 public class MyArrayList<T> implements IList<T>,Iterable<T> { public MyArrayList() { //不可行,是由於T不能保證默認構造函數?可是也能夠在內存中先存儲一些指針地址啊。再以後分配好後,指針放回去不能夠嗎。沒辦法,反正java.Cannot create a generic array of T. //mData=new T[mDEFAULTSIZE]; //代替方案,建立對象的最底基類,object的數組。 Initialize(); } public boolean clear() { Initialize(); return true; } @SuppressWarnings("unchecked") private void Initialize() { mData=(T[]) new Object[mDEFAULTSIZE]; mUsed=0; } private int getCapcity() { return mData.length; } @SuppressWarnings("unchecked") public MyArrayList(int size) { mData=(T[]) new Object[size]; mUsed=0; } @SuppressWarnings("unchecked") private void bigger() { T[] tempArray=(T[]) new Object[getCapcity()*2]; for(int i=0;i<mData.length;i++) { tempArray[i]=mData[i]; } mData=tempArray; } public boolean add(T item) { return insert(mUsed, item); } public boolean insert(int index, T item) { if(mUsed>=getCapcity()) { bigger(); } if(index>=0 && index<=mUsed-1) { for(int i=mUsed-1;i>=index;i--) { mData[i+1]=mData[i]; } mData[index]=item; mUsed++; } else if(index==mUsed) { mData[index]=item; mUsed++; } else { throw new Error("index is outofbounds"); } return true; } public boolean remove(T item) { boolean ret=false; int index=contain(item); if(index!=-1) { for(int i=index+1;i<mUsed;i++) { mData[i-1]=mData[i]; } mData[mUsed-1]=null; mUsed--; ret=true; } return false; } public T get(int index) { if(index>=0 && index<=mUsed-1) { return mData[index]; } else { throw new Error("index is outofbounds"); } } public int contain(T item) { int ret=-1; for(int i=0;i<mUsed;i++) { if(item.equals(mData[i])) { ret=i; } } return ret; } public int size() { return mUsed; } public boolean isEmpty() { return mUsed==0; } public String getInfo() { return "size"+mUsed+". capicity:"+getCapcity(); } private T[] mData=null; private static final Integer mDEFAULTSIZE=8; private Integer mUsed=0; public Iterator<T> iterator() { return new MyArrayIterator(); } //用靜態不方便,迭代器從關係上來講是對象級別,不是類級別,須要某個具體對象的數據和方法。 public class MyArrayIterator implements Iterator<T> { private int position=0; public boolean hasNext()//無力吐槽,這個方法是hasnext? 分明代碼是表達的是isValidate. java這命名嚴謹性。 { return position<=mUsed-1; } public T next() { if(hasNext()) { return mData[position++]; } else { throw new Error("overofbound"); } } } }
測試代碼:api
//arraylist public static class Arraylist { public static void test() { //show info :capcity:xxx. size: //add->show info //list each element; //del.modify. //for each process a fun. MyArrayList<Integer> myData=new MyArrayList<Integer>(); for(int i=0;i<7;i++) { myData.add(i); } myData.insert(6, 11); myData.remove(6); LSLog.printLine(myData.getInfo(), 1); for(int i=0;i<myData.size();i++) { LSLog.printLine(myData.get(i).toString(), 1); } for (Integer myint : myData) { LSLog.printLine(myint.toString(), 1); } } }
注意點函數
1.頭尾節點能夠作成哨兵,一直存在,方便不少處理。頗有意思的設計,能夠在實際開發中多多使用這種技巧。 2.雙鏈表對於大數據,插入仍是有優化做用。 3.鏈表根據索引搜索不像順序存儲那樣直接取下標是一個1的複雜度。而是n因此下先寫個findnode的方法。來完成索引查找,以便給其餘方法調用。 也是一個和順序存儲同樣簡單但想要完美必須花時間處理的例子,作一次就好。不值得複習從新
package com.linson.datastrcture; import java.util.Iterator; //1.頭尾節點能夠作成哨兵,一直存在,方便不少處理。頗有意思的設計,能夠在實際開發中多多使用這種技巧。 //2.雙鏈表對於大數據,插入仍是有優化做用。 //3.鏈表根據索引搜索不像順序存儲那樣直接取下標是一個1的複雜度。而是n因此下先寫個findnode的方法。來完成索引查找,以便給其餘方法調用。 //也是一個和順序存儲同樣簡單但想要完美必須花時間處理的例子,作一次就好。不值得複習從新。 public class MyLinkedList<T> implements IList<T>,Iterable<T> { public MyLinkedList() { initionize(); } private void initionize() { mRoot=new MyLinkedNode<T>(null, null, null); mLast=new MyLinkedNode<T>(null, null, null); mRoot.mNext=mLast; mLast.mPre=mRoot; mSize=0; } //鏈表沒法經過索引快速獲得節點。因此先要完成這個功能。 public MyLinkedNode<T> getNode(int index) { MyLinkedNode<T> ret=null; if(index>=0 && index<=mSize-1) { MyLinkedNode<T> replacedNode=null; if(index>mSize/2) { replacedNode=mLast; for(int i=0;i<mSize-index;i++) { replacedNode=replacedNode.mPre; } } else { replacedNode=mRoot.mNext; for(int i=0;i<index;i++) { replacedNode=replacedNode.mNext; } } ret=replacedNode; } else { throw new Error("index is outofbound."); } return ret; } public boolean add(T item) { return insert(mSize, item); } public boolean insert(int index, T item) { boolean ret=false; MyLinkedNode<T> replaceNode=null; if(index>=0 && index<=mSize-1) { replaceNode=getNode(index); } else if(index==mSize) { replaceNode=mLast; } if(replaceNode!=null) { MyLinkedNode<T> tempNode=new MyLinkedNode<T>(item, replaceNode, replaceNode.mPre); tempNode.mPre.mNext=tempNode; tempNode.mNext.mPre=tempNode; mSize++; ret=true; } return ret; } public boolean remove(T item) { MyLinkedNode<T> theNode= getNodeByElement(item); if(theNode!=null) { theNode.mPre.mNext=theNode.mNext; theNode.mNext.mPre=theNode.mPre; mSize--; } else { throw new Error("can't find element"); } return true; } public boolean clear() { initionize(); return true; } public T get(int index) { MyLinkedNode<T> theNode= getNode(index); if(theNode!=null) { return theNode.mdata; } else { return null; } } // public int contain(T item) { throw new Error("please use getNodeByElement"); } public MyLinkedNode<T> getNodeByElement(T item) { MyLinkedNode<T> ret=null; MyLinkedNode<T> checknode=mRoot.mNext; for(int i=0;i<mSize;i++) { if(checknode.mdata.equals(item)) { ret=checknode; break; } checknode=checknode.mNext; } return ret; } public int size() { return mSize; } public boolean isEmpty() { return mSize==0; } private String Print() { return "size:"+mSize; } // private MyLinkedNode<T> mRoot=null;//小技巧頭尾2個節點是哨兵節點,空數據也存在。2個節點的存在可讓真實頭尾節點跟普通節點同樣處理。 private MyLinkedNode<T> mLast=null; private Integer mSize=0;//冗餘一個字段吧。應該是個經常使用的字段。 public Iterator<T> iterator() { return new MyLinkedListIterator(); } //node public static class MyLinkedNode<T> { public T mdata=null; public MyLinkedNode<T> mNext=null; public MyLinkedNode<T> mPre=null; public MyLinkedNode(T data,MyLinkedNode<T> next,MyLinkedNode<T> pre) { mdata=data; mNext=next; mPre=pre; } } public class MyLinkedListIterator implements Iterator<T> { private MyLinkedNode<T> mCurrent=(MyLinkedNode<T>) mRoot.mNext; public boolean hasNext() { return mCurrent!=mLast; } public T next() { T retT=mCurrent.mdata; mCurrent=mCurrent.mNext; return retT; } } }
public static class linkedList { public static void test() { MyLinkedList<Integer> myData=new MyLinkedList<Integer>(); myData.insert(0, 3); myData.add(4); myData.add(5); myData.insert(0, 2); //myData.remove(4); // for(int i=0;i<myData.size();i++) // { // LSLog.printLine(myData.get(i).toString(), 1); // } for(Integer data :myData) { LSLog.printLine(data.toString(), 1); } } }
棧 組合鏈表實現。佈局
package com.linson.datastrcture; public class MyStack<T> { private MyLinkedList<T> myList2=new MyLinkedList<T>(); public T pop() { T result=top(); if(result!=null) { myList2.remove(myList2.mLast.mPre); } return result; } public T top() { T result=null; if(myList2.mLast.mPre!=myList2.mRoot) { result=myList2.mLast.mPre.mdata; } return result; } public Integer size() { return myList2.size(); } public boolean push(T item) { boolean result=false; return myList2.add(item); } }
隊列 ,組合鏈表實現。測試
package com.linson.datastrcture; public class MyQuene<T> { private MyLinkedList<T> theLinkedList=new MyLinkedList<T>(); public T top() { T resulT=null; if(theLinkedList.size()>0) { resulT=theLinkedList.mRoot.mNext.mdata; } return resulT; } public T deQueue() { T resulT=top(); if(top()!=null) { theLinkedList.remove(theLinkedList.mRoot.mNext); } return resulT; } public void inQueue(T item) { theLinkedList.add(item); } public int size() { return theLinkedList.size(); } }