快速排序算法(简单+改进+非递归)C++描述

在学习快速排序算法时,由于理解不对,出现了很多问题。后来在学习数据结构时才明白,故记之。

这里参考了两本书:但显然我校教材不太好理解。

快速排序算法的思想是:

选定枢纽元,将所有小于枢纽元的元素移动到枢纽元的左边,大于枢纽元的元素移动到枢纽元的右边。

主要步骤在于对序列的划分。

 

法一:用补空位的思想去理解(比较好理解的)

取序列中的第一个记录,以其关键码为标准划分其他记录,把关键码小的记录移动到表的左边,关键码大的记录移动到表的右边。

划分完成后表中间将留下一个空位,这就是作为比较标准的记录的正确位置。

    {11,0,4,6,23,5,2,18,7,7}
    {7,0,4,6,23,5,2,18,7,7}
    {7,0,4,6,23,5,2,18,7,23}
    {7,0,4,6,7,5,2,18,7,23}
    {7,0,4,6,7,5,2,18,18,23}
    {7,0,4,6,7,5,2,7,18,23} 

代码:

 1 void quicksort(int k[],int low,int high)
 2 {
 3     if(low>=high) //如果没有记录或者只有一个记录
 4         return;
 5     int i=low,j=high;//i从前向后数,j从后向前数
 6     int pivot=k[low];//选定第一个元素为关键元 
 7     while(i<j) //交换
 8     {
 9         while(i<j && k[j]>=pivot) --j;
10         if(i<j)
11         {
12             k[i]=k[j];
13             i++; 
14         }    
15         while(i<j && k[i]<=pivot) ++i;
16         if(i<j)
17         {
18             k[j]=k[i];
19             j--;
20         }
21     } 
22     k[i]=pivot;
23     quicksort(k,low,i-1);
24     quicksort(k,i+1,high);
25 }

测试无问题....

 

法二:

取序列中的第一个记录,以其关键码为标准划分其他记录,把关键码小的记录移动到表的左边,关键码大的记录移动到表的右边。采用交换的方式。

最后停止时i的位置就是作为比较标准的记录的正确位置。再交换k[i]和[0]即可。

 {11,0,4,6,23,5,2,18,7,7}
 {11,0,4,6,7i,5,2,18,7,23j}
 {11,0,4,6,7,5,2,7j,18i,23}
 {7,0,4,6,7,5,2,11j,18i,23}

代码:

void swap(int& a,int& b)
{
    int temp=a;
    a=b;
    b=temp;
}

void quicksort2(int k[],int low,int high)
{
    if(low>=high) return;//如果没有记录或者只有一个记录
    
    int i=low;
    int j=high+1;
    int pivot=k[low];
    while(i<j)
    {
        i++;
        while(k[i]<pivot) i++;
        j--;
        while(k[j]>pivot) j--;
        if(i<j)
            swap(k[i],k[j]);
    }
    swap(k[low],k[j]);
    quicksort2(k,low,j-1);
    quicksort2(k,j+1,high);
} 

这两种写法不同,但思想是一样的。

平均复杂度均为O(nlogn) 在已经排序的序列中复杂度最高O(n2)

 

三:

三者取中快速排序:

因为每次划分成大小差不多的两个序列时算法效率更高,所以我们在k[low],k[(low+high)/2],k[high]中 寻找中间值 

void quicksort3(int k[],int low,int high)
{
    if(low>=high) return;

    //STEP1:选中间值元素 
    swap(k[(low+high)/2] ,k[low+1]);
    if(k[low+1]>k[high]) swap(k[low+1],k[high]);
    if(k[low]>k[high]) swap(k[low],k[high]);
    if(k[low+1]>k[low]) swap(k[low],k[low+1]);

    //STEP2:
    int i=low;
    int j=high+1;
    int pivot=k[low];
    while(i<j)
    {
        i++;
        while(k[i]<pivot) i++;
        j--;
        while(k[j]>pivot) j--;
        if(i<j)
            swap(k[i],k[j]);
    }
    swap(k[low],k[j]);
    quicksort3(k,low,j-1);
    quicksort3(k,j+1,high);
    
} 

 

法四:

非递归快速排序:

非递归算法需要一个堆栈,储存一些待排序的子文件。由于元素较少时,直接插入排序算法的效率比快速排序效率更高,所以可以选定一个常数M,当文件长度>=M时调用算法Part,否则采用直接插入排序。

 

 1 int part4(int k[],int low,int high)
 2 {
 3     
 4     //STEP1:选中间值元素 
 5     swap(k[(low+high)/2] ,k[low+1]);
 6     if(k[low+1]>k[high]) swap(k[low+1],k[high]);
 7     if(k[low]>k[high]) swap(k[low],k[high]);
 8     if(k[low+1]>k[low]) swap(k[low],k[low+1]);
 9 
10     //STEP2:
11     int i=low;
12     int j=high+1;
13     int pivot=k[low];
14     while(i<j)
15     {
16         i++;
17         while(k[i]<pivot) i++;
18         j--;
19         while(k[j]>pivot) j--;
20         if(i<j)
21             swap(k[i],k[j]);
22     }
23     swap(k[low],k[j]);
24     return j;    
25 } 
26 
27 
28 
29 void insertsort(int k[],int n)
30 {
31     for(int i=1;i<n;i++)
32     {
33         int j=i;
34         int temp=k[i];
35         while(i>0&&temp<k[j-1])
36         {
37             k[j]=k[j-1];
38             j--;
39         }
40         k[j]=temp;
41     }
42 }
43 
44 void quicksort4(int k[],int low,int high,int M)
45 {
46     stack<int>s;
47     int temp;
48     int n=high-low+1;
49     s.push(0);
50     s.push(0);
51     while(low < high)
52     {
53         int mid=part4(k,low,high);
54         if((mid-low<M) && (high-mid<M))
55         {
56             low=s.top(); s.pop();
57             high=s.top();s.pop();
58             continue;
59         }
60         if((mid-low<M)&&(high-mid>=M))
61         {
62             low=mid+1;continue;
63         }
64         if((mid-low>=M)&&(high-mid<M))
65         {
66             high=mid-1;continue;
67         }
68         if((mid-low>=M)&&(high-mid>=M))
69         {
70             if(mid-low>high-mid)
71             {
72                 s.push(mid-1);s.push(low);
73                 low=mid+1;
74             }
75             else
76             {
77                 s.push(high);s.push(mid+1);
78                 high=mid-1;
79             }
80         }
81     }
82     insertsort(k,n);
83 }

 

posted @ 2016-11-13 16:27  保暖婆婆  阅读(567)  评论(0编辑  收藏  举报