九大数据结构排序算法的实现
targetver.h
#pragma once
// 包括 SDKDDKVer.h 将定义可用的最高版本的 Windows 平台。
// 如果要为以前的 Windows 平台生成应用程序,请包括 WinSDKVer.h,并将
// WIN32_WINNT 宏设置为要支持的平台,然后再包括 SDKDDKVer.h。
#include
stdafx.h
// stdafx.h : 标准系统包含文件的包含文件,
// 或是经常使用但不常更改的
// 特定于项目的包含文件
//
#define _AFXDLL
#pragma once
#include "targetver.h"
#include
#include
// TODO: 在此处引用程序需要的其他头文件
#include
#include
#include
#include
using namespace std;
static const int CMAX_N = 100;
//剩余排序
class CData
{
public:
int CKey_1;//使用该关键字
int CKey_2;//未使用
int CKey_3;//未使用
};
//基数排序数据节点
class _CList
{
public:
char CData[2];//各个位置
int CDataNum;//数据位数
class _CList *next;
};
//排序
class CSortFunction
{
public:
//构造
CSortFunction(string CReadName, string CWriteName);
//析构
~CSortFunction();
//警告信息
inline void CWarnings();
//获取文件数据
void CGetArray();
//获取文件数据
void CGetFileData(string CRadixFileName,string CWriteRadixFileName);
//基数排序写入
bool CWriteRadix();
//写入排序后数据
bool CWriteArray();
//直接插入排序
void CInsertSort();
//折半插入排序
void CHalfInsertSort();
//希尔排序
void CShellSort();
//冒泡排序
void CBubbleSort();
//快速排序
void CQuickSort();
//选择排序
void CSelectSort();
//堆排序
void CHeapSort();
//归并排序
void CMergeSort();
//基数排序
void CRadixSort();
private:
CData *CArray;
int CLength;
string CReadName;
string CWriteName;
ifstream CReadFile;
ofstream CWriteFile;
_CList *list;
_CList *CTmp = nullptr;
//快速排序
void PriCQuickSort(CData* CArray, int CStart, int CEnd);
//堆重构
void CSift(CData* CArray, int low, int high);
//归并子表
void CMerge(CData* CArray, int low, int mid, int high);
//归并整张表
void CMergePass(CData* CArray, int CChildLength, int CLength);
};
stdafx.cpp
// stdafx.cpp : 只包括标准包含文件的源文件
// AllSortFunction.pch 将作为预编译头
// stdafx.obj 将包含预编译类型信息
#include "stdafx.h"
// TODO: 在 STDAFX.H 中
// 引用任何所需的附加头文件,而不是在此文件中引用
//构造
CSortFunction::CSortFunction(string CReadName, string CWriteName)
{
this->CReadName = CReadName;//读取文件名
this->CWriteName = CWriteName;//写入文件名
CArray = (CData *)malloc(sizeof(CData)*CMAX_N);//申请空间
CLength = 0;//数组长度
}
//析构
CSortFunction::~CSortFunction()
{
//释放基数排序所用空间
_CList *CTmpList_r = list, *CTmpList_p = CTmpList_r->next;
while (CTmpList_p != NULL)
{
free(CTmpList_r);
CTmpList_r = CTmpList_p;
CTmpList_p = CTmpList_p->next;
}
free(CTmpList_p);
//释放其他排序所用空间
free(CArray);
}
//警告
inline void CSortFunction::CWarnings()
{
MessageBox(NULL, _T("No Data Found!"), _T("Warning"), 1);//无原始数据文件
exit(0);
}
//获取数据
void CSortFunction::CGetArray()
{
CReadFile.open(CReadName, ios::in);
if (CReadFile.is_open())
{
int CfData, i = 0;
while (!CReadFile.eof() && (CReadFile >> CfData).good())
{
CArray[i].CKey_1 = CfData;//读入数据
i++;
}
CLength = i;//数组长度
}
else
{
CSortFunction::CWarnings();//警告,无原始数据文件
}
CReadFile.close();
}
//写入排序数据
bool CSortFunction::CWriteArray()
{
CWriteFile.open(CWriteName, ios::out|ios::app);
CWriteFile << "----------" << endl;
for (int i = 0; i < CLength; i++)
{
CWriteFile << CArray[i].CKey_1 << endl;
}
CWriteFile.close();
return true;
}
//直接插入排序
void CSortFunction::CInsertSort()
{
for (int i = 1; i < CLength; i++)
{
CData tmp = CArray[i];
int j = i - 1;
//从有序序列末尾开始,若小于末尾,则后移覆盖
while (j >= 0 && tmp.CKey_1 < CArray[j].CKey_1)
{
CArray[j + 1] = CArray[j];
j--;
}
//正确位置
CArray[j + 1] = tmp;
}
}
//折半插入排序
void CSortFunction::CHalfInsertSort()
{
int low, high, mid;
for (int i = 1; i < CLength; i++)
{
CData tmp = CArray[i];
low = 0; high = i - 1;
//折半查找
while (low <= high)
{
mid = (low + high) / 2;
if (tmp.CKey_1 < CArray[mid].CKey_1)
{
high = mid - 1;
}
else
{
low = mid + 1;
}
}
//后移插入正确位置
for (int j = i - 1; j>high; j--)
{
CArray[j + 1] = CArray[j];
}
CArray[high + 1] = tmp;
}
}
//希尔排序
void CSortFunction::CShellSort()
{
//直接插入排序间隔为1,希尔排序间隔增大
int gap = CLength / 2;//分割标志
while (gap > 0)
{
for (int i = gap; i < CLength; i++)
{
CData tmp = CArray[i];
int j = i - gap;
while (j >= 0 && tmp.CKey_1 < CArray[j].CKey_1)
{
CArray[j + gap] = CArray[j];
j -= gap;
}
CArray[j + gap] = tmp;
}
gap /= 2;
}
}
//冒泡排序
void CSortFunction::CBubbleSort()
{
bool CExchange;//优化判断是否有数据交换
for (int i = 0; i < CLength - 1; i++)
{
CExchange = false;
for (int j = CLength - 1; j>i; j--)
{
//后一位小于前一位,交换位置
if (CArray[j].CKey_1 < CArray[j - 1].CKey_1)
{
CData tmp = CArray[j];
CArray[j] = CArray[j - 1];
CArray[j - 1] = tmp;
CExchange = true;
}
}
//若某一趟没有发生交换,排序结束
if (!CExchange)
{
return;
}
}
}
//快速排序
void CSortFunction::PriCQuickSort(CData* CArray,int CStart,int CEnd)
{
int i = CStart, j = CEnd;
CData tmp;
if (CStart < CEnd)
{
tmp = CArray[CStart];
while (i != j)
{
//从右到左
while (j>i&&CArray[j].CKey_1 >= tmp.CKey_1)
{
j--;
}
CArray[i] = CArray[j];
//从左到右
while (i= 0; i--)
{
CSift(CArray, i, CLength-1);
}
//排序
for (int i = CLength-1; i >= 1; i--)
{
CData tmp = CArray[0];
CArray[0] = CArray[i];
CArray[i] = tmp;
CSift(CArray, 0, i-1);//重构堆
}
}
//归并子表
void CSortFunction::CMerge(CData* CArray, int low, int mid, int high)
{
CData *CTmpArray;
int i = low, j = mid + 1, k = 0;
CTmpArray = (CData *)malloc(sizeof(CData)*(high - low + 1));
while (i <= mid&&j <= high)
{
//向CTmpArray中存入第一段
if (CArray[i].CKey_1 <= CArray[j].CKey_1)
{
CTmpArray[k] = CArray[i];
i++; k++;
}
else//存第二段
{
CTmpArray[k] = CArray[j];
j++; k++;
}
}
//复制第一段余下部分
while (i <= mid)
{
CTmpArray[k] = CArray[i];
i++; k++;
}
//复制第二段余下部分
while (j <= high)
{
CTmpArray[k] = CArray[j];
j++; k++;
}
//拷贝回原数组
for (k = 0, i = low; i <= high; k++, i++)
{
CArray[i] = CTmpArray[k];
}
free(CTmpArray);
}
//归并整张表
void CSortFunction::CMergePass(CData* CArray, int CChildLength, int CLength)
{
int i;
//归并CChildLength长的相邻子表
for (i = 0; i + 2 * CChildLength - 1 < CLength; i = i + 2 * CChildLength)
{
CMerge(CArray, i, i + CChildLength - 1, i + 2 * CChildLength - 1);
}
//归并子表
if (i + CChildLength - 1 < CLength)
{
CMerge(CArray, i, i + CChildLength - 1, CLength - 1);
}
}
//归并排序
void CSortFunction::CMergeSort()
{
for (int length = 1; length < CLength; length = length * 2)
{
CMergePass(CArray, length, CLength);
}
}
//获取文件数据
void CSortFunction::CGetFileData(string CRadixFileName, string CWriteRadixFileName)
{
CReadName = CRadixFileName;//读入数据文件名
CWriteName = CWriteRadixFileName;//写入数据文件名
//尾插法构造链表
_CList *CTmpList_r, *CTmpList_p;
list = (_CList *)malloc(sizeof(_CList));
CTmpList_r = list;
string CfData;
CReadFile.open(CReadName, ios::in);
if (CReadFile.is_open())
{
while (!CReadFile.eof() && (CReadFile >> CfData).good())
{
int j = 0;
CTmpList_p = (_CList *)malloc(sizeof(_CList));
CTmpList_p->CDataNum = CfData.length();//获取数据位数
while (CfData.length())
{
CTmpList_p->CData[j] = CfData[CfData.length()-1];//倒叙写入数据
CfData.assign(CfData.substr(0, CfData.length() - 1));//重构数据串
j++;
}
CTmpList_r->next = CTmpList_p;
CTmpList_r = CTmpList_p;
}
CTmpList_r->next = nullptr;
CReadFile.close();
}
else
{
CWarnings();
}
}
//基数排序
void CSortFunction::CRadixSort()
{
_CList *CHead[10], *CTail[10], *CTmp_r = nullptr;
CTmp = list->next;
//分散遍历排序
for (int i = 0; i < CTmp->CDataNum; i++)
{
//初始化为空
for (int j = 0; j < 10; j++)
{
CHead[j] = CTail[j] = nullptr;
}
//按个位/十位/百位...依次排序,循环次数定位数据位数次
while (CTmp!=NULL)
{
int k = CTmp->CData[i] - '0';
if (CHead[k] == NULL)
{
CHead[k] = CTail[k] = CTmp;
}
else
{
CTail[k]->next = CTmp;
CTail[k] = CTmp;
}
CTmp = CTmp->next;
}
//收集排序后序列
CTmp = NULL;
for (int j = 0; j < 10; j++)
{
if (CHead[j] != NULL)
{
if (CTmp == NULL)
{
CTmp = CHead[j];
CTmp_r = CTail[j];
}
else
{
CTmp_r->next = CHead[j];
CTmp_r = CTail[j];
}
}
}
CTmp_r->next = NULL;
}
}
//基数排序写入
bool CSortFunction::CWriteRadix()
{
CWriteFile.open(CWriteName, ios::out);
_CList *CTmpList_r = CTmp;
while (CTmpList_r != NULL)
{
//倒叙写入,获取正序数
CWriteFile << CTmpList_r->CData[1] << CTmpList_r->CData[0] << endl;
CTmpList_r = CTmpList_r->next;
}
CWriteFile.close();
return true;
}
// AllSortFunction.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
int _tmain(int argc, _TCHAR* argv[])
{
CSortFunction sort("read.txt", "sort.txt");
sort.CGetArray();//读数据
sort.CInsertSort();//直接插入排序
if (sort.CWriteArray())//写数据
{
cout << "直接插入排序 OK." << endl;
}
sort.CHalfInsertSort();//折半插入排序
if (sort.CWriteArray())//写数据
{
cout << "折半插入排序 OK." << endl;
}
sort.CShellSort();//希尔排序
if (sort.CWriteArray())//写数据
{
cout << "希尔排序 OK." << endl;
}
sort.CBubbleSort();//冒泡排序
if (sort.CWriteArray())//写数据
{
cout << "冒泡排序 OK." << endl;
}
sort.CQuickSort();//快速排序
if (sort.CWriteArray())//写数据
{
cout << "快速排序 OK." << endl;
}
sort.CSelectSort();//选择排序
if (sort.CWriteArray())//写数据
{
cout << "选择排序 OK." << endl;
}
sort.CHeapSort();//堆排序
if (sort.CWriteArray())//写数据
{
cout << "堆排序 OK." << endl;
}
sort.CMergeSort();//归并排序
if (sort.CWriteArray())//写数据
{
cout << "归并排序 OK." << endl;
}
sort.CGetFileData("radix.txt", "solveRadix.txt");//获取基数排序数据
sort.CRadixSort();//基数排序
//写入文件
if (sort.CWriteRadix())
{
cout << "基数排序 OK." << endl;
}
return 0;
}
测试运行
read.txt
radix.txt
sort.txt
solveradix.txt
注释:上面提供的基数排序仅能对相同位数的十进制数序列排序。