JAVA最基本的排序算法总结

不管是学习哪一门编程语言,算法都是必须要掌握的知识点。算法有很多种,这里我只对排序算法做一个简单的总结。

排序大体上分为两种,一种是只使用内存的内部排序(内排序),另外一种是内,外存结合使用的外部排序(外排序)。

这里只介绍内排序。而内排序又分为,插入排序,选择排序,交换排序,归并排序,基数排序。

(一):插入排序

(1)直接插入排序

基本思想:将要排序的数组,分成两部分,一部分是已经排好序的,另外一部分是未排序的。循环取出未排序区域中的数据,按照大小顺序,在已排好序的数据区域中找到存放下标。直到所有未排序中的数据取完为止。

JAVA实现:

  public void sort(List datas) {

      int length = datas.size();

      if(length<1)return;

      for(intindex=1;index<length;index++) {

         int startIndex = index-1;

         Ttemp= (T)datas.get(index);

         while(startIndex>=0 &&datas.get(startIndex).toString().compareTo(temp.toString())>0) {

            datas.set(startIndex+1,datas.get(startIndex));

            startIndex--;

         }

         datas.set(startIndex+1,temp);

      }

   }


(2)二分直接插入排序

基本思想:在直接插入排序的基础上,对已排序区域进行二分查找,提高查找速率。

JAVA实现:

public voidbinSort(List datas){

      int length = datas.size();

      if(length<1)return;

     

      for(intindex = 1;index<length;index++) {

         int startIndex = index-1;

         Ttemp= (T)datas.get(index);

         int binStartIndex = 0;

         //对已经排序的区域进行二分查找

         while(binStartIndex<=startIndex) {

            intbinMidIndex = (startIndex+binStartIndex)/2;

            if(datas.get(binMidIndex).toString().compareTo(temp.toString())<0) {

                binStartIndex =binMidIndex+1;

            }else {

                startIndex = binMidIndex-1;

            }

         }

        

         for(intbinIndex=index-1;binIndex>=startIndex+1;binIndex--) {

            datas.set(binIndex+1,datas.get(binIndex));

         }

         datas.set(startIndex+1,temp)

      }

   }


(3)希尔排序

基本思想:

希尔排序是针对直接插入排序做的改良。对于直接插入排序算法,待排序数组长度越小有序区域越多,排序速率越高。所以希尔排序,将待排序数组,按照一定的间隔gap,将数组分成多组。每组内的数据排序采用直接插入排序算法。排序完成后,减小gap的值,再对每个分组进行直接插入排序,直到gap的值为1.

 

JAVA实现:

public voidsort(List datas){

      int length = datas.size();

      if(length<1)return;

      int gap = length/2;

      while(gap>0) {

         for(intindex =gap;index<length;index++) {

            intstartIndex =index-gap;

            Ttemp= (T)datas.get(index);

            while(startIndex>=0 &&datas.get(startIndex).toString().compareTo(temp.toString())>0) {

                datas.set(startIndex+gap,datas.get(startIndex));

                startIndex = startIndex-gap;

            }

            datas.set(startIndex+gap,temp);

         }

         gap=gap/2;

      }

   }


(二):选择排序

(1)简单选择排序

基本思想:对给定的排序数组(n),进行n次挑选数据的过程,每次都挑出最小的数据并与当前挑选次数下标值交换。

JAVA实现:

public voidsort(List datas){

      int length = datas.size();

      for(intcount=0;count<length;count++) {

         Ttemp= (T)datas.get(count);

         TswitchValue= temp;

         int position = count;

         for(intindex=count+1;index<length;index++) {

            if(datas.get(index).toString().compareTo(switchValue.toString())<0) {

                position = index;

                switchValue = (T)datas.get(index);

            }

         }

         datas.set(count,datas.get(position));

         datas.set(position,temp);  

      }

   }


(2)堆排序

基本思想:堆的定义如下:具有n个元素的序列(h1,h2,...,hn),当且仅当满足(hi>=h2i,hi>=2i+1)或

(hi<=h2i,hi<=2i+1)(i=1,2,...,n/2)时称之为堆。在这里只讨论满足前者条件的堆。由堆的

定义可以看出,堆顶元素(即第一个元素)必为最大项(大顶堆)。完全二叉树可以很直观

地表示堆的结构。堆顶为根,其它为左子树、右子树。初始时把要排序的数的序列看作是一

棵顺序存储的二叉树,调整它们的存储序,使之成为一个堆,这时堆的根节点的数最大。然

后将根节点与堆的最后一个节点交换。然后对前面(n-1)个数重新调整使之成为堆。依此类

推,直到只有两个节点的堆,并对它们作交换,最后得到有 n个节点的有序序列。从算法

描述来看,堆排序需要两个过程,一是建立堆,二是堆顶与堆的最后一个元素交换位置。所

以堆排序有两个函数组成。一是建堆的渗透函数,二是反复调用渗透函数实现排序的函数。

 

JAVA实现:

public voidsort(List datas){

      int length = datas.size();

      if(length<1)return;

     

      for(intcount=0;count<length-1;count++) {

         buildMaxHeap(datas, length-1-count);

         swap(datas,0,length-1-count);

      }

   }

  

   private void swap(List datas,intindex1,intindex2) {

      Ttemp= (T)datas.get(index1);

      datas.set(index1,datas.get(index2));

      datas.set(index2,temp);

   }

  

   private void buildMaxHeap(Listdatas,intlastIndex) {

      for(intparentNode=(lastIndex-1)/2;parentNode>=0;parentNode--) {

         int currentNode = parentNode;

        

         while(2*currentNode+1<=lastIndex) {

            intleftChildNode = 2*currentNode+1;

            if(leftChildNode<lastIndex) {

                //存在右节点

            if(datas.get(leftChildNode).toString().compareTo(datas.get(leftChildNode+1).toString())<0){

                   leftChildNode++;

                }

            }

           

         if(datas.get(currentNode).toString().compareTo(datas.get(leftChildNode).toString())<0){

                swap(datas,currentNode,leftChildNode);

                currentNode = leftChildNode;

            }else {

                break;

            }

           

         }

      }

   }

(三):交换排序

(1)冒泡排序

基本思想:通过无序区中相邻记录关键字间的比较和位置的交换,使关键字最小的记录如气泡一般逐渐往上‘漂浮’直至‘水面’。整个算法是从最下面的记录开始,对每两个相邻的关键字进行比较,使关键字小的交换到较大记录之上,经过一趟冒泡排序后,关键字最小的记录到达最上端。

JAVA实现:

private void sort(List datas) {

int length = datas.size();

if(length<=1) {

return;

}

for(int count=0;count<length-1;count++) {

for(int index=length-1;index>count;index--) {

if(datas.get(index).toString().compareTo(datas.get(index-1).toString())<0) {

T temp = (T)datas.get(index);

datas.set(index,datas.get(index-1));

datas.set(index-1,temp);

}
}

}

}

 

(2)改进版冒泡排序

基本思想:在常规冒泡排序算法基础上,加一个判断标志用来判断是否该次冒泡排序是否有交换的记录,如果没有,说明已经排好序,直接跳出。

JAVA实现:

private void sort2(List datas) {

int length = datas.size();

if(length<=1) {

return ;

}

for(int count=0;count<length-1;count++) {

boolean change = true;

for(int index=length-1;index>count;index--) {

if(datas.get(index).toString().compareTo(datas.get(index-1).toString())<0) {

T temp = (T)datas.get(index);

datas.set(index,datas.get(index-1));

datas.set(index-1,temp);

change = false;

}

}

if(change)

break;

}

}

(3)快速排序

基本思想:选择一个基准值,扫描待排序区域,把基准值小的值,放在基准值的左边,将大于基准值的值,放在基准值的右边。然后递归分别排序左右两个数据区。
JAVA实现:

private void run(List datas,int start,int end) {

if(start<end) {

int left = start,right = end;

T temp = (T)datas.get(left);

while(left!=right) {

while(right>left &&datas.get(right).toString().compareTo(temp.toString())>0)

right--;

datas.set(left,datas.get(right));

while(left<right && datas.get(left).toString().compareTo(temp.toString())<0)

left++;

 

datas.set(right, datas.get(left));

 

}

datas.set(left, temp);

run(datas,start,left-1);

run(datas,left+1,end);

}

}

 

private void sort(List datas) {

int length = datas.size();

if(length<=1)

return;

int start = 0,end = length-1;

run(datas,start,end);

}

 

(四):归并排序

基本思想:将两个或两个以上的有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的。然后把有序子序列合并为整体有序序列。

JAVA实现:

private void merge(List datas,int left,int center,int right) {

List temp = new ArrayList();

int startIndex = left;

int mid = center+1;

while(left<=center && mid<=right) {

if(datas.get(left).toString().compareTo(datas.get(mid).toString())<0) {

temp.add(datas.get(left));

left++;

}else {

temp.add(datas.get(mid));

mid++;

}

}

while(mid<=right) {

temp.add(datas.get(mid));

mid++;

}

while(left<=center) {

temp.add(datas.get(left));

left++;

}

int index=0;

for(;startIndex<=right;startIndex++) {

datas.set(startIndex,temp.get(index++));

}

}

 

private void mergeSort(List datas,int left,int right) {

if(left<right) {

int center = (left+right)/2;

mergeSort(datas,left,center);

mergeSort(datas,center+1,right);

merge(datas,left,center,right);

}

}

 

 

private void sort(List datas) {

int length = datas.size();

if(length<=1)

return;

mergeSort(datas,0,length-1);

}


(五):基数排序

基本思想:将所有待比较数值(正整数)统一为同样的数位长度,数位较短的数前面

补零。然后,从最低位开始,依次进行一次排序。基数排序是通过‘分配’和‘收集’过程来实现排序的,不需要进行关键字间的比较,是一种借助于多关键字排序的思想对单关键字排序的方法。

JAVA实现:

private void sort(int[] datas) {

int length = datas.length;

if(length<=1) return;

List mainArray = new ArrayList();

//建立10个队列

for(int count=0;count<10;count++) {

List array = new ArrayList();

mainArray.add(array);

}

int max = datas[0];

for(int index=1;index<length;index++) {

if(datas[index]>max) {

max = datas[index];

}

}

//最大数是几位

int time = 0;

while(max>0) {

max/=10;

time++;

}

for(int bit=0;bit<time;bit++) {

//分配

for(int data=0;data<datas.length;data++) {

//求出该趟位数

int radix = datas[data]%(int)Math.pow(10,bit+1)/(int)Math.pow(10,bit);

List radixArray = (List) mainArray.get(radix);

radixArray.add(datas[data]);

}

//收集数据

int record = 0;

for(int index=0;index<10;index++) {

while(null!=mainArray.get(index) && ((List)mainArray.get(index)).size()>0) {

List array = (List)mainArray.get(index);

datas[record]=Integer.parseInt((array.get(0).toString()));

array.remove(0);

record++;

}

}

}

}

 

各种排序算法性能对比:

 

排序方法

时间复杂度

稳定性

直接插入排序

O(n^2)

稳定

希尔排序

O(n^1.3)

不稳定

冒泡排序

O(n^2)

稳定

快速排序

O(nlog2n)

不稳定

直接选择排序

O(n^2)

不稳定

堆排序

O(nlog2n)

不稳定

归并排序

O(nlog2n)

稳定

基数排序

O(d(n+r))

稳定

 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Go语言(也称为Golang)是由Google开发的一种静态强类型、编译型的编程语言。它旨在成为一门简单、高效、安全和并发的编程语言,特别适用于构建高性能的服务器和分布式系统。以下是Go语言的一些主要特点和优势: 简洁性:Go语言的语法简单直观,易于学习和使用。它避免了复杂的语法特性,如继承、重载等,转而采用组合和接口来实现代码的复用和扩展。 高性能:Go语言具有出色的性能,可以媲美C和C++。它使用静态类型系统和编译型语言的优势,能够生成高效的机器码。 并发性:Go语言内置了对并发的支持,通过轻量级的goroutine和channel机制,可以轻松实现并发编程。这使得Go语言在构建高性能的服务器和分布式系统时具有天然的优势。 安全性:Go语言具有强大的类型系统和内存管理机制,能够减少运行时错误和内存泄漏等问题。它还支持编译时检查,可以在编译阶段就发现潜在的问题。 标准库:Go语言的标准库非常丰富,包含了大量的实用功能和工具,如网络编程、文件操作、加密解密等。这使得开发者可以更加专注于业务逻辑的实现,而无需花费太多时间在底层功能的实现上。 跨平台:Go语言支持多种操作系统和平台,包括Windows、Linux、macOS等。它使用统一的构建系统(如Go Modules),可以轻松地跨平台编译和运行代码。 开源和社区支持:Go语言是开源的,具有庞大的社区支持和丰富的资源。开发者可以通过社区获取帮助、分享经验和学习资料。 总之,Go语言是一种简单、高效、安全、并发的编程语言,特别适用于构建高性能的服务器和分布式系统。如果你正在寻找一种易于学习和使用的编程语言,并且需要处理大量的并发请求和数据,那么Go语言可能是一个不错的选择。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值