排序

我的所有的排序算法都写在一个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[n];
 list[n] = 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[n].GetKey())Interchange(list, m+1, n);
 if (list[m].GetKey() > list[n].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[n].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;
}


你可能感兴趣的:(排序)