小四的海市蜃楼
Never surrender to complexity
posts - 21,comments - 59,trackbacks - 0

在程序设计实践上看到这个简单的快速排序,用模板重新写了一遍,加深一下印象。平均算法复杂度为O(nlogn)。

其中寻找支点元素pivot有多种方法,不同的方法会导致快速排序的不同性能。根据分治法平衡子问题的思想,希望支点元素可以使p[m..n]尽量平均地分为两部分,但实际上很难做到。下面给出几种寻找pivot的方法。

1.选择p[m..n]的第一个元素p[m]的值作为pivot;
2.选择p[m..n]的最后一个元素p[n]的值作为pivot;
3.选择p[m..n]中间位置的元素p[k]的值作为pivot;
4.选择p[m..n]的某一个随机位置上的值p[random(n-m)+m]的值作为pivot;
  按照第4种方法随机选择pivot的快速排序法又称随机化版本的快速排序法,在实际应用中该方法的性能也是最好的。本程序使用第4种方法。要求节点类型支持比较运算符。


template<typename T>
void quicksort(T* v, int n)
{
    
if (n<=1)
        
return;
    
int last = 0;
    
int pivot = rand()%n;
    swap(v, 
0, pivot);
    
for (int i = 1; i < n; i++)
    
{
        
if (v[i]<v[0])
            swap(v, 
++last, i);
    }

    swap(v, last, 
0);
    quicksort(v, last);
    quicksort(v
+last+1, n-last-1);
}


template
<typename T>
void swap(T* v, int i, int j)
{
    T tmp 
= v[i];
    v[i] 
= v[j];
    v[j] 
= tmp;    
}


随手写一个不太好看的测试程序

struct str
{
    str(
const char* a)
    
{
        assert(a);
        v 
= new char[strlen(a)+1];
        strcpy(v, a);
    }

    str(
const str& a)
    
{
        assert(a.v);
        v 
= new char[strlen(a.v)+1];
        strcpy(v, a.v);
    }

    
~str()
    
{
        delete [] v;
    }

    
void operator = (const str& a)
    
{
        
if (this == &a)
            
return;
        assert(a.v);
        delete [] v;
        v 
= new char[strlen(a.v)+1];
        strcpy(v, a.v);
    }

    
bool operator == (const str& a) const
    
{
        
return (strcmp(v, a.v)==0);
    }

    
bool operator > (const str& a) const 
    
{
        
return (strcmp(v, a.v)>0);
    }

    
bool operator < (const str& a) const
    
{
        
return (strcmp(v, a.v)<0);
    }

    
char* v;
}
;


int main(int argc, char* argv[])
{
    
int* array = new int [10];
    
for(int i = 0; i < 10; i++)
        array[i] 
= rand();
    quicksort(array, 
10);
    
for(i = 0; i < 10; i++)
    
{
        cout
<<array[i]<<endl;
    }


    str s[] 
= {"bd""e""ba""a"};
    quicksort(s, 
4);
    
for(i = 0; i < 4; i++)
    
{
        cout
<<s[i].v<<endl;
    }

    
return 0;
}


posted on 2007-12-29 14:31 小四 阅读(380) 评论(0)  编辑 收藏 引用 所属分类: 算法与数据结构

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理