C 语言常用的排序算法
来源:互联网 发布:网络通信是什么 编辑:程序博客网 时间:2024/04/25 19:57
[c-sharp] view plain copy
- /********************************************************************************************
- 平方阶(O(n2))排序
- 一般称为简单排序,例如直接插入、直接选择和冒泡排序
- ********************************************************************************************/
- /*插入排序*/
- extern int InsertSort(int source[], int array_size)
- {
- int index = 1; //插入排序
- int i, j;
- for (i = 1; i < array_size; i++)
- {
- index = source[i];
- j = i;
- while ((j > 0) && (source[j - 1] > index))
- {
- source[j] = source[j - 1];
- j--;
- }
- source[j] = index;
- }
- return 1;
- }
- /*冒泡排序*/
- extern int BubbleSort(int source[], int array_size)
- {
- int i, j;
- int temp;
- for (i = 0; i < array_size; i++)
- {
- for (j = 0; j < array_size - i - 1; j++)
- if (source[j] > source[j + 1])
- {
- temp = source[j];
- source[j] = source[j + 1];
- source[j + 1] = temp;
- }
- }
- return 1;
- }
- /*选择排序*/
- extern int SelectSort(int source[], int array_size)
- {
- int temp, min;
- int i, j;
- for (i = 0; i < array_size; i++)
- {
- min = i;//先假设最小下标为i
- for (j = i + 1; j < array_size; j++)
- if (source[j] < source[min])
- min = j;//把i之后的最小值附给min
- if (min != i)
- {
- temp = source[i];
- source[i] = source[min];
- source[min] = temp;
- }//判断min与i是否相等,若相等则说明原假设正确,反之:交换数值
- }
- return 1;
- }
[cpp] view plain copy
- /*********************************************************************************************
- 线性对数阶(O(nlgn))排序
- 如快速、堆和归并排序
- ********************************************************************************************/
- /*快速排序接口*/
- static int Partition(int source[], int left, int right)
- {
- int x = source[left];
- while (left < right)
- {
- while (left < right && x <= source[right])
- right--;
- source[left] = source[right];
- while (left < right && x >= source[left])
- left++;
- source[right] = source[left];
- }
- source[left] = x;
- return left;
- }
- extern int QuickSort(int source[], int left, int right)
- {
- int iPos;
- if (left >= right)
- return 1;
- iPos = Partition(source, left, right);
- QuickSort(source, left, iPos - 1); // 左边划分
- QuickSort(source, iPos + 1, right); // 右边划分
- return 1;
- }
- /*堆排序*/
- static void HeapAdjust(int source[], int root, int node)/*root根节点, node节点总数*/
- {
- //已知source[root..node]中除source[root]之外均满足堆的定义,本函数调整source[root]
- //使source[root..node]成为一个大顶堆
- int j, rc;
- rc = source[root];
- for (j = 2 * root; j <= node; j *= 2) //沿关键字叫大的结点向下筛选
- {
- if (j < node && source[j] < source[j + 1])
- ++j; //j为关键字较大的记录的下标
- if (rc >= source[j])
- break; //rc应插入在位置root上
- source[root] = source[j];
- root = j;
- }
- source[root] = rc; //插入
- }
- extern int HeapSort(int source[], int array_size)
- {
- int i, t;
- for (i = array_size / 2; i > 0; --i)
- //把a[1..L.length]建成大顶堆
- HeapAdjust(source, i, array_size);
- for (i = array_size; i > 1; --i)
- {
- t = source[1]; //将堆顶记录和当前未经排序子序列a[1..i]
- source[1] = source[i]; //中的最后一个记录相互交换
- source[i] = t;
- HeapAdjust(source, 1, i - 1); //将r[1..i-1]重新调整为大顶堆
- }
- return 1;
- }
[cpp] view plain copy
- /**********************************************************************************************
- O(n1+£)阶排序
- £是介于0和1之间的常数,即0<£<1,如希尔排序
- ********************************************************************************************/
- /*希儿排序*/
- extern int ShellSort(int source[], int array_size)
- {
- int increament;
- int e, i, j;
- /*初始步长设为n/2*/
- for (increament = array_size / 2; increament > 0; increament = increament / 2)
- for (j = increament; j < array_size; j++)
- {
- if (source[j] < source[j - increament])
- {
- e = source[j];
- for (i = j - increament; i >= 0 && source[i] > e; i = i - increament)
- source[i + increament] = source[i];
- source[i + increament] = e;
- }
- }
- return 1;
- }
九大数据结构排序算法的实现
targetver.h
[cpp] view plain copy
- #pragma once
- // 包括 SDKDDKVer.h 将定义可用的最高版本的 Windows 平台。
- // 如果要为以前的 Windows 平台生成应用程序,请包括 WinSDKVer.h,并将
- // WIN32_WINNT 宏设置为要支持的平台,然后再包括 SDKDDKVer.h。
- #include <SDKDDKVer.h>
stdafx.h
[cpp] view plain copy
- // stdafx.h : 标准系统包含文件的包含文件,
- // 或是经常使用但不常更改的
- // 特定于项目的包含文件
- //
- #define _AFXDLL
- #pragma once
- #include "targetver.h"
- #include <stdio.h>
- #include <tchar.h>
- // TODO: 在此处引用程序需要的其他头文件
- #include<iostream>
- #include<fstream>
- #include<string>
- #include<afxwin.h>
- 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
[cpp] view plain copy
- // 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<j&&CArray[i].CKey_1 <= tmp.CKey_1)
- {
- i++;
- }
- CArray[j] = CArray[i];
- }
- CArray[i] = tmp;
- //递归左右两侧
- PriCQuickSort(CArray, CStart, i - 1);
- PriCQuickSort(CArray, i + 1, CEnd);
- }
- }
- //快排
- void CSortFunction::CQuickSort()
- {
- PriCQuickSort(CArray, 0, CLength-1);
- }
- //选择排序
- void CSortFunction::CSelectSort()
- {
- for (int i = 0; i < CLength - 1; i++)
- {
- int k = i;
- //后i后存在更小值,则改变k值为该值下标
- for (int j = i + 1; j<CLength; j++)
- {
- if (CArray[j].CKey_1 < CArray[k].CKey_1)
- {
- k = j;
- }
- }
- //若发生改变,则交换
- if (k != i)
- {
- CData tmp = CArray[i];
- CArray[i] = CArray[k];
- CArray[k] = tmp;
- }
- }
- }
- //堆重构
- void CSortFunction::CSift(CData* CArray, int low, int high)
- {
- //位置i所在为双亲节点,j为左节点,j+1为右节点
- int i = low, j = 2 * i;
- CData tmp = CArray[i];
- while (j <= high)
- {
- //若右节点大于左节点,j指向右节点
- if (j < high&&CArray[j].CKey_1 < CArray[j + 1].CKey_1)
- {
- j++;
- }
- //若左右节点中较大值大于双钱节点,交换值和下标
- if (tmp.CKey_1 < CArray[j].CKey_1)
- {
- CArray[i] = CArray[j];
- i = j;
- j = 2 * i;
- }
- else
- {
- break;
- }
- }
- CArray[i] = tmp;
- }
- //堆排序
- void CSortFunction::CHeapSort()
- {
- //初始化堆
- for (int i = (CLength) / 2; 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(main文件)
[cpp] view plain copy
- // 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;
- }
1 0
- C 语言常用的排序算法
- C 语言常用的排序算法
- 常用排序算法的C语言实现
- C 语言常用的排序算法
- 几种常用排序算法的C语言实现
- 常用的各种排序算法(C语言实现)
- 几种常用排序算法的C语言实现
- 常用的排序算法C语言描述与分析
- 几种常用的排序算法(c语言实现)
- C语言常用排序算法(一)
- C语言常用排序算法(二)
- 用C语言实现常用排序算法
- 常用排序算法——C语言
- 常用排序算法C语言实现
- 用C语言实现常用排序算法
- C语言常用的几种排序算法代码(选择排序,冒泡排序,插入排序,快速排序)
- C语言常用排序
- 整理的常用的9种排序算法 c语言 复杂度表
- ngrok下载与使用方法
- Qt多线程编程中的对象线程与函数执行线程
- ClosedXML 读写Excel文件
- WeeX总结
- iOS获取应用和设备信息
- C 语言常用的排序算法
- QTwin热键接收消息
- docker私有仓库设置
- VS将本地的项目使用git上传到远程存储库
- LeetCode
- webstorm 使用svn
- [转载整理]Eclipse写JAVA的相对路径总结
- 南宁市三塘考点科目二考试注意事项
- 【转】zookeeper入门系列(持续更新)