zoukankan      html  css  js  c++  java
  • 数据结构(一)顺序表、链表以及队列

    一、顺序表
    顺序表:它具有连续内存地址。访问方便O(1),但是删除和插入不方便O(N)。常用数组实现。
    在JAVA中,声明一个数组直接使用语句:int[] array = new int[k];k为已知的数组大小。
    当然JAVA中本身自带了很多封装的数组,如Arrays,ArrayList,Stack等。

    import java.util.Arrays;
    
    /**数组的基本操作,包括插入,删除等,以整数数组为例进行操作
     * 
     * @author wenbaoli
     * @version 1.0
     */
    public class Array {
    
        /** 数组插入元素
         * @param arr 数组
         * @param k 插入的位置
         * @param x 插入的元素
         * @return 返回插入元素后的数组
         */
        public static int[] Insert(int[] arr,int k,int x){
            if(k > arr.length || k < 0){
                System.out.println("插入的位置非法!");
                return null;
            }
            int[] temp = new int[arr.length+1];
            for(int i = 0;i< k; i++){
                temp[i] = arr[i];
            }
            temp[k] = x;
            for(int i = k+1 ;i<temp.length;i++){
                temp[i] = arr[i-1];
            }
            arr = temp;//这里即使改变arr,在main函数中也无法得到改变后的数组,因为方法传递的是arr的拷贝,而不是真正意义上的arr
            return temp;
        }
        /**删除数组中指定位置的元素
         * @param arr 数组
         * @param k 指定的位置
         * @return 返回删除元素后的数组
         */
        public static int[] Delete(int[] arr,int k){
            int[] temp = new int[arr.length - 1];
            for(int i = 0; i < k; i++){
                temp[i] = arr[i];
            }
            for(int i = k+1; i < arr.length; i++){
                temp[i - 1] = arr[i];
            }
            return temp;
        }
    
        public static void print(int[] arr){
            for(int n : arr){
                System.out.print(n + "	");
            }
            System.out.println();
        }
        /** 对本类中的方法进行测试
         * 
         * @param arg
         */
        public static void main(String[] arg){
    
            //initial       
            int[] arr = {1,2,3,4,5,6,7,8,9,0};
            print(arr);
            int[] temp;
    
            //insert operation
            temp = Insert(arr,5,11);
            arr = temp;//在main函数中改变arr首地址的话是可以得到改变后的数组的。
            print(arr);//此时的arr就是改变后的数组temp
    
    
            //delete operation
            temp = Delete(arr,5);
            arr = temp;
            print(arr);
    
            //other operation using JAVA package
            Arrays.sort(arr);//利用java包Array,对数组进行排序
            print(arr);
    
        }
    }

    这里给出了简单的数组的插入与删除。

    当然对于数组类Arrays,它本身也有很多方便的方法,如:

    Arrays.sort(arr);
    Arrays.binarySearch(arr,key);
    Arrays.fill(arr,x);

    以及栈类Stack
    栈的特点是:只能在表的一端进行插入与删除操作,先进后出LIFO。它有两个基本操作:出栈和入栈
    使用顺序表stack与栈顶指针top来实现栈

    //这个操作一般是C/c++语言操作
    stack[top++] = item;//入栈
    item = stack[--top];//出栈

    需要注意的是:插入的时候需要判断栈是否已满,而删除的时候要判断栈是否为空。常用来设计如下题型:
    判断字符串的括号匹配

    JAVA中的栈则如下:

    import java.util.Stack;
    
    /**对JAVA中自带栈的测试,分别对其各个函数进行了了解与说明。这里的栈更像是一个数组,可以插入与删除(这不是栈的本来定义)。只能出栈与入栈(在一端)才是栈的特点。
     * 
     * @author wenbaoli
     *
     */
    public class StackTest {
    
        public static void main(String[] args){
            Stack<Integer> stack = new Stack<Integer>();
    
            for(int i = 0; i < 10;i++){
                stack.add(i);
            }
            System.out.println(stack);
            System.out.println(stack.peek());//peek()函数只定位到栈顶的值,并不会出栈
            System.out.println(stack);//此时栈还是原来的
            System.out.println(stack.pop());//pop()函数会出栈。
            System.out.println(stack);//此时栈已经改变(栈顶元素已经出栈了)
    
    
            stack.add(3, 10);//在索引为3的位置插入元素10.
            System.out.println(stack);
    
            stack.remove(3);//去除索引为3的元素
            System.out.println(stack);
    
    
            stack.push(9);//将元素9入栈。
            System.out.println(stack);
    
            stack.addElement(10);//此函数相当于入栈
            System.out.println(stack);
    
            System.out.println(stack.capacity());//当前栈的容量(这个值可能大于已有的元素个数)
    
            System.out.println(stack.contains(11));//判断是否含有指定元素,返回false or true
    
            System.out.println(stack.empty());//判空函数,返回false or true
    
            System.out.println(stack.search(5));//返回元素5所在的索引值
    
            System.out.println(stack.capacity());
            stack.trimToSize();//将栈的容量改为当前元素所占用的量
            System.out.println(stack.capacity());//此时的容量即为元素个数
            System.out.println(stack.size());
        }
    }

    以及ArrayList, Set ,Map 等Collection类。大部分都有类似的方法。但是它们每种都有自己的特点。详情见:http://blog.csdn.net/lilianforever/article/details/46739495

    二、链表
    相对于顺序表的定位快,插入删除慢,链表则不同,它通过指针将不同位置的元素链接起来,因而优缺点与数组正好相反:定位慢(O(n)),插入删除快(O(1))。链表一般用指针动态分配内存来实现。

    在JAVA中有常见的集合类 LinkedList(它的实现采用的是链表机制)。使用之前要先导入包:

    import java.util.LinkedList;

    声明链表如下:

    LinkedList<Integer> llist = new LinkedList<Integer>();

    这里的Integer可以换成其他的对象。如String,Double,以及自定义类。

    LinkedList的方法也不外乎有:插入,删除,判空,size(),判断是否含有某对象等等。这里不在一一叙述。

    除此之外:也可以自定义链表,如:
    首先定义一个链表的结点类

    public class SingleLinkList{
        int data;
        SingleLinkList next;
    }

    其次声明链表其实就是已知一个头结点即可。

    SingleLinkList h;

    当然对于链表还需要一个一个构建,将各个链表结点链接起来。

    同理,还可以定义双向链表

    public class DoubleLinkList{
        int data;
        DoubleLinkList prior;
        DoubleLinkList next;
    }

    三、队列
    队列是这样一种表:只能在一端(队尾)插入,另一端(对头)删除。

    队列的实现:一般用顺序表queue,队首指针front和队尾指针rear来实现队列。它有两个基本操作:入队(enqueue),出队(dequeue)

    queue[++rear] = item;//入队
    queue[++front] = item;//出队

    即不移动元素而是移动指针。这样操作很快,但是表前面的位置是浪费的。
    因此有一种特殊的队列是:循环队列,可以避免这种浪费。首先规定一个队列长度size,入队和出队因此变为:

    //入队
    rear = (rear + 1) % size;
    queue[rear] = item;
    //出队
    front = (front + 1) % size;
    queue[front] = item;

    JAVA中队列的实现:优先队列(说到底也是一种Collection)
    首先引入包

    import java.util.PriorityQueue;

    声明优先队列,以及一些方法。

    PriorityQueue<Integer> pq = new PriorityQueue<Integer>();
    pq.add(3);
    System.out.println(pq);
    pq.peek();
    pq.poll();

    在这种队列中,入队的顺序是无关的,每次都选一个优先级最小的元素出队。

  • 相关阅读:
    《玩转.NET Micro Framework 移植基于STM32F10x处理器》内容介绍
    《玩转.NET Micro Framework 移植基于STM32F10x处理器》前言
    《玩转.NET Micro Framework 移植基于STM32F10x处理器》内容介绍
    《玩转.NET Micro Framework 移植基于STM32F10x处理器》微软中国.NET Micro Framework项目组工程师所作之序
    《玩转.NET Micro Framework 移植基于STM32F10x处理器》资源汇总
    《玩转.NET Micro Framework 移植基于STM32F10x处理器》微软中国.NET Micro Framework项目组工程师所作之序
    《玩转.NET Micro Framework 移植基于STM32F10x处理器》前言
    Windows、Linux、ARM、Android、iOS全平台支持的RTMP推流组件libEasyRTMP库接口调用说明
    简单高效易用Windows/Linux/ARM/Android/iOS平台实现RTMP推送组件EasyRTMPAndroid MediaCodec硬编码流程介绍
    RTSP网络监控摄像头如何实现Windows、Linux、ARM、Android、iOS全平台支持的拉RTSP流推出RTMP直播流?
  • 原文地址:https://www.cnblogs.com/wenbaoli/p/5655741.html
Copyright © 2011-2022 走看看