您的位置:首页 > 职场人生

"黑马程序员"算法大全

2013-07-05 18:53 162 查看
------ <a href="http://www.itheima.com" target="blank">android培训</a>、<a href="http://www.itheima.com"


这里讲的是快速排序,冒泡排序,选择排序,插入排序,自己拼接4种算法。你懂这些吗?

快速排序

int partition(int n[],int left,int right)

{

int lo,hi,pivot,t;

pivot=n[left];

lo=left-1;

hi=right+1;

while(lo+1!=hi) {

     if(n[lo+1]<=pivot)

       lo++;

     else if(n[hi-1]>pivot)

       hi--;

     else {

       t=n[lo+1];

       n[++lo]=n[hi-1];

       n[--hi]=t;

     }

}

n[left]=n[lo];

n[lo]=pivot;

return lo;

}

    这段程序并不难,应该很好看懂,我把过程大致讲一下,首先你的脑子里先浮现一个

数组和三个指针,第一个指针称为p指针,在整个过程结束之前它牢牢的指向第一个数,

第二个指针和第三个指针分别为lo指针和hi指针,分别指向最左边的值和最右边的值。lo

指针和hi指针从两边同时向中间逼近,在逼近的过程中不停的与p指针的值比较,如果lo

指针的值比p指针的值小,lo++,还小还++,再小再++,直到碰到一个大于p指针的值,这

时视线转移到hi指针,如果 hi指针的值比p指针的值大,hi--,还大还--,再大再--,直

到碰到一个小于p指针的值。这时就把lo指针的值和hi指针的值做一个调换。持续这过程

直到两个指针碰面,这时把p指针的值和碰面的值做一个调换,然后返回p指针新的位置

------------------------------------------------------------------
冒泡排序:

void BubbleSort(SeqList R)

    { //R(l..n)是待排序的文件,采用自下向上扫描,对R做冒泡排序

     int i,j;

     Boolean exchange; //交换标志

     for(i=1;i<n;i++){ //最多做n-1趟排序

       exchange=false; //本趟排序开始前,交换标志应为假

       for(j=n-1;j>=i;j--)

        if(R[j+1].key<R[j].key){

          R[0]=R[j+1];

          R[j+1]=R[j];

          R[j]=R[0];

          exchange=true; //发生了交换,故将交换标志置为真

         }

        if(!exchange) //本趟排序未发生交换,提前终止算法

             return;

     }

     }

分析

     因为每一趟排序都使有序区增加了一个气泡,在经过n-1趟排序之后,有序区中就有n-1个气泡,而无序区中气泡的重量总是大于等于有序区中气泡的重量,所以整个冒泡排序过程至多需要进行n-1趟排序。

     若在某一趟排序中未发现气泡位置的交换,则说明待排序的无序区中所有气泡均满足轻者在上,重者在下的原则,因此,冒泡排序过程可在此趟排序后终止。为此,在下面给出的算法中,引入一个布尔量exchange,在每趟排序开始前,先将其置为FALSE。若排序过程中发生了交换,则将其置为TRUE。各趟排序结束时检查exchange,若未曾发生过交换则终止算法,不再进行下一趟排序。

------------------------------------------------------------------
选择排序:

基本思想:

  每一趟从待排序的数据元素中选出最小(或最大)的一个元素,顺序放在已排好序的数列的最后,直到全部待排序的数据元素排完。

直接选择排序的基本思想

     n个记录的文件的直接选择排序可经过n-1趟直接选择排序得到有序结果:

 ①初始状态:无序区为R[1..n],有序区为空。

 ②第1趟排序

     在无序区R[1..n]中选出关键字最小的记录R[k],将它与无序区的第1个记录R[1]交换,使R[1..1]和R[2..n]分别变为记录个数增加1个的新有序区和记录个数减少1个的新无序区。

  ……

 ③第i趟排序

  第i趟排序开始时,当前有序区和无序区分别为R[1..i-1]和R[i..n](1≤i≤n-1)。该趟排序从当前无序区中选出关键字最小的记录R[k],将它与无序区的第1个记录R[i]交换,使R[1..i]和R[i+1..n]分别变为记录个数增加1个的新有序区和记录个数减少1个的新无序区。

     这样,n个记录的文件的直接选择排序可经过n-1趟直接选择排序得到有序结果。

void SelectSort(SeqList R)

 {

   int i,j,k;

   for(i=1;i<n;i++){//做第i趟排序(1≤i≤n-1)

     k=i;

     for(j=i+1;j<=n;j++) //在当前无序区R[i..n]中选key最小的记录R[k]

       if(R[j].key<R[k].key)

         k=j;

       if(k!=i){

         R[0]=R[i];R[i]=R[k];R[k]=R[0];

        }

     }

  }

-------------------------------------------------------
插入排序:

将n个元素的数列分为已有序和无序两个部分,如插入排序过程示例  插入排序过程示例

下所示:

{{a1},{a2,a3,a4,…,an}}

{{a1⑴,a2⑴},{a3⑴,a4⑴ …,an⑴}}



{{a1(n-1),a2(n-1) ,…},{an(n-1)}}
每次处理就是将无序数列的第一个元素与有序数列的元素从后往前逐个进行比较,找出插入位置,将该元素插入到有序数列的合适位置中。

示例:

public class InsertSort {

public static void main(String[] args) {

insertSort(new int[]{8,2,4,9,3,6,7,10});

}

// 辅助函数

public static void dumpArray(int[] a) {

for (int index = 0; index < a.length; index++) {

System.out.print(a[index] + " ");

}

System.out.println("");

}

public static void insertSort(int[] a) {

// 输出原始数组

dumpArray(a);

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

int subIndex = index;

int currentData = a[index]; // 等待插入的数据

while ((subIndex > 0) && (a[subIndex - 1] > currentData)) {

a[subIndex] = a[subIndex - 1];

subIndex--;

a[subIndex] = currentData; // 插入到合适的位置

}

// 每次排序后也输出

dumpArray(a);

}

}
}

------ <a href="http://www.itheima.com" target="blank">android培训</a>、<a href="http://www.itheima.com"
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息