數據結構之線性結構

線性結構主要表示一個接一個的關係,或者沒有什麼關係,可是位置上若是表示一個接一個,那麼也方便查詢的集合關係。

主要有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();
    }
    
}
相關文章
相關標籤/搜索