zoukankan      html  css  js  c++  java
  • [2018/11/14] Java学习

    在网上下载了一个用Java实现的数据结构的视频, 看了前三个视频, 感觉收获很大, 今天花了接近三小时在Java的数据结构上.

    课程的目录如下:

    第01讲:数组
    第02讲:简单排序
    第03讲:栈和队列
    第04讲:链表
    第05讲:双端链表和双向链表
    第06讲:递归的应用
    第07讲:递归的高级应用
    第08讲:希尔排序
    第09讲:快速排序
    第10讲:二叉树的基本概念
    第11讲:二叉树的基本操作
    第12讲:遍历二叉树
    第13讲:删除二叉树节点
    第14讲:红黑树
    第15讲:哈希表
    第16讲:开放地址法
    第17讲:链地址法
    第18讲:图的基本概念
    第19讲:图的搜索
    第20讲:图的最小生成树

    今天和昨天我看完了前三章的内容, 代码都亲手敲了一遍:

    例子配套使用了测试类, 而不是将代码写在一个类里面, 这种写法非常的新颖(我以前的写法太过老土).

    细节都是用private保证了类的安全性.

    对于变量的使用, 太厉害了.

    package ch_01;
    
    public class MyArray {
        private long[] arr;
        private int elements;
        
        /**
         * 初始化数组
         */
        public MyArray() {
            arr = new long[50];
        }
        
        /**
         * 重构初始化函数, 自定义函数的长度
         * @param maxsize
         */
        public MyArray(int maxsize) {
            arr = new long[maxsize];
        }
        
        /**
         * 插入数组的元素
         */
        public void insert(long value) {
            /*由于数组的最末一项的编号是elements-1, 所以可以直接通过elements来表示新加入的元素*/
            arr[elements] = value;
            elements++;  // 注意elements要后移一位, 方便下一次添加元素.
        }
        
        /**
         * 显示数组的元素
         */
        public void display() {
            System.out.print("[");
            for (int i = 0; i < elements; i++) {
                System.out.print(arr[i] + " ");
            }
            System.out.println("]");
        }
        
        /**
         * 按照数组值搜索
         */
        public int search(long value) {
            int i;
            for (i = 0; i < elements; i++) {
                if (value == arr[i]) {
                    break;
                }
            }
            
            if(i == elements) {
                // 如果遍历到最后一个序列, 注意最后一个元素的序列因该是elements-1
                return -1;
            } else {
                return 1;
            }
        }
        
        /**
         * 按序列获取元素值
         */
        public long get(int index) {
            if (index >= elements || index < 0) {
                throw new ArrayIndexOutOfBoundsException();
            } else {
                return arr[index];
            }
        }
        
        /**
         * 删除数据
         */
        public void delete(int index) {
            if(index >= elements || index < 0) {
                throw new ArrayIndexOutOfBoundsException();
            } else {
                for(int i = index; i < elements; i++) {
                    arr[i] = arr[i + 1];  //写错了, 之前写成了arr[index] = arr[index + 1]
                    //抹掉index序列的元素的值, 后面的元素整体向前移动
                }
                elements--;  // 处理后, 要将元素的数量减一
            }
        }
    }

    测试类:

    package ch_01;
    
    public class TestArray {
        
        /**
         * 测试类
         * @param args
         */
        
        public static void main(String[] args) {
    
            MyArray arr = new MyArray();
            arr.insert(10);
            arr.insert(20);
            arr.insert(90);
            arr.display();
            System.out.println(arr.search(20));
            System.out.println(arr.get(2));
            arr.delete(0);
            arr.display();
        }
    
    }

    第二讲: 简单的排序

    冒泡排序

    插入排序

    选择排序

    冒泡排序:

      使用双重for循环,: 最外一层是从数组的开始向后循环, 内循环是从最后向前循环, 只要序号在前的元素大于序号靠后的元素, 就交换两个元素的值. 一直到数组的最前方, 将最小的元素放到元素的首部, 依次循环, 将第二小的元素放在第二位....

    上代码:

    package ch_02;
    
    public class BubbleSort {
     public static void sort(long[] arr) {
         long temp = 0;
         for(int i = 0; i < arr.length-1; i++) {
             // 外层的循环从前向后
             for (int j = arr.length - 1; j > i; j--) {
                 // 内层的循环从后向前, 判断序号靠前的元素是否小于序号靠后的元素
                 // 如果不是, 交换位置
                 if (arr[j - 1] > arr[j]) {
                     //进行交换
                     temp = arr[j];
                     arr[j] = arr[j-1];
                     arr[j-1] = temp;
                 }
             }
         }
     }
    }

    插入排序:

      和冒泡排序类似, 使用双层循环, 外层的for循环是从1开始的, 内层的循环是while循环, 外层的循环从前向后, 内层的循环从后向前. 从第2个元素开始(数组序号是1), 和前面的所有的元素进行比较直到遇到比自己小的元素或者序列为0, 该元素之前到比他小的元素之间的所有的元素整体向后移动, 然后将元素插入到较小的元素的后面. 如此循环......

    代码:

    package ch_02;
    
    public class Insertsort {
        public static void sort(long[] arr) {
            long tmp = 0;
            
            for (int i = 1; i < arr.length; i++) {
                // 从一开始设置插入点tmp.
                tmp = arr[i];
                int j = i;
                while(j > 0 && arr[j] >= tmp) {  // 少了=号就不能实现功能了.
                    // 从后向前移动, 直到数组的最前方或者是遇到一个比后面的数都小的数.
                    arr[j] = arr[j - 1];
                    j--;
                }
                arr[j] = tmp;
            }
        }
    }

    选择排序:

    和冒泡排序很像, 都是使用双层的for循环, 外层的循环用来控制数组的下标, 内层的for循环使用了两个变量, 一个j用来遍历后面所有的元素, 选择出值最小的一个元素, 通过另一个变量k记录该元素的下标, 通过该变量, 和外层的循环配合使用, 将k指向的最小的元素从0排列到最后.

    package ch_02;
    
    public class SelectionSort {
        public static void sort(long[] arr) {
            int k = 0;
            long temp = 0;
            for (int i = 0; i < arr.length - 1; i++) {
                // 这一步和冒泡排序是相同的, 都是从最前开始排序
                k = i;
                for (int j = i; j < arr.length; j++) {
                    if (arr[j] < arr[k]) {
                        // 确保k是最小的元素的下标
                        k = j;
                    }
                }
                temp = arr[i];
                arr[i] = arr[k];
                arr[k] = temp;
            }
        }
    }

    第三部分: 栈和队列

    栈先进后出, 从首部添加数组元素.

    队列先进先出, 栈包括单向队列和循环队列, 从尾部添加数组元素.

     

    栈只用一个变量top来指向数组的最上的元素.就可以实现栈的所有功能.

    package ch_03;
    
    public class MyStack {
        private long[] arr;
        private int top;
        
        /**
         * 默认构造方法
         */
        public MyStack() {
            arr = new long[10];
            top = -1;
        }
        
        /**
         * 带参数的构造方法
         */
        public MyStack(int maxsize) {
            arr = new long[maxsize];
            top = -1;
        }
        
        /**
         * 添加数据
         */
        public void push(int value) {
            arr[++top] = value;
        }
        
        /**
         * 移除数据
         */
        public long pop() {
            return arr[top--];
        }
        
        /**
         * 查看数据
         */
        public long peek() {
            return arr[top];
        }
        
        /**
         * 判断是否为空
         */
        public boolean isEmpty() {
            return top == -1;
        }
        
        /**
         * 判断栈是否满了
         */
        public boolean isFull() {
            return top == arr.length - 1;
        }
    }

    队列需要三个变量分别指代: 队列中元素的数量, 队列的首部, 队列的尾部.

    package ch_03;
    /**
     * 单项队列
     * @author narcisohuang
     *
     */
    public class MyQueue {
        public long[] arr;
        /**
         * elements 有效数据的大小
         * front 队列头部
         * end 队列尾部
         */
        private int elements;
        private int front;
        private int end;
        
        /**
         * 默认构造方法
         */
        public MyQueue() {
            arr = new long[10];
            elements = 0;
            front = 0;
            end = -1;
        }
        
        /**
         * 带参数的构造方法, 参数为数组的大小
         */
        public MyQueue(int maxsize) {
            arr = new long[maxsize];
            elements = 0;
            front = 0;
            end = -1;
        }
        
        /**
         * 添加数据
         */
        public void insert(long value) {
            arr[++end] = value;  //不是循环的队列, 在初始化并删除数据后, 不能再直接元素, 因为end溢出了.
            elements++;
        }
        
        /**
         * 删除数据, 从数组的头部删除
         */
        public long remove() {
            elements--;
            return arr[front++];
        }
        
        /**
         * 查看数据, 从队列的头部开始查看
         */
        public long peek() {
            return arr[front];
        }
        
        /**
         * 判断队列是否空
         */
        public boolean isEmpty() {
            return elements == 0;
        }
        
        /**
         * 判断队列是否满
         */
        public boolean isFull() {
            return elements == arr.length;
        }
    }

    单向队列在赋值之后, 再删除队列内的元素, 再赋值, 是不可以的, 因为, 描述队列头部的变量一直在向前增加, 第二次赋值的时候, 变量溢出了.

    循环队列为了解决不和对此赋值的问题, 将描述队列的头部的变量在其元素清空后初始化为零.

    上代码:

    package ch_03;
    /**
     * 单项队列
     * @author narcisohuang
     *
     */
    public class MyCycleQueue {
        public long[] arr;
        /**
         * elements 有效数据的大小
         * front 队列头部
         * end 队列尾部
         */
        private int elements;
        private int front;
        private int end;
        
        /**
         * 默认构造方法
         */
        public MyCycleQueue() {
            arr = new long[10];
            elements = 0;
            front = 0;
            end = -1;
        }
        
        /**
         * 带参数的构造方法, 参数为数组的大小
         */
        public MyCycleQueue(int maxsize) {
            arr = new long[maxsize];
            elements = 0;
            front = 0;
            end = -1;
        }
        
        /**
         * 添加数据
         */
        public void insert(long value) {
            if (end == arr.length-1) {
                end = -1;
            }
            arr[++end] = value;  
            elements++;
        }
        
        /**
         * 删除数据, 从数组的头部删除
         */
        public long remove() {
            long value = arr[front++];
            if (front == arr.length) {
                front = 0;
            }
            elements--;
            return value;
        }
        
        /**
         * 查看数据, 从队列的头部开始查看
         */
        public long peek() {
            return arr[front];
        }
        
        /**
         * 判断队列是否空
         */
        public boolean isEmpty() {
            return elements == 0;
        }
        
        /**
         * 判断队列是否满
         */
        public boolean isFull() {
            return elements == arr.length;
        }
    }
  • 相关阅读:
    LeetCode 227. Basic Calculator II
    LeetCode 224. Basic Calculator
    LeetCode 103. Binary Tree Zigzag Level Order Traversal
    LeetCode 102. Binary Tree Level Order Traversal
    LeetCode 106. Construct Binary Tree from Inorder and Postorder Traversal
    LeetCode 105. Construct Binary Tree from Preorder and Inorder Traversal
    LeetCode 169. Majority Element
    LeetCode 145. Binary Tree Postorder Traversal
    LeetCode 94. Binary Tree Inorder Traversal
    LeetCode 144. Binary Tree Preorder Traversal
  • 原文地址:https://www.cnblogs.com/huangZ-H/p/9961043.html
Copyright © 2011-2022 走看看