您的位置:首页 > 编程语言

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

2013-07-16 15:43 281 查看
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
= {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
= {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
= {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
= {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
= {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
= {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
= {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
= {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
= {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. 字符串(略)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐