编程珠玑 ~~ 排序与随机整数序列

来源:互联网 发布:电脑温度查看软件 编辑:程序博客网 时间:2024/05/14 03:14

11. 排序算法

       插入排序:

       版本1:

#include<iostream>using namespace std; #define N 10 void swap(int &a, int &b){    int temp = a;    a = b;    b = temp;} int main(){    int array[N] = {3, 5, 23,53, 44, 22, 11, 8, 99, 77};    for(int i = 0; i < N;i++)    {        cout << array[i]<< " ";    }    cout << endl;     for(int i = 0; i < N;i++)    {        for(int j = i; j >0 && array[j -1] > array[j]; j--)        {            swap(array[j-1],array[j]);        }    }     for(int i = 0; i < N;i++)    {        cout <<array[i]<< " ";    }    cout << endl;     return 0;}
 

版本2:

#include <iostream>using namespace std; #define N 10 int main(){    int array[N] = {3, 5, 23,53, 44, 22, 11, 8, 99, 77};    for(int i = 0; i < N;i++)    {        cout << array[i]<< " ";    }    cout << endl;     for(int i = 0; i < N;i++)    {        for(int j = i; j >0 && array[j -1] > array[j]; j--)        {            int temp =array[j-1];            array[j-1] =array[j];            array[j] = temp;        }    }     for(int i = 0; i < N;i++)    {        cout <<array[i]<< " ";    }    cout << endl;     return 0;} 版本3:#include <iostream>using namespace std; #define N 10 int main(){    int array[N] = {3, 5, 23, 53, 44, 22, 11, 8,99, 77};    for(int i = 0; i < N;i++)    {        cout << array[i]<< " ";    }    cout << endl;    int t = 0;  int j = 0;    for(int i = 0; i < N;i++)    {        t = array[i];        for( j = i; j > 0&& array[j -1] > t; j--)        {            array[j] =array[j-1];        }        array[j] = t;    }     for(int i = 0; i < N;i++)    {        cout <<array[i]<< " ";    }    cout << endl;     return 0;}

       简单快速排序:

       版本1: 

#include <iostream>using namespace std; #define N 10 void swap(int &a, int &b){    int temp = a;    a = b;    b = temp;} void qsort1(int array[], int l, int u){    if( l >= u)    {        return ;    }     int m = l;    for( int i = l + 1; i<= u; i++)    {        if(array[i] <array[l])        {            swap(array[++m],array[i]);        }    }    swap(array[l], array[m]);     qsort1(array, l, m-1);    qsort1(array, m+1, u);} int main(){    int array[N] = {3, 5, 23,53, 44, 22, 11, 8, 99, 77};    for(int i = 0; i < N;i++)    {        cout << array[i]<< " ";    }    cout << endl;     qsort1(array, 0, N-1);     for(int i = 0; i < N;i++)    {        cout << array[i]<< " ";    }    cout << endl;     return 0;}

       版本2:从末尾向开始进行循环,将循环后的swap删除

#include<iostream>using namespace std; #define N 10 void swap(int &a, int &b){    int temp = a;    a = b;    b = temp;} void qsort1(int array[], int l, int u){    if( l >= u)    {        return ;    }     int m = u+1;    // 将x[l]作为哨兵    int t = array[l];    for( int i = u; i >= l; i--)    {        if(array[i] >= t)        {            swap(array[--m],array[i]);        }    }    // swap(array[l],array[m]);     qsort1(array, l, m-1);    qsort1(array, m+1, u);} int main(){    int array[N] = {3, 5, 23,53, 44, 22, 11, 8, 99, 77};    for(int i = 0; i < N;i++)    {        cout << array[i]<< " ";    }    cout << endl;     qsort1(array, 0, N-1);     for(int i = 0; i < N;i++)    {        cout << array[i]<< " ";    }    cout << endl;     return 0;}

       附注:

#include<iostream>using namespace std; #define N 10 void swap(int &a, int &b){    int temp = a;    a = b;    b = temp;} void qsort1(int array[], int l, int u){    if( l >= u)    {        return ;    } int m = u+1;    int i = u+1;    int t = array[l];      do{        while(array[--i] <t)                     ;swap(array[--m], array[i]);}while( i != l)     qsort1(array, l, m-1);    qsort1(array, m+1, u);} int main(){    int array[N] = {3, 5, 23,53, 44, 22, 11, 8, 99, 77};    for(int i = 0; i < N;i++)    {        cout << array[i]<< " ";    }    cout << endl;     qsort1(array, 0, N-1);     for(int i = 0; i < N;i++)    {        cout << array[i]<< " ";    }    cout << endl;     return 0;}

       版本3:本版本主要是解决快速排序在待排序数组中的元素相同元素居多时,性能急剧下降而给出的。

#include<iostream>using namespace std; #define N 10 void swap(int &a, int &b){    int temp = a;    a = b;    b = temp;} void qsort3(int array[], int l, int u){    if( l >= u)    {        return ;    }     int t = array[l];    int i = l; int j = u + 1;    do    {        do{ i++; }while( i<= u && array[i] < t);        do{ j--; }while( j>= i && array[j] > t);        if( i > j)        {            break;        }        swap(array[i],array[j]);    }while(1);    swap(array[l], array[j]);     qsort3(array, l, j-1);    qsort3(array, j+1, u);} int main(){    int array[N] = {3, 5, 23,53, 44, 22, 11, 8, 99, 77};    for(int i = 0; i < N;i++)    {        cout << array[i]<< " ";    }    cout << endl;     qsort3(array, 0, N-1);     for(int i = 0; i < N;i++)    {        cout << array[i]<< " ";    }    cout << endl;     return 0;}

       版本4:将swap函数展开到程序中,而不使用函数调用

#include<iostream>using namespace std; #define N 10      void qsort3(int array[], int l, int u){    if( l >= u)    {        return ;    }     int t = array[l];    int i = l; int j = u + 1;    do    {        do{ i++; }while( i<= u && array[i] < t);        do{ j--; }while( j>= i && array[j] > t);        if( i > j)        {            break;        }        int temp = array[i];array[i] = array[j];array[j] = temp;    }while(1);    int temp = array[l];array[l] = array[j];array[j] = temp;     qsort3(array, l, j-1);    qsort3(array, j+1, u);} int main(){    int array[N] = {3, 5, 23,53, 44, 22, 11, 8, 99, 77};    for(int i = 0; i < N;i++)    {        cout << array[i]<< " ";    }    cout << endl;     qsort3(array, 0, N-1);     for(int i = 0; i < N;i++)    {        cout << array[i]<< " ";    }    cout << endl;     return 0;}

       补充:

       2.将x[l]用作标记值来提高Lomuto的划分方法的效率,说明该方法是如何在循环之后将swap移除的。

       两种方法:从u开始循环

       代码详解版本2中两个方法

      

       9.编写程序,让该程序在O(n)时间内从数组x[0..n-1]中找出第k个最小的元素,你的算法可以排列x的元素

      

       使用快速排序中的一步排序,最终将第k大的数字排到它自己的位置上。

       注:注意在程序中,第k大时,调用函数传递的应该是k-1。与写的代码有关系

#include<iostream>using namespacestd; #define N 10 void swap(int&a, int &b){    int temp = a;    a = b;    b = temp;}  voidselectKth(int array[], int l, int u, int k){    if( l >= u)    {        return ;    }     int t = array[l];    int i = l; int j = u + 1;    do    {        do{ i++; }while( i <= u &&array[i] < t);        do{ j--; }while( j >= i &&array[j] > t);        if( i > j)        {            break;        }        swap(array[i], array[j]);    }while(1);    swap(array[l], array[j]);    if( j < k)    {        selectKth(array, j+1, u, k);    }    else if( j > k)    {        selectKth(array, l, j-1, k);    }} int main(){    int array[N] = {3, 5, 23, 53, 44, 22, 11,8, 99, 77};    for(int i = 0; i < N; i++)    {        cout << array[i] << "";    }    cout << endl;     selectKth(array, 0, N-1, 2);    cout << "The three big: "<< array[3] << endl;     return 0;}

12. 抽样问题

       问题:给出1 – K 内的M个随机的不重复整数

       解决方法:

       1.使用标准库的集合容器,实现1~K内的随机的无重复M个整数。

       Initializeset S to empty

       size= 0

       whilesize < m do

              t= bigrand() % n

              ift is not in S

                     insertt into S

                     size++

       printthe elements of S in Sorted Orger

      

       这个方法主要是使用了集合中不会插入重复的数字

      

       2.产生随机整数排序子集的另外一个方法是将一个K个元素的数组打乱,这个数组中前M个元素输出,即我们要的不重复的M个整数。

       fori = [0, n)

              swap(i, randint( i, n-1));

      

       其实这个只需要扰乱前M个数字即可,不需要将整个数组都打乱。

      

补充:

       1.一般的C库中的rand()函数大概随机返回15个随机位,使用该函数实现函数bigrand(),使其返回30个随机位,并实现randint(l, u)。

intbigrand(){return RAND_MAX * rand() + rand();} int randint(){return l + bigrand() % ( u – l + 1);}

       9.当m接近n时,基于集合的算法会产生很多集合中早就存在的整数,因此需要去掉这些整数,你能写一个算法,即便是在最差的情况下,该算法只需要m个随机数值?

       可以选择 n – m个随机数,然后让最终得到的集合中排出这几个数字即可。这样得到的大部分数据都是可用的,而不会出现题目的问题。(这是一个思维的问题)

 

 

13. 堆排序

       对操作中两个关键的函数:两个函数主要用于修补在一端或另一端中断的堆属性,两个函数的效率都较高,大概是log n步来重新组织具有n个元素的堆。

       Siftup:将位于n的元素沿着树向上调整到适当的位置。

void Siftup( int array[], int n){    int i = n;    int p = 0;    while(1)    {        if(i == 1)        {            break;        }         p = i / 2;        if(array[p] <=array[i])        {            break;        }        swap(array[p],array[i]);        i = p;    }}


 

       Siftdown:将位于n的元素沿着树向下调整到适当的位置。

void Siftdown(int array[], int n){    int i = 1;    int c = 0;    while(1)    {        c = 2 * i;        if(c > n)        {            break;        }         if( c+1 <= n)        {            if(array[c+1] <array[c])            {                c++;            }        }         if(array[i] <=array[c])        {            break;        }         swap(array[c],array[i]);        i = c;    }}

       使用的swap()方法:    

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

优先队列:

       C++写的一个简单的优先级队列:

#include <iostream> using namespace std; template <typename T>class priqueque{public:    priqueque(int m);    ~priqueque();    void insert(T t);    T extractmin();private:    void swap(int i, int j)    {        T t = x[i]; x[i] =x[j]; x[j] = t;    }private:    int n;    int maxsize;    T *x;}; template <typename T>priqueque<T>::priqueque(int m){    maxsize = m;    x = new T[maxsize+1];    n = 0;} template <typename T>priqueque<T>::~priqueque(){    delete [] x;} template <typename T>void priqueque<T>::insert(T t){    int i, p;    x[++n] = t;    for( i = n; i > 1&& x[p=i/2] > x[i]; i = p)    {        swap(p, i);    }} template <typename T>T priqueque<T>::extractmin(){    int i, c;    T t = x[1];    x[1] = x[n--];    for( i = 1; (c= 2*i) <n; i = c)    {        if(c+1 <= n&& x[c+1] < x[c])            c++;        if(x[i] <= x[c])            break;        swap(c, i);    }     return t;} int main(){    priqueque<int>intQ(10);     intQ.insert(1);    intQ.insert(2);    intQ.insert(3);    intQ.insert(4);    intQ.insert(5);    intQ.insert(6);    intQ.insert(7);    intQ.insert(8);     cout <<intQ.extractmin() << endl;    cout <<intQ.extractmin() << endl;    cout <<intQ.extractmin() << endl;    cout << intQ.extractmin()<< endl;    cout <<intQ.extractmin() << endl;    cout <<intQ.extractmin() << endl;    cout <<intQ.extractmin() << endl;    cout << "Helloworld!" << endl;    return 0;}

       使用两个函数所形成的快速排序方法:

#include <iostream> using namespace std; void swap(int &a, int &b){    int temp = a;    a = b;    b = temp;} void Siftup( int array[], int n){    int i = n;    int p = 0;    while(1)    {        if(i == 1)        {            break;        }         p = i / 2;        if(array[p] <=array[i])        {            break;        }        swap(array[p],array[i]);        i = p;    }} void Siftdown(int array[], int n){    int i = 1;    int c = 0;    while(1)    {        c = 2 * i;        if(c > n)        {            break;        }         if( c+1 <= n)        {            if(array[c+1] <array[c])            {                c++;            }        }         if(array[i] <=array[c])        {            break;        }         swap(array[c],array[i]);        i = c;    }} void HeapSort( int array[], int n){    for( int i = 2; i <= n;i++)    {        Siftup(array, n);    }    for( int i = n; i >= 2;i--)    {        swap( array[1],array[i]);        Siftdown( array, i -1);    }} #define N 10 int main(){    int array[N+1] = {0, 3, 5,23, 34, 11, 66, 89, 43, 9, 10};    for( int i = 1; i < N +1; i++)    {        cout << array[i]<< "  ";    }    cout << endl;     HeapSort(array, N);     for( int i = 1; i < N +1; i++)    {        cout << array[i] << "  ";    }    cout << endl;    return 0;}


14. 字符串(略)

原创粉丝点击