堆排 归并排序 快排

堆排序的思想

利用大顶堆(小顶堆)堆顶记录的是最大关键字(最小关键字)这一特性,使得每次从无序中选择最大记录(最小记录)变得简单。

其基本思想为(大顶堆):

1)将初始待排序关键字序列(R1,R2....Rn)构建成大顶堆,此堆为初始的无序区;

2)将堆顶元素R[1]与最后一个元素R[n]交换,此时得到新的无序区(R1,R2,......Rn-1)和新的有序区(Rn),且满足R[1,2...n-1]<=R[n];

3)由于交换后新的堆顶R[1]可能违反堆的性质,因此需要对当前无序区(R1,R2,......Rn-1)调整为新堆,然后再次将R[1]与无序区最后一个元素交换,得到新的无序区(R1,R2....Rn-2)和新的有序区(Rn-1,Rn)。不断重复此过程直到有序区的元素个数为n-1,则整个排序过程完成。

操作过程如下:

1)初始化堆:将R[1..n]构造为堆;

2)将当前无序区的堆顶元素R[1]同该区间的最后一个记录交换,然后将新的无序区调整为新的堆。

package sort;

import java.util.Scanner;

public class 堆排 {
    static void maxHeapity(int a[],int x,int y){//保持最大堆性质
       int  max=a[x];
       int l=x;
       if  (((x+1)*2<y)&&(a[(x+1)*2]>max) )  {
                   l=(x+1)*2;
                   max=a[l];
                   }
       if  ((x*2+1<y)&&(a[x*2+1]>max) ){
           l=x*2+1;
           max=a[l];
           }
       if (l!=x){
           int t;
           t=a[l];a[l]=a[x];a[x]=t;
           maxHeapity(a,l,y);

       }

    }
    static void buildMaxHead(int a[],int n){//建堆
        int i;
        for (i=n/2;i>=0;i--)
            maxHeapity(a,i,n);
    }

    public static void main(String[] args) {
        Scanner read = new Scanner(System.in);
        //System.out.println("输入元素个数N:=");
        int n=read.nextInt();
        int a[]=new int[n];
        int b[]=new int[n];
        int i;
        for ( i=0;i<n;i++)
            a[i]=read.nextInt();
        buildMaxHead(a,n);

       int l=n;
        for(i=0;i<l;i++)
        {
            b[i]=a[0];
            a[0]=a[n-1];
            n=n-1;
            maxHeapity(a,0,n);
        }
        for (i=0;i<l;i++)
            System.out.print(b[i]+"  ");
        }
}
归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法package sort;

import java.util.Scanner;

public class 二分排序 {
    private  static int sort(int  a[],int x,int y ){
        if  (x==y) return 0;
        int mid=(x+y)/2;
        sort(a,x,mid);
        sort(a,mid+1,y);
        int l=x;
        int r=mid+1;
        int b[]=new int[y-x+1];
        int s=0;int t;
        while ((l<=mid)&&(r<=y)){
            if (a[l]>a[r]) { b[s]=a[r];r++; }
            else {b[s]=a[l];l++;}
            s++;
        }
        if (l<=mid)
             for (int i=l;i<=mid;i++) {b[s]=a[i];s++;}
        else  for (int i=r;i<=y;i++) {b[s]=a[i];s++;}
        for (int i=0;i<s;i++)
              a[x+i]=b[i];
        return 0;
  }

    public static void main(String[] args) {
        Scanner read = new Scanner(System.in);
        //System.out.println("输入元素个数N:=");
        int n=read.nextInt();
        int a[];
        a=new int[n];
        for (int i=0;i<n;i++)
            a[i]=read.nextInt();
        int l=sort(a,0,n-1);
        for (int i=0;i<n;i++)
            System.out.print(a[i]+"  ");
    }

}
它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
package sort;

import java.util.Scanner;

public class 快排 {
    private  static void sort(int x,int y,int[] a){
        int i,j,k,t,l;
        i=x;
        j=y;
        l=(i+j)/2;
        k=a[l];
        do{
             System.out.print(i+"  "+j+"  "+k+"------");
             while ( (i<j) && (a[i]<k)) { i++;}
             while ( (i<j) && (a[j]>k) ) { j--;}
             System.out.println(i+"  "+j+"  "+k);
           if (i<j) {
               if (a[i]==k ) l=j;
               if (a[j]==k) l=i;
               t=a[i]; a[i]=a[j];a[j]=t;
               i++;
               j--;
           }

        }while  (i<j);
        if (l-1>x)   {   sort(x,l-1,a);  }
        if (l+1<y)  {   sort(l+1,y,a); }

    }
    public static void main(String[] args) {
        Scanner read = new Scanner(System.in);
        //System.out.println("输入元素个数N:=");
        int n=read.nextInt();
        int a[];
        a=new int[n];
        for (int i=0;i<n;i++)
            a[i]=read.nextInt();
        sort(0,n-1,a);
        for (int i=0;i<n;i++)
            System.out.print(a[i]+"  ");
        }
}
时间: 2024-08-11 05:31:43

堆排 归并排序 快排的相关文章

排序算法合集(冒泡,选择,插入,堆排,快排)

1.冒泡排序 最初在学c语言时,老师就教的这个排序算法,原理比较简单:从数组下标为0处开始遍历,相邻之间进行比较,若a[i]>a[i+1],则exchange(a[i],a[i+1]),当然也可以将小的往后传递,将此过程不断进行,那么最后数组就有序了. 要点:(1)每遍历一遍,末尾就得到一个最大值(或最小值),那么接下来的遍历是不是每次都减少一个元素就好了,因为后边的已经排好序了啊. (2)遍历n-1遍就排好序了,因为最后一遍只剩一个元素了,它一定放那儿,所以最后一遍就不用遍历了. 当然如果数据

topK问题最小堆和快排哪个快

最近一直纠结这个问题.看了很多帖子,决定自己写个例子,实测结果如下: 总数1万个取最大100,快排略快,最小堆偶尔快. 总数10万个取最大100,最小堆略快,快排偶尔快. 总数100万个取最大100,最小堆完胜,快排没戏,而且最小堆大概快了2倍. 总数1000万个取最大100,最小堆完虐,快排没戏,而且最小堆快了大概2倍. 结论:最小堆比快排优秀. 原因: 1.速度确实快. 2.最小堆不需要打乱原数据顺序,而快排会打乱.(并不是快的原因,而是最小堆的优点) 3.如果内存有限,无法加载所有数据,则

普林斯顿公开课 算法3-3:三路快排

很多时候排序是为了对数据进行归类,比如对城市进行排序,对员工的职业进行排序.这种排序的特点就是重复的值特别多. 如果使用普通的快排对这些数据进行排序,会造成N^2复杂度,但是归并排序和三路快排就没有这样的问题. 三路快排 三路快排的基本思想就是,在对数据进行分区的时候分成左中右三个部分,中间都是相同的值,左侧小于中间,右侧大于中间. 性能 三路快排的复杂度比普通快排小,主要取决于数据中重复数据的数量.重复数据越多,三路快排的复杂度就越接近于N. 代码 public class Quick3 {

快排和归并分治总结

快排和归并排序都运用了分治的思想,所以在我看来这两种排序方法都有自己的相似性. 快排 在快排中,首先运用的是分割的方式,选取pivot,将比pivot小的元素放在pivot前面.将比pivot大的元素放在pivot后面. quickSort(arr[],low,high) { if(low<high) { pi = partition(arr,low,high); quickSort(arr,low,pi-1); quickSort(arr,pi+1,high); } } 接下来是实现这个方法的

算法导论学习之快排+各种排序算法时间复杂度总结

快排是一种最常用的排序算法,因为其平均的时间复杂度是nlgn,并且其中的常数因子比较小. 一.快速排序 快排和合并排序一样都是基于分治的排序算法;快排的分治如下: 分解:对区间A[p,r]进行分解,返回q,使得A[p–q-1]都不大于A[q] A[q+1,r]都大于A[q]; 求解:对上面得到的区间继续递归进行快排 合并:因为快排是原地排序,所以不需要特别的合并 从上可以看出最重要的就是分解函数,其按关键值将数组划分成3部分,其具体实现的过程见代码注释. 我们一般取数组的最后一个元素作为划分比较

排序 折半,冒泡 快排

折半插入排序: /*********************************************** 折半插入排序 ***********************************************/ #include<stdio.h> #include<string.h> #include<math.h> #include<ctype.h> #include<stdbool.h> #include<stdlib.h

初探快排

学了数据结构,实现下快排, public void QuickSort1(float[] seq,int low,int hight){int i = low;//记录最左值索引int j = hight;//记录最右值索引float temp = seq[low];//记录比较值(此处是最左值)while (low < hight)//每轮比较{while (low < hight && temp >= seq[hight]){hight--;}seq[low] = s

淘宝等seo广告里面所讲的三天上首页的快排技术大揭秘

淘宝等seo广告里面所讲的三天上首页的快排技术大揭秘 淘宝seo快排技术 今天,我在志在指尖群里面看了看,有人说做一个排名其实非常的简单(我去,简单?想做好seo这是何等漫长的一个事情,谈何简单)我们都知道,做好seo,不仅要做好站内,也要做好站外,不管是关键词布局,内链布局等,还是外链创设,在这是文章书写等,这都是需要很大耐心以及技术的.所以,我没打扰他,我就想听听他口中所谓seo'简单'二字是什么意思,结果意想不到,他就直说了四个字-淘宝快排-what fuck?这四个字让我笑得肚子疼(这里

快排,堆排与归并排序

快排: Parition函数用于进行一次快排,本次快排将某个元素放在它应该呆在的位置pos.pos左侧全比它小,pos右侧全比它大. Parition中,设置low指针与high指针,以待排元素为标杆,判断high指向元素是否大于待排元素,若小于则与low指向的元素交换,并切换到low指针.low指针此时指向刚交换过来的元素,其一定小于待排元素,然后low自加直到low指向的元素大于待排元素,此时再与high指向的元素交换,high指向的元素为之前一次low - high交换前low指向的元素: