现在的位置: 首页 > 综合 > 正文

常用排序算法的简单实现

2013年09月09日 ⁄ 综合 ⁄ 共 6578字 ⁄ 字号 评论关闭

数据结构的一次实验。。。。

/*******************************************************************

   文件名: SortDemo.h
   摘要: 类SortDemo的申明文件,该类可以对整型数组进行排序
   开发平台: Win Xp SP2
   编译环境: CL.exe 8.0 (in Visual Studio 2005 SDK)
   作者: 88250
   完成日期: 2006-12-25    版本: 1.0
   Blog: http://DL88250.ynutx.net
   E-mail: DL88250@gmail.com
   QQ: 845765 or 316281008
               
 *******************************************************************/

#include <iostream>
#include <ctime>

using namespace std;
const int MAX_NUM = 25;  // 可以进行排序的最多元素

class SortDemo
{
 public:
  // 显示数组序列
  void DisplaySerial(const int *r){
   for (int i = 1; i < MAX_NUM; i++)
   {
    cout << *(r+i) << ' ';
   }
   cout << endl;
  }
  // 快速排序
  void QSort(int *r, int low, int high);
  // 堆排序
  void HSort(int *r);
  // 直接插入排序
  void ISort(int *r);
  // 归并排序
  void MSort(int *r);

 private:
  // 用于快速排序,拆分一个数组
  int Partition(int *r, int low, int high);
  // 用于堆排序,做一个向下筛选
  void SiftDown(int *r, int begin, int end);
  // 用于归并排序,将sr[s..t]归并排序为sr[s..t]
  void MergeSort(int *sr, int s, int t);
  // 用于归并排序,将有序的sr[i..m]和sr[m+1..n]归并为有序的sr[i..n]
  void Merge(int *sr, int i, int m, int n);

};
/*******************************************************************

   文件名: HeapSort.cpp
   摘要: 堆排序的C++实现
   开发平台: Win Xp SP2
   编译环境: CL.exe 8.0 (in Visual Studio 2005 SDK)
   作者: 88250
   完成日期: 2006-12-25    版本: 1.0
   Blog: http://DL88250.ynutx.net
   E-mail: DL88250@gmail.com
   QQ: 845765 or 316281008
               
 *******************************************************************/

#include "stdafx.h"
#include "SortDemo.h"

// 函数名:SiftDown
// 功能:用于堆排序,做向下筛选,使r[s...m]成为一个大根堆
// 输入参数:int *r:待排序数组地址
//      int s:r[s]不满足堆的定义
//      int m:r数组的最大边界
// 输出参数:void
void SortDemo::SiftDown(int *r, int s, int m)
{
 int tmp = r[s];
 
 int i = s; 
 int j = 2 * i;  // r[j]是r[i]的左孩子
 while (j <= m)
 {
  if ((j < m) && (r[j] < r[j+1]))
  {// 右孩子较大,则把j修改为右孩子的下标
   j++;
  }
    
  if (tmp < r[j])
  {
   r[i] = r[j]; // 将R[j]调到父亲的位置上
   i = j;
   j = 2 * i; 
  }
  else
  {// 筛选完成,跳出循环
   break;
  }
 }
 r[i] = tmp; // 被筛结点的值放入最终位置

 return;
}

// 函数名:HSort
// 功能:将r数组进行堆排序
// 输入参数:int *r:待排序数组地址
// 输出参数:void
void SortDemo::HSort(int *r)
{
 int temp = 0;
 // 建堆
 for (int i = MAX_NUM / 2; i >= 1; i--)
 {
  SiftDown(r, i, MAX_NUM - 1);
 }
 // 堆排序
 for (int i = MAX_NUM - 1; i >= 2; i--)
 {
  temp = r[1];
  r[1] = r[i];
  r[i] = temp;  // 将第一个元素同当前区间内最后一个元素对换
  SiftDown(r, 1, i - 1); // 筛选r[1]结点,得到(i-1)个结点的堆
 }

 return;
}

/*******************************************************************

   文件名: InsertSort.cpp
   摘要: 直接插入排序的C++实现
   开发平台: Win Xp SP2
   编译环境: CL.exe 8.0 (in Visual Studio 2005 SDK)
   作者: 88250
   完成日期: 2006-12-25    版本: 1.0
   Blog: http://DL88250.ynutx.net
   E-mail: DL88250@gmail.com
   QQ: 845765 or 316281008
               
 *******************************************************************/

#include "stdafx.h"
#include "SortDemo.h"

void SortDemo::ISort(int *r)
{
 int j = 0;

 for (int i = 2; i < MAX_NUM; i++)
 {
  if (r[i] < r[i-1])
  {
   r[0] = r[i];  // 复制为哨兵
   r[i] = r[i-1];
  }
  for (j = i - 2; r[0] < r[j]; --j)
  {
   r[j+1] = r[j];  // 记录后移
  }
  r[j+1] = r[0];   // 插入到正确位置
 }

 return;
}

/*******************************************************************

   文件名: MergeSort.cpp
   摘要: 归并排序的C++实现
   开发平台: Win Xp SP2
   编译环境: CL.exe 8.0 (in Visual Studio 2005 SDK)
   作者: 88250
   完成日期: 2006-12-25    版本: 1.0
   Blog: http://DL88250.ynutx.net
   E-mail: DL88250@gmail.com
   QQ: 845765 or 316281008
               
 *******************************************************************/

#include "stdafx.h"
#include "SortDemo.h"

// 函数名:MSort
// 功能:将数组r进行归并排序
// 输入参数:int *sr:待排序数组地址
// 输出参数:void
void SortDemo::MSort(int *r)
{
 MergeSort(r, 1, MAX_NUM-1);
 return;
}
 
// 函数名:MergeSort
// 功能:用于归并排序,将sr[s..t]归并排序为tr1[s..t]
// 输入参数:int *sr:待排序数组地址
//      int s:下标s
//      int t:下标t
void SortDemo::MergeSort(int *sr, int s, int t)
{
 if (s < t)
 {
  int m = (s + t) >> 1; // 将sr[s..t]平分为sr[s..m]和sr[m+1..t]
  MergeSort(sr, s, m); // 递归地将sr[s..t]归并为有序的sr[s..m]
  MergeSort(sr, m+1, t); // 递归地将sr[m+1..t]归并为有序的sr[m+1..t]
  Merge(sr, s, m, t); // 将sr[s..m]和sr[m+1..t]归并到sr[s..t]
 }  

 return;
}

// 函数名:Merge
// 功能:用于归并排序,将有序的sr[i..m]和sr[m+1..n]归并为有序的sr[i..n]
// 输入参数:int *sr:待排序数组地址
//      int i:low下标
//      int m:mid下标
//      int n:high下标
void SortDemo::Merge(int *sr, int i, int m, int n)
{
 
 int j = i, k = m + 1, p = 0;

 int *tr = new int[n-i+1]; // 辅助空间

 while ((j <= m) && (k <= n))
 {// 将sr中记录由小到大地并入tr
  tr[p++] = (sr[j] <= sr[k]) ? sr[j++]:sr[k++];
 }
 while (j <= m)
 {// 将剩余的sr[i..m]复制到tr
  tr[p++] = sr[j++];
 }
 while (k <= n)
 {// 将剩余的sr[j..n]复制到tr
  tr[p++] = sr[k++];
 }
 // 将有序结果返回到sr
 for (j = i, p = 0; j <= n; j++, p++)
 {
  sr[j] = tr[p];
 }

 return;
}
/*******************************************************************

   文件名: QSort.cpp
   摘要: 快速排序的C++实现
   开发平台: Win Xp SP2
   编译环境: CL.exe 8.0 (in Visual Studio 2005 SDK)
   作者: 88250
   完成日期: 2006-12-25    版本: 1.0
   Blog: http://DL88250.ynutx.net
   E-mail: DL88250@gmail.com
   QQ: 845765 or 316281008
               
 *******************************************************************/

#include "stdafx.h"
#include "SortDemo.h"

// 函数名:QSort
// 功能:快速排序
// 输入参数:int *r:待排序数组地址
//      int low:比枢轴小的记录下标
//           int high:比枢轴大的记录下标
// 输出参数:void
void SortDemo::QSort(int *r, int low, int high)
{
 if (low < high)
 {
  // 将表一分为二
  int pivot = Partition(r, low, high);
  QSort(r, low, pivot - 1); // 对低子表递归排序
  QSort(r, pivot + 1, high); // 对高子表递归排序
 }

 return;
}

// 函数名:Partition
// 功能:通过枢轴将r数组分为两个子表
// 输入参数:int *r:待排序数组地址
//      int low:比枢轴小的记录下标
//           int high:比枢轴大的记录下标
// 输出参数:void
int SortDemo::Partition(int *r, int low, int high)
{
 r[0] = r[low]; // 用子表的每一个记录作枢轴记录
 
 while (low < high)
 {// 从表的两端交替地向中间扫描
  while ((high > low) && (r[high] >= r[0]))
  {
   high--;
  }
  if (high > low)
  {
   r[low] = r[high]; // 将比枢轴记录小的记录移到低端
   low++;   // 跳过本身
  }
  while ((low < high) && (r[low] <= r[0]))
  {
   low++;
  }
  if (high > low)
  {
   r[high] = r[low]; // 将比枢轴记录大的记录移到高端
   high--;   // 跳过本身
 
  }
 }
 r[low] = r[0];   // 枢轴记录到位

 return low;   // 返回枢轴位置
}

/*******************************************************************

   文件名: TestSortDemo.cpp
   摘要: 类SortDemo的测试文件
   开发平台: Win Xp SP2
   编译环境: CL.exe 8.0 (in Visual Studio 2005 SDK)
   作者: 88250
   完成日期: 2006-12-25    版本: 1.0
   Blog: http://DL88250.ynutx.net
   E-mail: DL88250@gmail.com
   QQ: 845765 or 316281008
               
 *******************************************************************/

#include "stdafx.h"
#include "SortDemo.h"
#include <cstdlib>
#include <ctime>
#include <iostream>

using namespace std;

int main(void)
{
 int testArray[MAX_NUM];  // MAX_NUM定义于SortDemo.h文件
 SortDemo sorter;
 srand((unsigned int)time(NULL));
 int choose = 1;
 for (;;)
 {
  // 产生随机数, r[0]保留作辅助空间
  for(int i = 1; i < MAX_NUM; i++)
  {
   testArray[i] = rand() % 100;
  }
  
  cout << "请选择排序算法:" << endl
       << "1. 快速排序   2. 堆排序   3. 直接插入排序   4. 2-路归并排序   5. 退出"<< endl;
  cin >> choose;
  if (5 == choose)
  {
   return 0;
  }
  cout << "排序前的序列:" << endl;
  sorter.DisplaySerial(testArray);
  switch (choose)
  {
   case 1:
   {
    sorter.QSort(testArray, 1, MAX_NUM - 1); 
    break;
   }
   case 2:
   {
    sorter.HSort(testArray);
    break;
   }
   case 3:
   {
    sorter.ISort(testArray);
    break;
   }
   case 4:
   {
    sorter.MSort(testArray);
    break;
   }
   default:
   {
    cout << "选择有误!" << endl;
    break;
   }
  }
  cout << "排序后的序列:" << endl;
  sorter.DisplaySerial(testArray);
  system("pause");
  system("cls");
 }

 return 0;
}

 

抱歉!评论已关闭.