一、数组
1、数组的定义 (数组的局限性)
数组是java中最基本的一种数据结构,用于存放一系列类型相同的数据,这些类型相同的数据的集合就是数组。
数组可以当成一个容器,用来存放自己想放的东西。
数组的长度在创建时就已经固定了,一旦创建,长度便不能更改。
2、数组的分类
数组可以分为:一维数组、二维数组、多维数组
3、定义数组的格式
常用的有三种格式:
第一种是:数据类型 [ ] 数组名 = new 数据类型[数组长度];
第二种是:数据类型 [ ] 数组名 = {数值,...};
第三种是:数据类型 [ ] 数组名 = new 数据类型[ ]{数值,...};
也可以先声明数组,再实例化数组
数据类型 [ ] 数组名 ;
数组名 = new 数据类型[数组长度];
= {数值,...};
= new 数据类型[ ]{数值,...};
二维数组的定义与一维的基本类似:
第一种是:数据类型 [ ][ ] 数组名 = new 数据类型[数组长度][数组长度] ;
第二种是:数据类型 [ ][ ] 数组名 = {{数值},{数值},{数值},...};
第三种是:数据类型 [ ][ ] 数组名 = new 数据类型[ ][ ]{{数值},{数值},{数值},...};
也可以先声明数组,再实例化数组
数据类型 [ ][ ] 数组名 ;
数组名 = new 数据类型[数组长度][数组长度] ;
= {{数值},{数值},{数值},...};
= new 数据类型[ ][ ]{{数值},{数值},{数值},...};
4、使用数组的基本用法及应注意的问题
数组长度是固定的;
数组时有序的;
数组中每一个元素都有唯一的索引位置,索引值从0开始,最大值为数组长度-1,
如:
int[] array = {3,4,6};
array[0] = 3;
array[1] = 3;
array[2] = 3;
如果运行array[3];则会出现数组越界的错误;
取得数组的长度,可以通过 数组名.length得到 数组array的长度为:array.length
取得数组元素值,一般通过 数组名[索引值] 得到 array[1]
5、数组的排序
一维数组的排序:
冒泡排序:
把数组想象成一个垂直的柱体,其中按最小的元素在顶部,最大的元素在底部排序,就是冒泡排序。
冒泡排序从顶部或底部开始扫描,对相邻的两个元素进行比较,i的取值是0~array.length-2,
如果array[i]>array[i+1],则交换两个数的值,把小的数浮到顶部,大的数沉到底部;
冒泡排序的算法很简单,但是进行了很多重复的比较,造成时间效率比较低,冒泡排序的时间效率
为O(n*n)
具体实现如下:
// 冒泡排序 public static int[] maoPao(int[] x) { for (int i = 0; i < x.length; i++) { for (int j = i + 1; j < x.length; j++) { if (x[i] > x[j]) { int temp = x[i]; x[i] = x[j]; x[j] = temp; } } } return x; }
选择排序
选择排序就是在位置上对数组中的元素进行交换,使它们从原来不合适的位置移到按照一定位置排好的
位置上。即先找出数组中最小的元素,再与第一个元素进行交换,再把剩余的i-1个元素中最小的放到第二个位置
上, 直到排序完成。
// 选择排序 public static int[] xuanZe(int[] x) { for (int i = 0; i < x.length; i++) { int lowerIndex = i; // 找出最小的一个索引 for (int j = i + 1; j < x.length; j++) { if (x[j] < x[lowerIndex]) { lowerIndex = j; } } // 交换 int temp = x[i]; x[i] = x[lowerIndex]; x[lowerIndex] = temp; } return x; }
插入排序
插入排序是先考虑数组中的前两个元素x[0],x[1],如果后一个数x[1]小于前一个数x[0]就交换两个数的位置,然
后再考虑第三个元素x[2],如果x[2]比前两个都小,则把x[2]移到x[0],前两个依次后移;如过x[2]小于x[1]大
于x[0],则只交换x[1]和x[2];如果x[2]比前两个都大则不需要交换。就这样把每个元素都插入到合适的置上
// 插入排序 public static int[] caRu(int[] x) { for (int i = 1; i < x.length; i++) { for (int j = i; j > 0; j--) { if (x[j] < x[j - 1]) { int temp = x[j]; x[j] = x[j - 1]; x[j - 1] = temp; } } } return x; }
希尔排序
希尔排序是先对原始数组的各部分进行排序,待整个数组“基本有序”时,再对整个数组进行排序,这样就提高
了排序的效率。
// 希尔排序 public static int[] shell(int[] x) { // 分组 for (int increment = x.length / 2; increment > 0; increment /= 2) { // 每个组内排序 for (int i = increment; i < x.length; i++) { int temp = x[i]; int j = 0; for (j = i; j >= increment; j -= increment) { if (temp < x[j - increment]) { x[j] = x[j - increment]; } else { break; } } x[j] = temp; } } return x; }
此外还有堆排序、快速排序、归并排序、基数排序等,今天暂不做总结。
二维数组的排序:
冒泡排序:
我以两种方法实现了二维数组的冒泡排序,一种是先对行或列进行排序,再对二维数组排序;另一种是先把
二维数组转化为一维数组进行排序,再把一维数组转换成二维数组。
// 对数组中的元素从小到大排序:采用冒泡排序法 public static int[][] maoPao(int[][] a){ for(int k=0;k<a.length*a[0].length;k++){ for(int i=0;i<a.length;i++){ for(int j=0;j<a[i].length;j++){ //为每一行进行排序 if((j+1)%a[i].length != 0){ if(a[i][j]>a[i][j+1]){ int temp=a[i][j]; a[i][j]=a[i][j+1]; a[i][j+1]=temp; } } else { //为每一列进行排序 if(i+1 != a.length){ if(a[i][j] > a[i+1][(j+1)%a[i].length]){ int temp = a[i][j]; a[i][j] = a[i+1][(j+1)%a[i].length]; a[i+1][(j+1)%a[i].length]=temp; } } } } } } //或者: //把二维数组转换为一维数组再排序 int[] a2 = new int[qty]; for(i=0;i<rows;i++) { for(j=0;j<cols;j++) { a2[i*cols+j] = a1[i][j]; } } for(i=0;i<qty-1;i++) { for(j=i+1;j<qty;j++) { if(a2[i]>a2[j]) { temp = a2[i]; a2[i] = a2[j]; a2[j] = temp; } } } //把排序后的一维数组又转换回二维数组 for(i=0;i<rows;i++) { for(j=0;j<cols;j++) { a1[i][j] = a2[i*cols+j]; } }
二、自定义队列
1、小谈自定义队列
由于之前看过一点点儿数据结构的书,知道有一个队列,与堆栈的“先进后出”不同,队列是“先进先出的”,队
列删元素只能在队头,添加元素只能在队尾,队列可以用数组,也可以用链表。但现在学的这个自定义队列可以有
比较多的功能,可以在任意位置添加或删除一个元素,原来,此“队列”非彼“队列”啊!
2、自定义队列与数组相比的好处(为什么要用自定义队列)
已经创建好的数组不能再添加一个元素;
数组也不可以删除一个元素,将后面的元素向前移一位;
数组也不能将一个数组追加到另一个数组末尾;
但这些功能都可以通过自定义队列列来实现
3、自定义队列的实现
1:向队尾添加数据
2:在队尾删除数据
3:在指定位置添加数据
4:在指定位置删除数据
5:返回指定位置的数据
6:返回队列中数据的个数
7:修改指定位置的元素值
8:将一个队列追加到另一个队列后面
下面是我写的简单实现:
//1、向队尾添加数据 public void add(Student stu){ //新建一个比原数组长度大一的数组 Student[] tempList = new Student[stuList.length + 1]; //把原数组数据一次复制到新数组中 for(int i=0;i<stuList.length;i++){ tempList[i] = stuList[i]; } //把数据放入最后一个位置 tempList[stuList.length] = stu; //交换两个数组 stuList = tempList; } //2、在队尾删除数据 public void remove(){ //新建一个比原数组长度小一的数组 Student[] tempList = new Student[stuList.length - 1]; //把原数组数据一次复制到新数组中 for(int i=0;i<stuList.length - 1;i++){ tempList[i] = stuList[i]; } //交换两个数组 stuList = tempList; } //3、在指定位置添加数据 public void insert(int index, Student stu){ //新建一个比原数组长度大一的数组 Student[] tempList = new Student[stuList.length + 1]; //把原数组数据index之前的数据复制到新数组中 for(int i=0;i<index;i++){ tempList[i] = stuList[i]; } //把新插入的放入index位置 tempList[index-1] = stu; //把剩下的元素向后错一位放入新数组中 for(int i=index;i<stuList.length+1;i++){ tempList[i]=stuList[i-1]; } //交换两个数组 stuList = tempList; } //4、在指定位置删除数据 public Student delete(int index){ //新建一个比原数组长度小一的数组 Student[] tempList = new Student[stuList.length - 1]; //把原数组数据index之前的数据复制到新数组中 for(int i=0;i<index;i++){ tempList[i] = stuList[i]; } //把剩下的元素向后前一位放入新数组中 for(int i=index;i<stuList.length-1;i++){ tempList[i]=stuList[i+1]; } //交换两个数组 stuList = tempList; return null; } //5、返回指定位置的数据 public Student get(int index){ return stuList[index]; } //6、返回队列中数据的个数 public int size(){ return stuList.length; } //7、修改指定位置的元素值 public void update(int index,Student stu){ //新建一个与原数组长度相同的数组 Student[] tempList = new Student[stuList.length]; //把原数组数据index之前的数据复制到新数组中 for(int i=0;i<index;i++){ tempList[i] = stuList[i]; } //把修改后的的放入index位置 tempList[index] = stu; //把剩下的元素放入新数组中 for(int i=index+1;i<stuList.length;i++){ tempList[i]=stuList[i]; } //交换两个数组 stuList = tempList; } //8、将一个队列追加到另一个队列后面 public void addList(ZDList zdlist){ //新建一个数组,长度为原数组长度加上追加的数组长度 Student[] tempList = new Student[stuList.length +zdlist.size() ]; //把原数组数据一次复制到新数组中 for(int i=0;i<stuList.length;i++){ tempList[i] = stuList[i]; } //把数组追加 for(int i=stuList.length;i<tempList.length;i++){ tempList[i]=zdlist.get(i-stuList.length); } //tempList[stuList.length] = stu; //交换两个数组 stuList = tempList; }
4、使用泛型定义一个通用的自定义队列
泛型,就是在创建队列时,指定队列中所放对象的类型。在定义泛型时,我们用到了E 和Object:
其中泛型E 表示可以匹配所有的类型(基本数据类型除外)
Object 是java所有类的父类
泛型与队列区别不大,以上面的在队尾添加数据为例来说明泛型:
//向队尾添加数据 public void add(E stu){ //新建一个比原数组长度大一的数组 Object[] tempList = new Object[stuList.length + 1]; //把原数组数据一次复制到新数组中 for(int i=0;i<stuList.length;i++){ tempList[i] = stuList[i]; } //把数据放入最后一个位置 tempList[stuList.length] = stu; //交换两个数组 stuList = tempList; }
5.队列的优化
队列的优化就是将泛型定义成一个类,方便以后的使用
分享到:
相关推荐
- 构造函数:初始化空的优先队列,可能包括默认容量的构造函数和自定义容量的构造函数。 - 插入方法:如`add(int val)`,将元素插入到队列的末尾并调整堆。 - 删除方法:如`remove()`,删除并返回队首元素,然后...
但如果你想自定义队列,你可以创建一个类,包含一个数组作为底层数据结构,并实现添加元素(Enqueue)、移除元素(Dequeue)以及检查队首元素(Peek)等方法。以下是一个简单的自定义队列的C#实现: ```csharp ...
总的来说,这个自定义的`WMArrayDeque`类模板提供了一种基于数组实现双端队列的方式,允许在两端进行高效的插入和删除操作。虽然其接口可能没有标准库中的`deque`那么丰富,但对于特定场景,这样的自定义实现可能更...
数组实现的双端队列需要规定一个头元素的位置(head)和尾元素的下一个位置(tail)。head 用来表示头元素的位置,tail 用来表示尾元素的下一个位置。在数组实现中,需要使用逻辑与操作来确定元素的操作位置。 在...
本文主要探讨了如何利用数组的特性,特别是`push`、`shift`方法实现队列的先进先出(FIFO)原则,以及`forEach`方法在数组操作中的应用和注意事项。 ### 数组与队列 在JavaScript中,数组天生支持队列的操作。`...
"IndexedQueue"可能是自定义队列类的名称,而"LogOn.aspx"链接可能指向一个在线平台,提供完整的代码下载和详细的步骤说明,帮助开发者理解和实现这个索引队列。 总结来说,这个话题涉及到了C#编程中的自定义数据...
链表实现的循环队列在处理满队列和空队列时与数组实现有所不同,因为链表的节点可以动态增加和删除,所以无需像数组那样进行特殊的重置操作。 在C++中,模板(template)是泛型编程的重要工具,它可以让我们创建...
数据结构(数组型队列),内含源代码和教程MyDeque_Demo。支持自定义数据类型,支持访问队列中的任意元素。 使用教程参见 http://blog.csdn.net/michaelliang12/article/details/51325801
本实例重点讲解了泛型顺序队列和泛型循环队列,这两种队列都是C#中实现队列数据结构的有效方式。 首先,泛型在编程中是指能够处理多种数据类型的类、接口或方法。在C#中,我们可以通过使用`<T>`来声明一个泛型类型...
总结来说,这个Java代码实例展示了如何使用数组和自定义比较逻辑来实现优先级队列。虽然这种方法在性能上可能不如Java内置的`PriorityQueue`类高效,但对于学习理解优先级队列的工作原理和数据结构的实现是一个很好...
在Java编程中,大作业通常涉及实际应用中的问题解决,这次的任务是利用数组实现一个队列排序,并且能够动态地插入新的元素。这个任务主要涵盖了两个核心知识点:数组的使用和排序算法。下面将详细解释这两个方面。 ...
在Java中,LinkedList类就是链表的实现,适用于实现队列和栈等数据结构。 5. **二叉树(Binary Tree)**:二叉树是每个节点最多有两个子节点的数据结构,分为左子节点和右子节点。常见的二叉树类型有二叉搜索树、...
本文将探讨如何在VB中利用数组(尤其是动态数组)和自定义数据类型(Type Statement)来实现常见的数据结构,如链表、栈、队列和二叉树,并讨论它们的应用。 #### VB中的堆栈与队列实现 ##### 1. 基础概念 - **...
9. **代码实例**:在提供的`array.sv`文件中,可能包含了各种数组操作的示例代码,如数组的声明、初始化、遍历、并行操作、队列的使用等,通过阅读和分析这些实例,可以更直观地理解SV中的数组操作。 通过深入学习...
在Java编程中,泛型是一种强大的工具,它允许我们在编写代码时指定容器(如堆栈、队列等)可以容纳的数据类型,从而提高了代码的可读性和安全性。在这个例子中,我们将探讨如何使用泛型实现一个堆栈类——`...
"实例185 - 自定义泛型化数组类"是一个关于如何创建和使用自定义泛型数组类的示例,这个主题将深入探讨泛型、数组以及两者的结合。 首先,我们需要理解泛型的基本概念。泛型是Java 5引入的一个重要特性,它允许我们...
自定义队列通常涉及以下关键组件和操作: 1. **初始化**:创建队列时,需要设置一个初始容量或默认为空。 2. **入队**:在队列末尾添加元素。这可以通过动态数组或链表来实现,确保在达到容量限制时能自动扩展。 3....
自定义队列的实现方式有: 1. 双端队列(Deque):可以同时在两端进行入队和出队操作,例如C++中的`std::deque`。 2. 链表:使用链表,入队在尾部插入节点,出队则删除头部节点。 3. 循环数组:当数组满时,通过循环...
在这个自定义队列中,我们使用了环形数组来模拟队列的行为。`front`和`rear`分别表示队首和队尾的位置。当队列满时,我们抛出异常;当队列空时,我们也抛出异常。 ### 性能分析 队列操作的时间复杂度通常为O(1),...
易语言源码易语言自定义数据类型的内存存储方式.rar 易语言源码易语言自定义数据类型的内存存储方式.rar 易语言源码易语言自定义数据类型的内存存储方式.rar 易语言源码易语言自定义数据类型的内存存储方式.rar ...