Summary of iOS Sorting Algorithms


Check website: http://student.zjzk.cn/course_ware/data_structure/web/paixu/paixu8.5.1.1.htm

binary tree

http://blog.csdn.net/walkinginthewind/article/details/7518888



Learn from the above address and summarize some commonly used sorting algorithms, which is convenient for everyone and their own learning.


1. Insertion sort

    1. Direct insertion sort

Basic idea of ​​direct insertion sort


1. Basic idea

 Suppose the records to be sorted are stored in the array R[ 1. .n] . Initially, R[ 1 ] forms an ordered area by itself , and the disordered area is R[ 2. .n] . From i= 2 until i=n , ​​insert R[i] into the current ordered area R[ 1..i- 1 ] in turn to generate an ordered area with n records.


2. The i- 1th direct insertion sort:

 Usually, a record R[i] (i= 2 , 3 , , n- 1 ) is inserted into the current ordered area, so that the records in the interval are guaranteed to be ordered by keywords after the insertion, which is called the i -th operation. - 1 pass direct insertion sort.

 At some intermediate moment in the sorting process, R is divided into two subintervals R[ 1 . . i- 1 ] (sorted ordered region) and R[i . . n] (the current unsorted part, which can be called an unordered area).

 The basic operation of direct insertion sort is to insert the first record R[i] of the current disordered area into the ordered area R[ 1 ] . . i- 1 ] in the appropriate position, make R[ 1 . . i] becomes the new ordered area. Because this method increases the ordered area by 1 record at a time, it is usually called the incremental method.

 Insertion sort is very similar to sorting out your cards in a game of poker. The first card drawn does not need to be sorted, after that each time the top card is drawn from the cards on the table ( disordered area ) and inserted into the correct position in the left-hand card ( ordered area ) . In order to find this correct position, the drawn cards must be compared one by one with the existing cards in the left hand from left to right ( or right to left ) .


     1. Algorithm Description

void lnsertSort(seqList R)

{ // Insert and sort the records R[1..n] in the sequence table R in increasing order

    int i, j;

    for(i=2; i<=n; i++)//依次插入R[2]R[n]

    {

        if (R[i].key<R[i- 1 ].key){ // If R[i].key is greater than or equal to all keys in the ordered area , then R[i]

            // should be in the original position

            R[0]=R[i];

            j=i- 1 ; //R[0] is a sentinel and a copy of R[i]

            do { // From right to left in the ordered area R[1 . . Find the insertion position of R[i] in i-1]

                R[j+ 1 ]=R[j]; // Move back the records whose keywords are greater than R[i].key

                j-- ;

            }while(R[0].key<R[j].key);//R[i].key≥R[j].key时终止

        R[j+ 1 ]=R[ 0 ]; //R[i] is inserted in the correct position

        }//endif

    }

}


2, Hill (shell) sorting

Basic idea:

     先取一个小于n的整数d1作为第一个增量,把文件的全部记录分成d1个组。所有距离为dl的倍数的记录放在同一个组中。先在各组内进行直接插人排序;然后,取第二个增量d2<d1重复上述的分组和排序,直至所取的增量dt=1(dt<dt-l<…<d2<d1),即所有记录放在同一组中进行直接插入排序为止。

 该方法实质上是一种分组插入方法。


Shell排序的算法实现


1不设监视哨的算法描述

void ShellPass(SeqList Rint d)

{//希尔排序中的一趟排序,d为当前增量

    for(i=d+1;i<=ni++)//R[d+1..n]分别插入各组当前的有序区

        if(R[i].key<R[i-d].key){

            R[0]=R[i];j=i-d//R[0]只是暂存单元,不是哨兵

            do {//查找R[i]的插入位置

                R[j+d]=R[j]//后移记录

                j=j-d//查找前一记录

            }while(j>0&&R[0].key<R[j].key)

                R[j+d]=R[0]//插入R[i]到正确的位置上

                } //endif

} //ShellPass


void  ShellSort(SeqList R)

{

    int increment=n//增量初值,不妨设n>0

    do {

        increment=increment/3+1//求下一增量

        ShellPass(Rincrement)//一趟增量为incrementShell插入排序

    }while(increment>1)

        } //ShellSort

注意:

     当增量d=1时,ShellPassInsertSort基本一致,只是由于没有哨兵而在内循环中增加了一个循环判定条件"j>0",以防下标越界。


二、交换排序

  1、冒泡排序

具体算法

void BubbleSort(SeqList R)

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

    int ij

    Boolean exchange //交换标志

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

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

        for(j=n-1;j>=ij--) //对当前无序区R[i..n]自下向上扫描

            if(R[j+1].key<R[j].key){//交换记录

                R[0]=R[j+1] //R[0]不是哨兵,仅做暂存单元

                R[j+1]=R[j]

                R[j]=R[0]

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

            }

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

            return

            } //endfor(外循环)

} //BubbleSort


2、快速排序

快速排序是对冒泡排序的一种本质改进。它的基本思想是通过一趟扫描后,使得排序序列的长度能大幅度地减少。在冒泡排序中,一次扫描只能确保最大数值的数移到正确位置,而待排序序列的长度可能只减少1。快速排序通过一趟扫描,就能确保以某个数为基准点的左边各数都比它小,右边各数都比它大。然后又用同样的方法处理它左右两边的数,直到基准点的左右只有一个元素为止。

显然快速排序可以用递归实现,当然也可以用栈化解递归实现。

快速排序是不稳定的。最理想情况算法时间复杂度O(nlog2n),最坏O(n2)

main()

{

int a[10],i;

quick_sort(a,0,9);

}

quick_sort(int L[],int first,int end)

{

int split;

if(end>first)

{

split=quick(first,end,L);//进行一次希尔排序,返回值为本次排序基准值的下标值 

       quick_sort(L,first,split-1);//上面的排序完成后再对基准点左右的数组进行同样的排序操作

       quick_sort(L,split+1,end);

   }

}

quick(int first,int end,int L[])

{

int left=first,right=end;

int key=L[first];

while(left<right)

{

while((left<right)&&(L[right]>=key))

right--;

if(left<right)

L[left++]=L[right];

while((left<right)&&(L[left]<=key))

left++;

if(left<right)

L[right--]=L[left];

}

L[left]=key;

return left;

}




Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325770835&siteId=291194637