Insertion sort and quick sort

 Insertion Sort

 The basic idea is insertion sort: a sort of record of each pass to be inserted according to the size of the keyword is already in place a set of sorted records on, until all the records to be sorted until the entire insert.

For example, when the grip play poker card grabbed to ensure an orderly arrangement of the cards each draw a card, is inserted into an appropriate position, until the catch until the finished card, to obtain an ordered sequence.

You can select a different approach to find the insertion position has been sorted records. Depending on the search method, there are a variety of insertion sort method, here we are introduced directly into the sort.

Direct insertion sort

Direct insertion sort (Straight Insertion Sort) is one of the simplest sorting method, the basic operation is to have a record into the sorted list of ordered rows, to thereby obtain a new record ordered by number in Table 1

 

Algorithm steps

1) to be sorted on the recording apparatus [... n-1] in, r [1] of the array is an ordered sequence r.

2) cycle n-1 times, each time using the sequential search method to find r [i] (i = 2, ... n) is inserted [1 ... i-1] is already in the sorted sequence r position, then r [i] into a table of length i-1 ordered sequence of r [1 ... i-1], directly to the ordered sequence r [n] into a table of length n-1, r [1 ... n-1], to obtain a final table ordered sequence of length n,

Sorting insert schematic

Realization of java code

Package com.hxy.sort; 

Import java.util.Arrays; 

public  class InsertSort {
     public  static  void main (String [] args) {
         int [] = {49,38,65,97,76,13,27,49 ARR }; 
        System.out.println ( "before the sorted array" ); 
        System.out.println (of Arrays.toString (ARR)); 
        insertSort (ARR); 
        System.out.println ( "after sorted array" ); 
        the System .out.println (of Arrays.toString (ARR)); 
    } 
    public  static  void insertSort ( int [] ARR) {
         for ( int. 1 = i; i <arr.length; i ++ ) {
             IF (ARR [i] <ARR [i-1]) { // If the i-th element of i-1 is smaller than the first element, an ordered sequence of movement, if more than then directly inserted 
                int TEMP = ARR [I]; // store data to be inserted recording 
                ARR [I] = ARR [I-. 1 ];
                 int J = I-. 1 ;
                 for (; J> = 0 && TEMP <ARR [J] ; J -) { // determination condition 
                    ARR [J +. 1] = ARR [J]; 
                } 
                ARR [J + 1'd] = TEMP; // the element to be inserted into the specified position 
            } 
        } 
    } 
}

Results are shown in FIG.

 Animated schematic

 Insertion Sort

time complexity

对于整个排序过程需执行n-1趟,在最好的情况下(正序:待排序序列中记录按关键字非递减有序排列),总的移动比较次数达到最小值n-1,记录不需移动;最坏情况下(即待排序表为逆序),总的关键字比较次数为(n+2)(n-1)/2≈n^{2}/2,记录移动次数为(n+4)(n-1)/2≈n^{2}/2。若待排序序列中出现各种可能排列的概率相同,则可取上述最好情况和最坏情况的平均情况。在平均情况下,直接插入排序关键字的比较次数和记录移动次数均约为n^{2}/4。由此,直接插入排序的时间复杂度为O(n^{2}

空间复杂度

直接插入排序只需要一个记录的辅助空间temp,所以空间复杂度为O(1)。

算法的特点

(1)稳定排序

(2)算法简单,且容易实现

(3)也适用于链式存储结构,只是在单链表上无需移动记录,只需修改相应的指针。

(4)更适合初始记录基本有序(正序)的情况,当初始记录无序,n较大时,此算法的时间复杂度较高,不宜采用

快速排序

快速排序(Quick Sort)是由冒泡排序改进而得的。在冒泡排序过程中,只对相邻的两个记录进行比较,因此每次交换两个相邻的记录时只能消除一个逆序。如果能通过两个(不相邻)记录的一次交换,消除多个逆序,则会大大加快排序的速度。快速排序方法中的一次交换可能消除多个逆序。

 

算法步骤

在待排序的n个记录中任取一个记录(通常取第一个记录)作为枢轴(或支点),设其关键字为pivotkey。经过一趟排序后,把所有关键字小于pivotkey的记录交换到前面,把所有关键字大于pivotkey的记录交换到后面,结果将待排序记录分成两个子表,最后将枢轴放置在分界处的位置。然后,分别对左、右子表重复上述过程,直至每一个子表只有一个记录时,排序完成。

其中,一趟快速排序的具体步骤如下。

  1)选择待排序表中的第一个记录作为枢轴,将枢轴记录暂存在r[0]的位置上。附设两个指针low和high,初始时分别指向表的下界和上界(第一趟时,low=1;high=L.length)。

  2)从表的最右侧位置依次向左搜索,找到第一个关键字小于枢轴关键字pivotkey的记录,将其移到low处。具体操作是当low<high时,若high所指记录的关键字大于等于pivotkey,则向左移动指针high(执行操作high- -);否则将high所指记录与枢轴记录录交换。

  3)然后再从表的最左侧位置,依次向右搜索找到第一个关键字大于pivotkey的记录和枢轴记录交换。具体操作是:当low<high时,若low所指记录记录关键字小于等于pivotkey,则向右移动指针low(执行操作low++);否则将low所指记录与枢轴记录交换。

  4)重复步骤2)和3),直至low与high相等为止。此时low或high的位置即为枢轴在此趟排序中的最终位置,原表被分成两个子表。

  在上述过程中,记录的交换都是与枢轴之间发生,每次交换都要移动3次记录,可以先将枢轴记录暂存在r[0]的位置上,排序过程中只要移动与枢轴交换的记录,即只做r[low]或r[high]的单向移动,直至一趟排序结束后再将枢轴记录移至正确位置上 

 

 

java代码的实现

       

 
 
package com.hxy.sort;

import java.util.Arrays;

public class QuickSort {
public static void main(String[] args) {

int[] arr ={8,5,7,6,9,5,4,2,10};
System.out.println("排序之前的顺序");
System.out.println(Arrays.toString(arr));
//int [] arr = {4,6};
//int[] arr = {1,2,3,4,5,6,7,7,7,9};
quickSort(arr,0,arr.length-1);
System.out.println("排序之后的顺序");
System.out.println(Arrays.toString(arr));

}
public static void quickSort(int[] arr , int leftBound, int rightBound){
if(leftBound>=rightBound){
return;
}
int mid = partition(arr, leftBound, rightBound);
quickSort(arr,leftBound,mid-1);
quickSort(arr,mid+1,rightBound);
}
public static int partition(int[] arr,int leftBound,int rightBound){
int pivot = arr[rightBound];
int left = leftBound ;
int right = rightBound-1;
while (left<right){
while (arr[left]<=pivot && left<=right)left++;

while (arr[right]>pivot && left<right)right--;

if(left<right) {
swap(arr, left, right);
}
}
if(arr[left]>pivot)
swap(arr,left,rightBound);
return left;

}
static void swap(int[] arr, int i,int j){
int temp = arr[i];
arr[i] = arr[j];
arr[j]= temp;
}
}

 

 

结果如下图所示      

 

 

 

 

动画示意图

时间复杂度

从快速排序算法的递归树可知,快速排序的趟数取决于递归树的深度。

最好情况下:每一趟排序后都能将记录序列均匀地分割成两个长度大致相等的子表,类似折半查找。在n个元素的序列中,对枢轴定位所需时间为O(n).若设T(n)是对n个元素的序列进行排序所需的时间,而且每次对枢轴正确定位后,正好把序列划分为长度相等的两个子表,此时,设Cn是一个常数,表示n个元素进行一趟快速排序的时间,则总排序的时间为

T(n)=Cn+2T(n/2)

  ≤n+2T(n/2)

  ≤n+2(n/2+2T(n/4))=2n+4T(n/4)

  ≤2n+4(n/4+2T(n/8))=3n+8T(n/8)

  ……

  ≤kn+2kT(n/2k)

∵k=n

∴T(n) ≤nn+nT(1)≈O(nn)

  最坏情况下:在待排序序列已经排好序的情况下,其递归树成为单支树,每次划分只得到一个比上一次少一个记录的子序列。这样必须经过n-1趟才能将所有记录定位,而且第i趟需要经过n-i次比较。这样,总的关键字比较次数为n(n-1)/2≈n2/2

  In this case, quick sort of speed has been degraded to the level of simple sorting. Reasonable choice pivot recorded avoid this worst case occurs, such as the use of "taking in three" rule: first comparing the current record in the table, the intermediate and the last record a record keyword, the keyword takes recording the recording as a pivot center, prior to the exchange position of the first record.

  In theory can be proved, the average case time complexity of quick sort is O (nn).

Space complexity

Quicksort is recursive, it is necessary to stack a corresponding data store execution. The maximum depth of recursive calls to the number consistent with the recursive lost, so in the best case space complexity is the worst-case O O (n)

Algorithms Features

1) non-sequential recording movement causes ordering method is unstable.

2) sorting process requires lower and upper bounds of the location table, it is suitable for the sequential structure, a chain structure is difficult.

3) when n is large, in the average case quicksort internal sorting method all the fastest one of its applicable random initial recording, where n is large.

Guess you like

Origin www.cnblogs.com/huxiaoyang/p/12032004.html