您的位置:首页 > 编程语言 > Java开发

JAVA4——数组的实现及数组的三种排序方法实现

2018-02-02 22:59 501 查看

1、数组实现

public class String_num {
public static void main(String[] args) {
// 声明一个数组
int[] a;
int[] b=new int[5];
b[0]=2;
System.out.println(b[0]);
}
}


public class HelloWorld {
public static void main(String[] args) {
//声明一个引用
int[] a;
//创建一个长度是5的数组,并且使用引用a指向该数组
a = new int[5];

int[] b = new int[5]; //声明的同时,指向一个数组

}
}


总感觉,与C语言的数组表达不一样。

这是C语言的数组定义:

#include <stdio.h>
int main(void){
int i,a[10];
for(i=0;i<=9;i++)
a[i]=i;
for(i=9;i>=0;i--)
printf("%d ",a[i]);
return 0;
}


可以看出,JAVA就是和类打交道,而且,不用库的调用也不一样,一个使用 include,一个使用 import

2、理论介绍

int[] a; 声明了一个数组变量。
[]表示该变量是一个数组
int 表示数组里的每一个元素都是一个整数
a 是变量名
但是,仅仅是这一句声明,不会创建数组

有时候也会写成int a[]; 没有任何区别,就是你看哪种顺眼的问题


创建数组的时候,要指明数组的长度。
new int[5]
引用概念:
如果变量代表一个数组,比如a,我们把a叫做引用
与基本类型不同
int c = 5; 这叫给c赋值为5
声明一个引用 int[] a;
a = new int[5];
让a这个引用,指向数组


3、应用–寻找数组的最小值

public class FindMinmun{
public static void main(String[] args){
int[] a=new int[5];
for(int i=0;i<5;i++){
a[i]=(int)(Math.random()*100);
}
int min=a[0];
for(int i=0;i<5;i++){
if(min>a[i]){
min=a[i];
}
}
System.out.println("The min num is:"+min);
}
}


但看到有人使用下表来遍历,也是另外一种思路

//数组最小值
public class Min {
public static void main(String[] args){
int [] a= new int[5];
int x=0;
a[0] = (int) (Math.random() * 100);
for(int i=1;i<a.length;i++){
a[i] = (int) (Math.random() * 100);
x=a[i]<a[i-1]?i:x;   //对比前一位的大小,若比前一位小,则保存当前下标
}
System.out.println("最小值为:"+a[x]);
}
}


5、初始化数组

public class HelloWorld {
public static void main(String[] args) {
//写法一: 分配空间同时赋值
int[] a = new int[]{100,102,444,836,3236};

//写法二: 省略了new int[],效果一样
int[] b = {100,102,444,836,3236};

}
}


6、数组前后反转

public class ReverseNum{
public static void main(String[] args){
int[] a=new int[5];
for(int i=0;i<a.length;i++){
a[i]=(int)(Math.random()*100);
}
int[] b=new int[a.length];
for(int i=0;i<a.length;i++){
b[i]=a[a.length-1-i];
}

for(int i=0;i<a.length;i++){
System.out.println(a[i]);
}
System.out.println("----------");
for(int i=0;i<b.length;i++){
System.out.println(b[i]);
}
}
}


7、数组排序

方法一:选择法排序

思想:每次迭代,都是将首个位置和剩下的数比较,最小的放在首个位置;直到迭代结束。

class SelectionSort{
public static void main(String[] args){
int[] a=new int[]{18,62,68,82,65,9};
for(int i=0;i<a.length;i++){
System.out.println(a[i]);
}

System.out.println("----------选择法排序");
int index=0;
for(index=0;index<a.length-1;index++){
for(int j=index+1;j<a.length;j++){
if(a[index]>a[j]){
int temp=a[index];
a[index]=a[j];
a[j]=temp;
}
}
}

for(int i=0;i<a.length;i++){
System.out.println(a[i]);
}

}
}


使用了两个for循环,不是很好的实现方式。

方法二:冒泡法排序

思想:每次迭代,将相邻的两个数比较,把较大的放在后面,直到迭代结束。

class BubbleSort{
public static void main(String[] args){
int[] a=new int[]{18,62,68,82,65,9};
for(int i=0;i<a.length;i++){
System.out.println(a[i]);
}

System.out.println("----------冒泡法排序");
int index=0;
for(int iter=0;iter<a.length-1;iter++){
for(index=0;index<a.length-iter-1;index++){
if(a[index]>a[index+1]){
int temp=a[index];
a[index]=a[index+1];
a[index+1]=temp;
}
}
}

for(int i=0;i<a.length;i++){
System.out.println(a[i]);
}

}
}


方法三:快速排序

/*参考:http://developer.51cto.com/art/201403/430986.htm*/
class QuickSort{
public static void main(String[] args){
int[] a=new int[]{18,62,68,82,65,9,70,35,61,8,68};
for(int i=0;i<a.length;i++){
System.out.println(a[i]);
}

System.out.println("----------快速排序");

int benchmark=a[0];
quickSort(a,0,a.length);

for(int i=0;i<a.length;i++){
System.out.println(a[i]);
}
}

private static void quickSort(int[] a,int lowid,int highid){
int i=lowid;
int j=highid-1;

if (i>=j){
;
}
else{
int benchmark=a[lowid];
while(i<j){

for(j=j;j>i;j--){
if(a[j]<benchmark){
//return j;
break;
}
}
for(i=i;j>i;i++){
if(a[i]>benchmark){
//return i;
break;
}
}

int temp=a[j];
a[j]=a[i];
a[i]=temp;

/* lowid=i;
highid=j;*/
}
int temp=a[i];
a[i]=a[lowid];
a[lowid]=temp;
quickSort(a,lowid,i);
quickSort(a,i+1,highid);
}

/* quickSort(a,i+1,highid);*/

}

}


这种实现有点冗肿。看到别人是,把判断是否继续递推部分,放在了main()里边,看起来很清爽。

别人的代码:

class QuickSort2{
public static void main(String[] args){

int[] a=new int[]{18,62,68,82,65,9,70,35,61,8,68};
quickSort2(a);

for(int i=0;i<a.length;i++){
System.out.println(a[i]);
}
}
public static void quickSort2(int[] a){
qsort(a, 0, a.length-1);
}
private static void qsort(int[] a, int low, int high){
if (low < high){
int pivot=partition(a, low, high);        //将数组分为两部分
qsort(a, low, pivot-1);                   //递归排序左子数组
qsort(a, pivot+1, high);                  //递归排序右子数组
}
}
private static int partition(int[] a, int low, int high){
int pivot = a[low];     //枢轴记录
while (low<high){
while (low<high && a[high]>=pivot) --high;
a[low]=a[high];             //交换比枢轴小的记录到左端
while (low<high && a[low]<=pivot) ++low;
a[high] = a[low];           //交换比枢轴小的记录到右端
}
//扫描完成,枢轴到位
a[low] = pivot;
//返回的是枢轴的位置
return low;
}
}


算法优化

上面这个快速排序算法可以说是最基本的快速排序,因为它并没有考虑任何输入数据。但是,我们很容易发现这个算法的缺陷:这就是在我们输入数据基本有序甚至完全有序的时候,这算法退化为冒泡排序,不再是O(n㏒n),而是O(n^2)了。

究其根源,在于我们的代码实现中,每次只从数组第一个开始取。如果我们采用“三者取中”,即arr[low],arr[high],arr[(low+high)/2]三者的中值作为枢轴记录,则可以大大提高快速排序在最坏情况下的性能。但是,我们仍然无法将它在数组有序情形下的性能提高到O(n)。还有一些方法可以不同程度地提高快速排序在最坏情况下的时间性能。

此外,快速排序需要一个递归栈,通常情况下这个栈不会很深,为log(n)级别。但是,如果每次划分的两个数组长度严重失衡,则为最坏情况,栈的深度将增加到O(n)。此时,由栈空间带来的空间复杂度不可忽略。如果加上额外变量的开销,这里甚至可能达到恐怖的O(n^2)空间复杂度。所以,快速排序的最差空间复杂度不是一个定值,甚至可能不在一个级别。

为了解决这个问题,我们可以在每次划分后比较两端的长度,并先对短的序列进行排序(目的是先结束这些栈以释放空间),可以将最大深度降回到O(㏒n)级别。

值得一提的是,快速排序也有非递归的实现方法,参考链接4,主要是使用栈来实现。

参考:

1.数组教程

2.快速排序法详解及C实现

3.JAVA实现快速排序

4.快速排序的非递归实现C++实现
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: