感觉学校算法课挺水的,不过编程这东西还是要靠自己想,自己琢磨,老师也只能帮你指引下。菜鸟我还是好好敲代码吧。。。。
计数排序:其他排序方法都是依靠元素之间的比较从而产生次序,而计数排序是依靠元素计算,得出自己在序列中的位置
//计数排序(设元素均为非负整数)
#include <iostream>
#include <memory.h>
using namespace std;
const int maxn = 50;
int Size = 8;
int a[maxn] = {2,5,3,0,2,3,0,3};
int b[maxn];//存储最后排列顺序
int c[maxn];//c[lp...rp],lp,rp应分别对应数组 最小和最大值,即lp <= min(a),rp >= max(a)
//c[i]代表 <= i元素个数,即i在排序后的位置
void counting_sort()
{
memset(c,0,sizeof(c));
memset(b,-1,sizeof(b));
for(int i = 0;i < Size;i++)
c[a[i]]++;
for(int i = 1;i < Size;i++)
c[i] += c[i - 1];
for(int i = 0;i < Size;i++)
{
b[c[a[i]]] = a[i];
c[a[i]]--;
}
}
int main()
{
freopen("out.txt","w",stdout);
counting_sort();
for(int i = 0;i < maxn;i++)
if(-1 != b[i])
cout<<b[i]<<" ";
return 0;
}
归并排序:使用分治的思想,将n个元素的序列分解为两个(n / 2 )大小的子序列(分解步奏),继续使用归并排序排列两个子序列(分治解决),最后将两个排序后的序列合并(关键步骤)
#include <iostream>
#include <math.h>
using namespace std;
const int maxn = 0x7fffffff;
const int size = 8;
int a[size] = {5,2,4,7,1,3,2,6};
void merge(int p,int q,int r)
{
int n1 = q - p + 1;
int n2 = r - q;
int la[size],ra[size];
for(int i = 1;i <= n1;i++) //p ----- q
la[i] = a[p + i - 1];
for(int i = 1;i <= n2;i++) //q + 1 ------ r
ra[i] = a[q + i];
la[n1 + 1] = maxn;
ra[n2 + 1] = maxn;
int i,j;
i = j = 1;
for(int k = p;k <= r;k++)
{
if(la[i] <= ra[j])
{
a[k] = la[i];
i++;
}
else
{
a[k] = ra[j];
j++;
}
}
}
void merge_sort(int p,int r)
{
if(p < r)
{
int q = (p + r) / 2;
merge_sort(p,q);
merge_sort(q + 1,r);
merge(p,q,r);
}
}
int main()
{
freopen("out.txt","w",stdout);
merge_sort(0,7);
for(int i = 0;i < size;i++)
cout<<a[i]<<endl;
return 0;
}
堆排序,大(小)顶堆可以近似的看成是一棵完全二叉树,除了最低层外,该树是全满的。所以很容易用一维数组存储完全二叉树。堆排中关键的地方在于维护好堆的性质,即a[parent(i)] >= a[i] (大顶堆) a[parent(i)] <= a[i] (小顶堆)
堆的一个重要的应用是构造优先队列,虽然STL中有了优先队列的模板,但了解其原理总没有什么坏处。
//大顶堆
#include <iostream>
#include <cstdio>
#include <cstdlib>
using namespace std;
const int maxn = 100;
int a[maxn] = {0,4,1,3,2,16,9,10,14,8,7};//从1开始存储
int Size = 10;//排序元素数量
void heapify(int num)//对下标num元素构造堆
{
int largest = num;
int lp = num * 2;
int rp = lp + 1;
if(lp <= Size && a[lp] > a[num])
largest = lp;
if(rp <= Size && a[rp] > a[largest])
largest = rp;
if(largest != num)
{
swap(a[num],a[largest]);
heapify(largest);
}
}
void build_heap()
{
if(Size != 0)
{
for(int i = Size / 2;i >= 1;i--)
heapify(i);
}
}
void heap_sort()
{
build_heap();
for(int i = Size;i >= 1;i--)
{
cout<<a[1]<<" ";
swap(a[1],a[Size]);
Size--;
heapify(1);
}
}
int main()
{
freopen("out.txt","w",stdout);
heap_sort();
return 0;
}
快速排序:快速排序也使用了分治的思想,序列a[p...r]被划分为两个子序列a[p...q-1] 和 a[p + 1....r],使得a[p...q - 1] <= a[q],a[q + 1...r]均大于a[q]。
#include <iostream>
#include <cstdio>
#include <cstdlib>
using namespace std;
const int maxn = 50;
int a[maxn] = {2,8,7,1,3,5,6,4};
int Size = 8;
//两种划分方法,感觉后一种效率高些
/*
int partition(int p,int r)//以a[r]为基准元素比较
{
int tmp = a[r];
int i = p - 1;
for(int j = p;j < r;j++)
{
if(a[j] < tmp)
{
i++;
swap(a[i],a[j]);
}
}
swap(a[i + 1],a[r]);
return i + 1;
}
*/
int partition(int lp,int rp)
{
int tmp = a[rp];
while(lp < rp)
{
while(a[lp] <= tmp && lp < rp)
lp++;
a[rp] = a[lp];
while(a[rp] >= tmp && lp < rp)
rp--;
a[lp] = a[rp];
}
a[lp] = tmp;
return lp;
}
void quick_sort(int p,int r)
{
if(p < r)
{
int pos = partition(p,r);
quick_sort(p,pos - 1);
quick_sort(pos + 1,r);
}
}
int main()
{
freopen("out.txt","w",stdout);
quick_sort(0,7);
for(int i = 0;i < Size;i++)
cout<<a[i]<<" ";
return 0;
}