• 数据结构--线性表


    C++中有析构函数,用于销毁对象时释放内存,而Java中因为有gc(垃圾回收机制)所以就没有析构函数,但是java有finalize() 方法,两者的用途相近。

    具体请参考链接:http://blog.csdn.net/jemasw/article/details/8470480

    什么是线性表?

    官方定义:线性表是n个数据元素的有限序列

    顺序表和链表互为补充;

    定义解读:n个(个数),元素(可以是复杂元素对象,也可以是单个数据),有限(有限的),序列(是一个序列集合)

    线性表分为两大类:数组和链表

    顺序表

    前驱:指定元素前一个元素

    后继:指定元素的后一个元素

    优点:可以通过下标遍历寻址,所以遍历和寻址极为快速。

    缺点:插入和删除元素,因为要移动后面的所有元素,所以较为缓慢。

    链表

    单链表:

    单链表,每个节点分为两部分,分别为 数据域  指针域

    initChainList(); 初始化链表

    void destroyList(); 销毁链表,废弃

    boolean isListEmpty(); 判断链表是否为空

    int listLength(); 获取链表的长度

    void clearList(); 清空链表的所有元素

    Node listInsertHead(Node node); 插入头节点

    Node listInsertTail(Node node); 插入尾节点

    Node insertElement(int i, Node node); 指定位置插入节点

    Node deleteElement(int i); 删除指定节点

    Node getElement(int i); 获取指定位置节点

    int elementLocate(Node node); 获取指定节点所在的位置

    Node priorElement(Node node); 找到指定节点的前驱

    Node nextElement(Node node); 找到指定节点的后继

    void listTraverse(); 遍历链表

    循环链表

    简单的说,就是首尾相连的单链表即尾节点的指针域指向首节点的位置

    双向链表

    双向链表,每个节点分为三部分,分别为:

    前指针域:顺向指向下一个节点的位置

    数据域:数据节点

    后指针域:逆向指向下一个节点的位置

    静态链表

    此处附上顺序表的创建代码:

    package util;
    
    public class MyList {
        //线性表本身
        private Object myList[];
        //线性表的大小,即最大容量
        private int listSize;
        //线性表的长度,即线性表中的元素个数
        private int myLength;
        
        
        
        public MyList() {
            super();
        }
    
        /**
         * 初始化线性表 - 顺序表
         * @param size
         */
        public MyList(int size) {
            listSize = size;
            //申请线性表内存
            myList = new Object[listSize];
            myLength = 0;
        }
        
        /**
         * 销毁线性表
         */
        public void DestroyList(){
            myList = null;
        }
        
        /**
         * 清空线性表元素
         */
        public void clearList(){
            myLength = 0;
        }
        
        /**
         * 判断线性表是否为空
         * @return
         */
        public boolean isListEmpty(){
            return myLength == 0 ? true : false;
        }
        
        /**
         * 获取线性表的元素个数
         * @return
         */
        public int listLength(){
            return myLength;
        }
        /**
         * 获取下标位置的元素
         */
        public Object getElement(int i)
        {
            //需要将i入参进行一定的限制,因为元素存在的位置坐标仅限于0到线性表的个数减一(即0~myLength-1),所以如果i小于0或者i大于等于线性表的长度都判定为获取失败返回null
            if(i < 0 || i >= myLength){
                return null;
            }
            return myList[i];
        }
        
        /**
         * 获取线性表中元素所在的位置(只获取第一个遇到的位置)
         * @param element
         * @return
         */
        public int elementLocate(Object element){
            for (int i = 0; i <= myLength; i++){
                if (element.equals(myList[i]))
                {
                    return i;
                }
            }
            return -1;
        }
        
        /**
         * 获取指定元素前驱
         * @param element
         * @return
         */
        public Object priorElement(Object element){
            int i = elementLocate(element);
            if(i == -1){
                //如果i==-1那么则表示当前线性表中没有找到元素,所以直接判定失败,返回null
                return null;
            }else if(i == 0){
                //如果i==0则该元素本身就是第一个元素,前面不可能再有前驱,所以返回null
                return null;
            }else{
                return myList[i - 1];
            }
        }
        
        /**
         * 获取指定元素后缀
         * @param element
         * @return
         */
        public Object nextElement(Object element){
            int i = elementLocate(element);
            if(i == -1){
                return null;
            }else if(i == myLength-1){
                return null;
            }else{
                return myList[i + 1];
            }
        }
        
        /**
         * 在指定位置插入元素
         * @param i
         * @param element
         * @return
         */
        public Object insertElement(int i, Object element)
        {
            if(i < 0 || i > myLength)
            {
                return null;
            }
            
            //此处注意要从后向前依次将i后面的元素向后移位
            for (int j = myLength-1; j >= i; j--){
                //依次把前面的元素向后移位
                myList[j + 1] = myList[j];
            }
            
            myList[i] = element;
            
            myLength++;
            
            return element;
        }
        
        /**
         * 删除指定位置元素
         * @param i
         * @return
         */
        public Object deleteElement(int i){
    
            if (i < 0 || i >= myLength){
                return null;
            }
            
            Object element = myList[i];
            
            //此处注意要从前向后依次将i后面的元素向后移位,不用单独执行删除操作,因为在移位的过程中已经把i坐标的元素给覆盖了
            for (int j = i + 1; j < myLength; j++){
                //依次把后面的元素向前移位
                myList[j - 1] = myList[j];
            }
            
            myLength--;
            return element;
        }
        
        /**
         * 遍历线性表中的元素
         */
        public void listTraverse(){
            for (int i = 0; i <= myLength-1; i++){
                System.out.println(myList[i].toString());
            }
        }
    }
    

      此处附上链表的结构代码:

    package util;
    
    import test.entity.Node;
    
    public class MyChainList {
        
        private Node myChainList;
        
        private int listLength;
        
        /**
         * 初始化链表
         */
        public MyChainList() {
            //申请节点内存
            myChainList = new Node();
            
            myChainList.data = null;
            myChainList.next = null;
            
            listLength = 0;  
        }
    
        /**
         * 销毁链表,废弃
         */
        public void destroyList(){
            clearList();
            myChainList = null;
        }
        
        /**
         * 判断链表是否为空
         * @return
         */
        public boolean isListEmpty(){
            return 0 == listLength ? true :false;
        }
        
        /**
         * 获取链表的长度
         * @return
         */
        public int listLength(){
            return listLength;
        }
        
        /**
         * 清空链表的所有元素
         */
        public void clearList(){
            Node currentNode = myChainList;
            //初始节点的下一个节点,为第一个节点,找到第一个节点判断是否为空
            while(null != currentNode.next){
                Node temp = currentNode.next;
                //将当前节点删除
                currentNode = null;
                //查找下一个节点
                currentNode = temp;
            }
            currentNode.data = null;
            currentNode.next = null;
            listLength = 0;
        }
        
        /**
         * 插入头节点
         * @param node
         * @return
         */
        public Node listInsertHead(Node node){
            //将第一个元素指向的下一个节点,存放备用
            Node temp = myChainList.next;
            
            //从堆内存中申请空间,将数据放入内存
            Node newNode = new Node();
            if(null == newNode){
                return null;
            }
            newNode.data = node.data;
            
            //让新的节点指向,第一个节点原指向的节点
            newNode.next = temp;
            //将node节点放入第一个节点的后面
            myChainList.next = newNode;
            listLength ++;
            return newNode;
        }
        
        /**
         * 插入尾节点
         * @param node
         * @return
         */
        public Node listInsertTail(Node node){
            Node currentNode = myChainList;
            //重第一个节点开始循环查找下一个节点,知道找到尾节点
            while(null != currentNode.next)
            {
                currentNode = currentNode.next;
            }
          
            //从堆内存中申请空间,将数据放入内存
            Node newNode = new Node();
            if(null == newNode){
                return null;
            }
            newNode.data = node.data;
            newNode.next = null;
            
            //将新节点插入尾节点的后面
            currentNode.next = newNode;
            
            listLength ++;
            return newNode;
        }
        
        /**
         * 指定位置插入节点
         * @param i
         * @param node
         * @return
         */
        public Node insertElement(int i, Node node){
            
            //判断i是否合法
            if (i < 0 || i > listLength){
                return null;
            }
            
            //遍历节点找到 i 位置的上一个节点
            Node currentNode = myChainList;
            for (int j = 0; j < i; j++){
                currentNode = currentNode.next;
            }
            
            Node newNode = new Node();
            if (null == newNode){
                return null;
            }
            
            newNode.data = node.data;
            //将原位于i位置的节点放入新节点的后面
            newNode.next = currentNode.next;
            //将新节点,放入i上一个节点的后面
            currentNode.next = newNode;
            
            listLength ++;
            return newNode;
        }
        
        /**
         * 删除指定节点
         * @param i
         * @return
         */
        public Node deleteElement(int i){
            
            if (i < 0 || i >= listLength){
                return null;
            }
            
            //找到第i个节点,和i的上一个节点
            Node currentNode = myChainList;
            Node currentNodeBefore = null;
            for (int j = 0; j <= i; j++){
                currentNodeBefore = currentNode;
                currentNode = currentNode.next;
            }
            
            //将i位置后面的节点,放在i前面节点的后面
            currentNodeBefore.next = currentNode.next;
            Node temp = currentNode;
            
            currentNode = null;
            listLength --;
            return temp;
        }
        
        /**
         * 获取指定位置节点
         * @param i
         * @return
         */
        public Node getElement(int i){
            
            //过滤i的合理范围
            if (i < 0 || i >= listLength){
                return null;
            }
            
            // 找到第i个节点
            Node currentNode = myChainList;
            for (int j = 0; j <= i; j++){
                currentNode = currentNode.next;
            }
            
            return currentNode;
        }
        
        /**
         * 获取指定节点所在的位置
         * @param node
         * @return
         */
        public int elementLocate(Node node){
            
            //循环查找所有节点
            Node currentNode = myChainList;
            int count = 0;
            while(null != currentNode.next){
                currentNode = currentNode.next;
                //找到链表中第一个与指定节点匹配的节点
                if (currentNode.data.equals(node.data)){
                    //返回当前循环的次数
                    return count;
                }
                //每执行一次表示当前位置没有匹配的节点,注意不能放在if前面
                count++;
            }
            
            return -1;
        }
        
        /**
         * 找到指定节点的前驱
         * @param node
         * @return
         */
        public Node priorElement(Node node){
            
            //找到 指定节点 和 指定节点的 上一个节点
            Node currentNode = myChainList;
            Node currentNodeBefore = null;
            while(null != currentNode.next){
                currentNodeBefore = currentNode;
                currentNode = currentNode.next;
                
                //匹配到了第一个与指定节点相同的节点
                if (node.data.equals(currentNode.data)){
                    //如果找到的对象是线性表中的第一个元素,那么他就没有前驱,返回null
                    if (currentNodeBefore.equals(myChainList)){
                        return null;
                    }
                    return currentNodeBefore;
                }
            }
            return null;
        }
        
        /**
         * 找到指定节点的后继
         * @param node
         * @return
         */
        public Node nextElement(Node node){
            //遍历线性表,找到指定节点
            Node currentNode = myChainList;
            while(null != currentNode.next){
                currentNode = currentNode.next;
                //如果找到了元素
                if (currentNode.data.equals(node.data)){
                    //判断该元素是否为线性表中的最后一个元素,最后一个元素没有后缀,直接返回null
                    if (currentNode.next == null){
                        return null;
                    }
                    return currentNode.next;
                }
            }
            return null;
        }
        
        /**
         * 遍历链表
         */
        public void listTraverse(){
            //遍历链表中的所有元素,依次打印出他们的 数据域
            Node currentNode = myChainList;
            while(null != currentNode.next){
                currentNode = currentNode.next;
                currentNode.printNode();
            }
        }
    }
    

      

  • 相关阅读:
    百度面试题
    分治法--二分查找、乘方、斐波那契数
    01-11李宁老师学Python视频课程(1):初识Python返回课程
    邮件发送的两种实现方法。
    Docker(一):Docker入门教程
    安装docker及在docker中安装python环境学
    vim编辑器的使用和CentOS有很多不同
    大一编程基础培训]==02-03-04-05课==类型
    大一编程基础培训]==08课==条件判断]==07课==Python的LIST与TUPLE数据类型
    Beautiful Soup 4.2.0 文档¶ BeautifulSoup对象内任何第一个标签入口,使用find()方法。
  • 原文地址:https://www.cnblogs.com/fuhui-study-footprint/p/9087917.html
Copyright © 2020-2023  润新知