插入排序:直接插入排序、折半插入排序和系尔排序

2024-06-03 22:08

本文主要是介绍插入排序:直接插入排序、折半插入排序和系尔排序,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

排序算法java版,速度排行:冒泡排序、简单选择排序、直接插入排序、折半插入排序、希尔排序、堆排序、归并排序、快速排序  

2011-05-26 17:11:17|  分类: java |字号 订阅

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 插入排序:直接插入排序、折半插入排序和系尔排序
 * 交换排序:冒泡排序和快速排序
 * 选择排序:简单选择排序和堆排序
 * 归并排序:归并排序
 *
 * 基本思想
 * 插入排序:将第N个记录插入到前面(N-1)个有序的记录当中。
 * 交换排序:按照某种顺序比较两个记录的关键字大小,然后根据需要交换两个记录的位置。
 * 选择排序:根据某种方法选择一个关键字最大的记录或者关键字最小的记录,放到适当的位置。
 *
 * 排序方法比较
 * 排序方法         平均时间        最坏时间         辅助存储
 * 直接插入排序      O(N2)          O(N2)           O(1)
 * 起泡排序         O(N2)          O(N2)           O(1)
 * 快速排序         O(Nlog2N)      O(N2)           O(Nlog2N)
 * 简单选择排序      O(N2)          O(N2)           O(1)
 * 堆排序           O(Nlog2N)      O(Nlog2N)       O(1)
 * 归并排序         O(Nlog2N)      O(Nlog2N)       O(n)
 * 基数排序         O(d(n+radix))  O(d(n+radix))   O(radix)
 *
 *
 *
 * @author Administrator
 *
 */
public class SortTest {

    public static void main(String[] args)throws Exception {
        //测试排序是否正确
        //String[] testErr=new String[]{"冒泡排序","简单选择排序","直接插入排序","折半插入排序","系尔排序","堆排序","归并排序","快速排序"};
        //new SortTest().testErr(testErr);
        
        //排序1(全部)
        String[] strs=new String[]{"冒泡排序","简单选择排序","直接插入排序","折半插入排序","希尔排序","堆排序","归并排序","快速排序"};
        new SortTest().test(strs,10000,50000,5000);
        
        //排序2(加强)
        String[] strs2=new String[]{"希尔排序","堆排序","归并排序","快速排序"};
        new SortTest().test(strs2,100000,1900000,100000);
        
    }
private  void testErr(String[] strings) throws Exception{
        
        //System.out.println(Arrays.toString(old));
        System.out.println(Arrays.toString(strings));
        
            Number[] old=getRundom(50);
            Integer[] oo={1,2,3,3,2,21,5,6,7,78,5,65,8,7,6,6,6,6,6,9,56544,354,32,4,456,8,89,-9,0,3,243,-321,321,-3,-2,21};
            old=oo;
            for(String s:strings){
                Number[] testNum=Arrays.copyOf(old, old.length);
                long begin=System.currentTimeMillis();
                SortTest.class.getMethod(s, Number[].class).invoke(this, (Object)testNum);
                
                long end=System.currentTimeMillis();
                System.out.println(s+":"+(end-begin)+"\t");
                System.out.println(Arrays.toString(testNum));
            }
            System.out.println();
        
        
    }
    
    private  void test(String[] strings,long begin,long end,long step) throws Exception{
        System.out.print("数量\t");
        for(String str:strings){
            System.out.print(str+"\t");
        }
        System.out.println();
        for(long i=begin;i<end;i=i+step){
            System.out.print(i+"个\t");
            Number[] old=getRundom(i);
            for(String s:strings){
                Number[] testNum=Arrays.copyOf(old, old.length);
                long beginTime=System.currentTimeMillis();
                SortTest.class.getMethod(s, Number[].class).invoke(this, (Object)testNum);
                
                long endTime=System.currentTimeMillis();
                System.out.print((endTime-beginTime)+"\t");
                //System.out.println(Arrays.toString(testNum));
            }
            System.out.println();
        }
        
    }

    private static Integer[] getRundom(long num) {
        List<Integer> list=new ArrayList<Integer>();
        for(long i=0;i<num;i++){
            int k;
            if(Math.random()>0.5){
                k=(int)(Math.random()*Integer.MAX_VALUE);
            }else{
                k=(int)(Math.random()*Integer.MIN_VALUE);
            }
            list.add(k);
        }
        return list.toArray(new Integer[list.size()]);
    }
    
    
    
    
    /**
     * 插入排序————直接插入排序
     * @param data
     */
    public static  void  直接插入排序(Number[] data)
    {
        Number tmp=null ;
        
      for(int i=1;i<data.length;i++){
          tmp = data[i];
          int j=i-1;
          while(j>=0 && tmp.doubleValue()<data[j].doubleValue()){
              data[j+1]=data[j];
              j--;
          }
          data[j+1]=tmp;
      }
    }
    /**
     * 插入排序————折半插入排序
     * @param data
     */
    public static  void  折半插入排序(Number[] data)
    {
        Number tmp=null ;
          for(int i=1;i<data.length;i++){
              tmp = data[i];
              int smallpoint=0;    
              int bigpoint=i-1;
                
              while(bigpoint>=smallpoint){
                  int mid=(smallpoint+bigpoint)/2;
                  if(tmp.doubleValue()>data[mid].doubleValue()){
                      smallpoint=mid+1;
                  }else{
                      bigpoint=mid-1;
                  }
              }
              for(int j=i;j>smallpoint;j--){
                  data[j]=data[j-1];
              }
              data[bigpoint+1]=tmp;
          }
    }
    
    /**
     * 插入排序————希尔排序
     * @param data
     */
    public static  void  希尔排序(Number[] data)
    {
        int span=data.length/7;
        if(span==0)span=1;
        while(span>=1){
            for(int i=0;i<span;i++){
                for(int j=i;j<data.length;j=j+span){
                    //组内直接插入排序    
                    int p = j-span;
                    Number temp = data[j];
                    while( p >=0 && data[p].doubleValue() > temp.doubleValue()){
                        data[p+span] = data[p];
                        p -=span;
                    }    
                    data[p + span] = temp;
                }
            }
            span=span/2;
        }
        
      
    }
    
    /**
     * 交换排序————冒泡排序
     *
     * @param data
     */
    public static void  冒泡排序(Number[] data)
    {
         for (int i = 0; i < data.length; i++) {
             //将相邻两个数进行比较,较大的数往后冒泡
             for (int j = 0; j < data.length - i-1; j++) {
                    if (data[j].doubleValue()> data[j + 1].doubleValue()) {
                           //交换相邻两个数
                           swap(data, j, j + 1);
                    }
             }
      }
    }
    /**
     * 交换排序————快速排序
     * @param data
     */
    public static void  快速排序(Number[] data)
    {
        QuickSort(data,0,data.length-1);
    }
    
     private static void QuickSort(Number[] data, int begin, int end) {
        // System.out.println(begin+":"+end);
         if(begin<end){
             //取中点
             int mid=(begin+end)/2;
             if(data[end].doubleValue()<data[begin].doubleValue()){
                 swap(data, end, begin);
             }
             if(data[end].doubleValue()<data[mid].doubleValue()){
                 swap(data, end, mid);
             }
             if(data[mid].doubleValue()<data[begin].doubleValue()){
                 swap(data, mid, begin);
             }
            
             swap(data, mid, begin);
            
            // System.out.println(Arrays.toString(Arrays.copyOfRange(data, begin, end)) );
            int min=begin+1;
            int big=end;
            
             while(true){
                while(min<big && data[min].doubleValue()<data[begin].doubleValue()){min++;}
                while(min<big && data[big].doubleValue()>=data[begin].doubleValue()){big--;}
                if(min>=big){
                    break;
                }
                swap(data, min, big);
            }
             if(data[begin].doubleValue()>data[min].doubleValue()){
                 swap(data, begin, min);
             }
            
            if(min>1)
             QuickSort(data,begin,min-1);
            //if(min<end)
             QuickSort(data,min,end);
         }
    }
    /**
         * 选择排序————简单选择排序
         * @param data
         */
        public static void  简单选择排序(Number[] data)
        {
             for (int i = 0; i < data.length-1; i++) {
                 int smallPoint=i;
                 for (int j = i+1; j < data.length; j++) {
                        if (data[smallPoint].doubleValue()> data[j].doubleValue()) {
                            smallPoint=j;
                        }
                 }
                 swap(data, i, smallPoint);
          }
          
        }
        
         /**
         * 选择排序————堆排序
         * @param data
         */
        public static void  堆排序(Number[] data)
        {

             int n = data.length;
            for(int i=n/2;i>=0;i--){
                 keepHeap(data, n, i);
            }
              while (n > 0) {
                  swap(data, 0, n-1);
                  keepHeap(data, --n, 0);
              }
        }
        
        
         private static void keepHeap(Number[] a, int n, int i) {
             Number x = a[i];
              int j = 2 * i + 1;
              while (j <= n - 1) {
               if (j < n - 1 && a[j].doubleValue() < a[j + 1].doubleValue())
                ++j;
               if (a[j].doubleValue() > x.doubleValue()) {
                a[i] = a[j];
                i = j;
                j = 2 * i ;
               } else{
                break;
                }
              }
              a[i] = x;
             }
        
        
        
        
         /**
             * 归并排序法————归并排序
             * @param data
             */
            public static void  归并排序(Number[] data)
            {
                 Number[] result = merge_sort(data,0,data.length-1);
                 for(int i=0;i<result.length;i++){
                     data[i]=result[i];
                 }
            }
         private static  Number[] merge_sort(Number[] array, int start, int end){
             Number[] result = new Number[end-start+1];
                if(start< end){
                    int mid= (start+end)/2;
                    Number[] left= merge_sort(array, start, mid);
                    Number[] right =  merge_sort(array, mid+1, end);
                   result= merge(left,right);
                } else if (start == end) {
                    result[0] = array[start];
                return result;
                }
                return result;
            }
           private static Number[]  merge(Number[] left, Number[] right) {
               Number[] result = new Number[left.length+right.length];
                int i=0;
                int j=0;
                int k=0;
                while(i< left.length&&j< right.length){
                    if(left[i].doubleValue()< right[j].doubleValue()){
                        result[k++] = left[i++];
                    }else{
                        result[k++] = right[j++];
                        
                    }
                }
                while(i< left.length){
                    result[k++] = left[i++];
                }
                while (j< right.length) {
                   result[k++]= right[j++];
                }
                return result;
            }
        
           /**
            * 交换数组中指定的两元素的位置
            * @param data
            * @param x
            * @param y
            */
           private static void swap(Number[] data, int x, int y) {
               Number temp = data[x];
                  data[x] = data[y];
                  data[y] = temp;
           }
}

这篇关于插入排序:直接插入排序、折半插入排序和系尔排序的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1028246

相关文章

【数据结构】——原来排序算法搞懂这些就行,轻松拿捏

前言:快速排序的实现最重要的是找基准值,下面让我们来了解如何实现找基准值 基准值的注释:在快排的过程中,每一次我们要取一个元素作为枢纽值,以这个数字来将序列划分为两部分。 在此我们采用三数取中法,也就是取左端、中间、右端三个数,然后进行排序,将中间数作为枢纽值。 快速排序实现主框架: //快速排序 void QuickSort(int* arr, int left, int rig

usaco 1.3 Mixing Milk (结构体排序 qsort) and hdu 2020(sort)

到了这题学会了结构体排序 于是回去修改了 1.2 milking cows 的算法~ 结构体排序核心: 1.结构体定义 struct Milk{int price;int milks;}milk[5000]; 2.自定义的比较函数,若返回值为正,qsort 函数判定a>b ;为负,a<b;为0,a==b; int milkcmp(const void *va,c

hdu 1285(拓扑排序)

题意: 给各个队间的胜负关系,让排名次,名词相同按从小到大排。 解析: 拓扑排序是应用于有向无回路图(Direct Acyclic Graph,简称DAG)上的一种排序方式,对一个有向无回路图进行拓扑排序后,所有的顶点形成一个序列,对所有边(u,v),满足u 在v 的前面。该序列说明了顶点表示的事件或状态发生的整体顺序。比较经典的是在工程活动上,某些工程完成后,另一些工程才能继续,此时

《数据结构(C语言版)第二版》第八章-排序(8.3-交换排序、8.4-选择排序)

8.3 交换排序 8.3.1 冒泡排序 【算法特点】 (1) 稳定排序。 (2) 可用于链式存储结构。 (3) 移动记录次数较多,算法平均时间性能比直接插入排序差。当初始记录无序,n较大时, 此算法不宜采用。 #include <stdio.h>#include <stdlib.h>#define MAXSIZE 26typedef int KeyType;typedef char In

【软考】希尔排序算法分析

目录 1. c代码2. 运行截图3. 运行解析 1. c代码 #include <stdio.h>#include <stdlib.h> void shellSort(int data[], int n){// 划分的数组,例如8个数则为[4, 2, 1]int *delta;int k;// i控制delta的轮次int i;// 临时变量,换值int temp;in

学习记录:js算法(二十八):删除排序链表中的重复元素、删除排序链表中的重复元素II

文章目录 删除排序链表中的重复元素我的思路解法一:循环解法二:递归 网上思路 删除排序链表中的重复元素 II我的思路网上思路 总结 删除排序链表中的重复元素 给定一个已排序的链表的头 head , 删除所有重复的元素,使每个元素只出现一次 。返回 已排序的链表 。 图一 图二 示例 1:(图一)输入:head = [1,1,2]输出:[1,2]示例 2:(图

鸡尾酒排序算法

目录 引言 一、概念 二、算法思想 三、图例解释 1.采用冒泡排序:   2.采用鸡尾酒排序:  3.对比总结 四、算法实现  1.代码实现  2.运行结果 3.代码解释   五、总结 引言 鸡尾酒排序(Cocktail Sort),也被称为双向冒泡排序,是一种改进的冒泡排序算法。它在冒泡排序的基础上进行了优化,通过双向遍历来减少排序时间。今天我们将学习如何在C

快速排序(java代码实现)

简介: 1.采用“分治”的思想,对于一组数据,选择一个基准元素,这里选择中间元素mid 2.通过第一轮扫描,比mid小的元素都在mid左边,比mid大的元素都在mid右边 3.然后使用递归排序这两部分,直到序列中所有数据均有序为止。 public class csdnTest {public static void main(String[] args){int[] arr = {3,

O(n)时间内对[0..n^-1]之间的n个数排序

题目 如何在O(n)时间内,对0到n^2-1之间的n个整数进行排序 思路 把整数转换为n进制再排序,每个数有两位,每位的取值范围是[0..n-1],再进行基数排序 代码 #include <iostream>#include <cmath>using namespace std;int n, radix, length_A, digit = 2;void Print(int *A,

常用排序算法分析

1. 插入排序 1.1 性能分析 时间复杂度O(n^2), 空间复杂度O(1) 排序时间与输入有关:输入的元素个数;元素已排序的程度。 最佳情况,输入数组是已经排好序的数组,运行时间是n的线性函数; 最坏情况,输入数组是逆序,运行时间是n的二次函数。 1.2 核心代码 public void sort(){int temp;for(int i = 1; i<arraytoSort.