• 数据结构之线性结构


    线性结构主要表示一个接一个的关系,或者没有什么关系,但是位置上如果表示一个接一个,那么也方便查询的集合关系。

    主要有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 的内存结构是这样。

    为什么会这样,是因为java库中数组的内存布局就已经成这样了

     

    代码:

    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");
                }
                
            }
            
        }
    }

    测试代码:

    //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();
        }
        
    }
  • 相关阅读:
    CoreBluetooth
    IOS Monkey 测试
    Ruby+appium实现截图、滑屏、长按、日志输出到本地文件夹
    maven中GroupID 和ArtifactID怎么写
    MAC安装Eclipse及对其进入相关配置
    单元测试断言利器 AssertJ
    python+appium app自动化的方法实例运用
    美团接口自动化测试实践
    appium滑动操作总结
    Appium+python自动化-Appium Python API
  • 原文地址:https://www.cnblogs.com/lsfv/p/10198539.html
Copyright © 2020-2023  润新知