您的位置:首页 > 其它

排序

2016-05-10 21:02 190 查看
[align=center][/align]

我的所有的排序算法都写在一个cpp文件里面了,所以日记也不分开每种都介绍了。

排序只要分为:

基于关键字比较的:插入排序(直接插入排序和希尔排序),交换排序(冒泡和快速排序),选择排序(直接选择和堆排序),合并排序等。

不基于关键字比较的:分布排序。

其中,广泛应用的是快速排序。

几种排序算法是:直接插入,选择插入排序,冒泡排序,希尔排序,快速排序(递归和不递归的),二路归并排序,堆排序,基数排序,分布排序

用到的一些头文件,以后再传。主要是几种数据结构链表队列栈二叉树等等的类

写得不好的或者有错误的请指正了,感激不尽………

-------------------------头文件
const int MaxNum = 8;//大于八位不支持,用于基数排序
class Element
{
public:
int GetKey() const {return key;}
void SetKey(int k) {key = k;}
//------基数排序专用
int GetKey(int n) ;//返回某位的数值eg :120返回GetKey(1) = 1;
void SetKey(int k, int n); //设置某位的数值
//设置所有的数值,number表示位数,默认radix为10吧--
void SetKeyB(int key, const int  number)
{
const int radix = 10;
int power = 0;
int j = 0;
//最后一位先不进行计算
for (int i = 1; i < number; i ++)
{
for (j = 1; j <= number-i;  j ++)
{
power *= radix;
}
keys[i] = key/power;
keys[i] = keys[i]%radix;
}
//设置最后一位
keys[i] = keys[i]%radix;
for (int k = i + 1; k < MaxNum+1; k++)
keys[k] = 0;
}

private:
int key;
public:
//-------基数排序专用
int link; //用于基数排序,指向下一个元素
int keys[MaxNum+1] ;//关键字的位数,基数排序只针对整数 =。=
};

-------------------------cpp文件
#include "Sort.h"
#include "LStack.h"
const int k0 = 0;
const int M = 8; //大于M采用快速排序  小于M采用插入排序
void Interchange(Element *list, int m, int n)
{
Element temp;
temp = list[m];
list[m] = list
;
list
= temp;
}
//直接插入排序 k0为最小值
void InsertSortA(Element *list, int n)
{
Element e;
int i;
list[0].SetKey(k0);
for (int j = 2; j <= n; j++)
{
e = list[j];
i = j-1;
while(e.GetKey() < list[i].GetKey())
{
list[i+1] = list[i];
i --;
}
list[i+1] = e;
}
}

//冒泡排序
void Bubble(Element *R, int n)
{
int bound, j, t;
Element e;
bound = n;
while(bound)
{
t = 0;
for(j = 1; j < bound; j++)
if (R[j].GetKey() > R[j+1].GetKey())
{
e = R[j];
R[j] = R[j+1];
R[j+1] = e;
}
t = j;
bound = t;
}
}
//直接选择排序
void SSort(Element *R, int n)
{
int t;
Element e;
for (int j = n; j >= 2; j--)
{
t = 1;
for (int i = 2; i <= j; i ++)
{
if (R[t].GetKey() < R[i].GetKey())
t = i;
}
e = R[t];
R[t] = R[j];
R[j] = e;
}
}
//shell排序
void ShellSort(Element *list, int n)
{
int gap = n;
int i;
Element e;
int t;
while(gap >= 1)
{
gap = gap/2;
for(i = 1; i <= gap; i ++)
{
for(int j = i+gap; j <= n; j = j+gap)
{
e = list[j];
t = j - gap;
while(e.GetKey() < list[t].GetKey())
{
list[t+gap] = list[t];
t = t - gap;
if (t <= i)
break;
}
}
list[t+gap] = e;
}
}
}
//二路归并算法sourcelist[t...m]和sourcelist[m+1.....n]都已经排序好,把他们合并到mergedlist[t...n]
void merge(Element *sourcelist, Element *mergedlist, const int t, const int m, const int n)
{
int i, j, k;
i = t;
j = m+1;
k = t;
while(i <= m && j <= n)
{
if (sourcelist[i].GetKey() <= sourcelist[j].GetKey())
{
mergedlist[k] = sourcelist[i];
i ++;
}
else
{
mergedlist[k] = sourcelist[j];
j ++;
}
k ++;
}
if (i > m)
{
for(int p = k; p <= n; p++)
mergedlist[p] = sourcelist[j+p-k];
}
else
{
for(int p = k; p <= n; p++)
mergedlist[p] = sourcelist[i+p-k];
}
}
//一趟合并算法
void MPass(Element *sourcelist, Element *mergedlist, const int n, int length)
{
for (int j = 1; j <= n-2*length+1; j += 2*length)
merge(sourcelist, mergedlist, j, j+length-1, j+2*length-1);
if (j+length < n)
merge(sourcelist, mergedlist, j, j+length-1, n);
else
for(int p = j; p <= n; p ++)
mergedlist[p] = sourcelist[p];
}
//直接二路合并算法
void Msort(Element *list, const int n)
{
Element *templist = new Element[n+1];
for (int j = 1; j < n; j *= 2)
{
MPass(list, templist, n ,j);
j *= 2;
MPass(templist, list, n, j);
}
delete [] templist;
}
//快速排序的递归算法,第m个位置的关键字作为分划的关键字k
//R[m...n]对进行排序
void QSort(Element *R, int m, int n)
{
int i, j, k, temp;
if (m < n)
{
i = m;
j = n + 1;
k = R[m].GetKey();
while(i < j)
{
i ++;
while(R[i].GetKey() < k) i++;
j --;
while(R[j].GetKey() > k) j--;
if (i < j)
{
temp = R[i].GetKey();
R[i].SetKey(R[j].GetKey());
R[j].SetKey(temp);
}
}
temp = R[m].GetKey();
R[m].SetKey(R[j].GetKey());
R[j].SetKey(temp);
QSort(R, m, j-1);
QSort(R, j+1, n);
}
}
//分划方法,取位置的中间值,相当于设置QSort(Element *R, int m, int n)的m值
int Part(Element *list, int m, int n)
{
int i, j, k;
Interchange(list, (int)(m+n)/2, m+1);
if (list[m+1].GetKey() > list
.GetKey())Interchange(list, m+1, n);
if (list[m].GetKey() > list
.GetKey())Interchange(list, m, n);
if (list[m+1].GetKey() > list[m].GetKey())Interchange(list, m+1, m);
i = m;
j = n+1;
k = list[m].GetKey();
while(i < j)
{
i ++;
while(list[i].GetKey() < k) i ++;
j--;
while(list[j].GetKey() > k) j --;
if (i < j)Interchange(list, i, j);
}
Interchange(list, m, j);
return j;
}
//快速排序的非递归算法
struct stacktype
{
int x;
int y;
};
void HSort(int n, Element *R, int M)
{
LStack<stacktype> stackptr;
stacktype temp;
int f, t, j;
temp.x = temp.y = 0;
stackptr.Push(temp);
f = 1;
t = n;
while (f < t)
{
j = Part(R, f, t);
if ((j-f < M) && (t-j < M))
{
stackptr.Pop(temp);
f = temp.x;
t = temp.y;
continue;
}
if ((j-f < M) && (t-j >= M))
{
f = j + 1;
continue;
}
if ((j-f >= M) && (t-j < M))
{
t = j - 1;
continue;
}
if ((j-f >= M) && (t-j >= M))
{
if (j-f > t-j)
{
temp.x = f;
temp.y = j - 1;
stackptr.Push(temp);
f = j + 1;
}
else
{
temp.x = j + 1;
temp.y = t;
stackptr.Push(temp);
t = j - 1;
}
}
}
InsertSortA(R, n);
}
//重建堆tree[root]的二叉树,结点个数为n
void Restore(Element *tree, int root, const int n)
{
int m;
int j = root;
while(j <= (int)(n/2))
{
if ((2*j < n) && (tree[2*j].GetKey() < tree[2*j + 1].GetKey()))
m = 2*j + 1;
else
m = 2 * j;
//父节点关键值小于孩子结点的关键值
if (tree[j].GetKey() < tree[m].GetKey())
{
//将孩子结点关键值大的交换到父节点
Interchange(tree, j, m);
j = m;
}
else
j = n;
}
}
//堆排序R[1...n]
void HeapSor(Element *R, const int n)
{
int i;
for(i = n/2; i >= 1; i--)
Restore(R, i, n);
for (i = n; i > 1; i--)
{
Interchange(R, 1, i);
Restore(R, 1, i-1);
}
}
//基数排序
//radix为基数 p个关键字的位数key[0...p-1] n个待排序列list[1...n]
void RadixSort(Element *list, const int n, const int p, const int radix)
{
//指向表示桶的每个队列的队头和队尾
int *start = new int[radix];
int *end = new int[radix];
//建立初始链表
for (int j = 1; j < n; j ++)list[j].link = j + 1;
list
.link = 0;
int current = 1;
int k = 0;
int last;
//从低位开始依次按子关键词key[i]排序
for (int i = p-1; i >= 0; i--)
{
//初始化队列表头
for (j = 0; j < radix; j++)start[j] = 0;
while(current)
{
k = list[current].GetKey(i);
if (!start[k]) start[k] = current;
else list[end[k]].link = current;
end[k] = current;
current = list[current].link;
}
//寻找第一个非空队列
for (j = 0; start[j] == 0; j++);
current = start[j];
last = end[j];
for(int k = j+1; k < radix; k++)
{
if (start[k])
{
list[last].link = start[k];
last = end[k];
}
}
list[last].link = 0;
}
delete [] start;
delete [] end;
}

//分布计数排序算法,count[i]为相应位置的大小
//对R[1...n]文件进行排序  关键字:最小值指是u,最大值是v
void Distribute(Element *R, Element *S, const int n, const int u, const int v)
{
int i, j;
int *count = new int[v-u+1];
for (i = u; i <= v; i++) count[i-u] = 0;
for (j  = 1; j <= n; j++)count[R[j].GetKey()-u]++;
for (i = u+1; i <= v; i++)count[i-u] += count[i-u-1];
for (j = n; j >= 1; j --)
{
i = count[R[j].GetKey()-u];
S[i] = R[j];
count[R[j].GetKey()-u] --;
}
delete [] count;
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: