#ifndef SORT_PRELIMITATION_H
#define SORT_PRELIMITATION_H
#define MAXSIZE 10 //用于要排序数组个数最大值
typedef struct {
int r[MAXSIZE]; //用于存储要排序数组,r[0]可当做临时变量
int length; //用于记录顺序表的长度
}SqList;
/**
* 交换L中数组r的下标为i和j的值
* @param L
* @param i
* @param j
*/
void swap(SqList *L, int i, int j){
int temp = L->r[i];
L->r[i] = L->r[j];
L->r[j] = temp;
}
#endif //SORT_PRELIMITATION_H
#ifndef SORT_BUBBLESORT_H
#define SORT_BUBBLESORT_H
#define bool int
#define TRUE 1
#define FALSE 0
#include "Prelimitation.h"
/* 对顺序表L做交换排序 */
void BubbleSort0(SqList *L){
int i, j;
for(i = 1; i < L->length; i++){
for(j = i + 1; j <= L->length; j++){
if(L->r[i] > L->r[j]){
swap(L, i, j); //交换L->r[i]与L->r[j]的值
}
}
}
}
void BubbleSort(SqList *L){
int i, j;
for(i = 0; i < L->length; i++){
for(j = L->length; j >= i; j++){ //注意j是从后往前循环
if(L->r[j] > L->r[j + 1]){ //若牵着大于后者(注意这里与上面算法的差距)
swap(L, j, j + 1); //交换L->r[j]与L->r[j + 1]的值
}
}
}
}
//优化
void BubbleSort2(SqList *L){
int i, j;
bool flag = TRUE; //flag用来做标记
for(i = 1; i < L->length && flag; i++){ //若flag为TRUE则退出循环
flag = FALSE; //初始为FALSE
for(j = L->length - 1; j >= i; j--){
if(L->r[j] > L->r[j + 1]){
swap(L, j, j + 1); //交换L->r[j]与L->r[j + 1]的值
flag = true; //如果有数据交换,则flag为true
}
}
}
}
#endif //SORT_BUBBLESORT_H
#ifndef SORT_SELECTSORT_H
#define SORT_SELECTSORT_H
#include "Prelimitation.h"
/* 对顺序表L做简单选择排序 */
/**
* 选择排序
* @param L
*/
void SelectSort(SqList *L){
int i, j, min;
for(i = 1; i < L->length; i++){
min = i; //将当前下表定义为最小值下标
for(j = i + 1; j <= L->length; j++){ //循环之后的数据
if(L->r[min] > L->r[j]){ //如果小于当前最小值的关键字
min = j; //将此关键字的下标赋值给min
}
}
if(i != min){ //若min不等于i,说明找到最小值,交换
swap(L, i, min);//交换L->r[min]与L->r[i]的值
}
}
}
#endif //SORT_SELECTSORT_H
#ifndef SORT_INSERTSORT_H
#define SORT_INSERTSORT_H
#include "Prelimitation.h"
/**
* 插入排序
* @param L
*/
void InsertSort(SqList *L){
int i, j;
for(i = 2; i < L->length; i++){
if(L->r[i] < L->r[i - 1]){ //需将L->r[i]插入有序子表
L->r[0] = L->r[i]; //设置哨兵
for(j = i - 1; L->r[j] > L->r[0]; j--){
L->r[j+1] = L->r[j];//记录后移
}
L->r[j + 1] = L->r[0]; //插入到正确位置
}
}
}
#endif //SORT_INSERTSORT_H
#ifndef SORT_SHELLSORT_H
#define SORT_SHELLSORT_H
#include "Prelimitation.h"
/**
* 希尔排序
* @param L
*/
void ShellSort(SqList *L){
int i, j;
int increment = L->length;
do{
increment = increment / 3 + 1; //增量序列
for(i = increment + 1; i <= L->length; i++){
if(L->r[i] < L->r[i - increment]){ //需将L->r[i]插入有序增量子表
L->r[0] = L->r[i]; //暂存在L->r[0]
for(j = i - increment; j > 0 && L->r[0] > L->r[j]; j -= increment){
L->r[j + increment] = L->r[j];//记录后移,查找插入位置
}
L->r[j + increment] = L->r[0]; //插入
}
}
}while (increment > 1);
}
#endif //SORT_SHELLSORT_H
#ifndef SORT_HEAPSORT_H
#define SORT_HEAPSORT_H
#include "Prelimitation.h"
/**
* 已知L->r[s,m]中记录的关键字除L->r[s]之外均满足堆的定义
* 本函数调整L-r[s]的关键字,使L->r[s,m]成为一个大顶堆
* @param L
* @param s
* @param m
*/
void HeapAdjust(SqList *L, int s, int m){
int temp, j;
temp = L->r[s];
for(j = 2 * s; j <= m; j *= 2){ //沿关键字较大的孩子节点向下筛选
if(j < m && L->r[j] < L->r[j + 1]){
++j; //j为关键字中较大的记录的下标
}
if(temp >= L->r[j]){
break; //rc用插入在位置s上
}
L->r[s] = L->r[j];
s = j;
}
L->r[s] = temp; //插入
}
/**
* 堆排序
* @param L
*/
void HeapSort(SqList *L){
int i;
for (i = L->length / 2; i > 0; i--){ //把L中的r构建成一个大顶堆
HeapAdjust(L, i, L->length);
}
for(i = L->length; i > 1; i--){
swap(L, 1, i); //将堆顶记录和当前未经排序子序列的最后一个记录交换
HeapAdjust(L, 1, i - 1); //将L->r[1..i-1]重新调整为大顶堆
}
}
#endif //SORT_HEAPSORT_H
#ifndef SORT_MERGESORT_H
#define SORT_MERGESORT_H
#include
#include "Prelimitation.h"
/**
* 将有序的SR[i..m]和SR[m+1..n]归并为有序的TR[i..n]
* @param SR
* @param TR
* @param i
* @param m
* @param n
*/
void Merge(int SR[], int TR[], int i, int m, int n){
int j, k, l;
for(j = m + 1, k = i; i <= m && j <= n; k++){//将SR中记录由小到大归并入TR
if(SR[i] < SR[j]){
TR[k] = SR[i++];
} else{
TR[k] = SR[j++];
}
}
if(i <= m){
for(l = 0; l <= m - i; l++){//将剩余的SR[i..m]复制到TR
TR[k + 1] = SR[i + 1];
}
}
if(j <= n){
for(l = 0; l <= n - j; l++){//将剩余的SR[j..n]复制到TR
TR[k + l] = SR[j + l];
}
}
}
//递归实现
/**
* 将SR[s..t]归并排序为TR1[s..t]
* @param SR
* @param TR1
* @param s
* @param t
*/
void MSort(int SR[], int TR1[], int s, int t){
int m;
int TR2[MAXSIZE + 1];
if(s == t){
TR1[s] = SR[s];
} else{
m = (s + t) / 2; //将SR[s..t]平分为SR[s..m]和SR[m+1..t]
MSort(SR, TR2, s, m); //递归将SR[s..m]归并为有序的TR2[s..m]
MSort(SR, TR2, m + 1, t);//递归将SR[m+1..t]归并为有序的TR2[m+1..t]
Merge(TR2, TR1, s, m, t); //将TR2[s..m]和TR2[m+1..t]归并到TR1[s..t]
}
}
/**
* 递归归并排序
* @param L
*/
void MergeSort(SqList *L){
MSort(L->r, L->r, 1, L->length);
}
//非递归实现
/**
*
* @param SR
* @param TR
* @param s
* @param n
*/
void MergePass(int SR[], int TR[], int s, int n){
int i = 1;
int j;
while(i <= n - 2 * s + 1){
Merge(SR, TR, i, i + s - 1, i + 2 * s - 1); //两两归并
i = i + 2 * s;
}
if(i < n - s + i){ //归并最后两个序列
Merge(SR, TR, i, i + s - 1, n);
} else{ //若最后只剩下单个子序列
for(j = i; j <= n; j++){
TR[j] = SR[j];
}
}
}
/**
* 非递归归并排序
* @param L
*/
void MergeSort2(SqList *L){
int *TR = (int *)malloc(L->length * sizeof(int)); //申请额外空间
int k = 1;
while(k < L->length){
MergePass(L->r, TR, k, L->length);
k = 2 * k; //子序列长度加倍
MergePass(TR, L->r, k, L->length);
k = 2 * k; //子序列长度加倍
}
}
#endif //SORT_MERGESORT_H
#ifndef SORT_QUICKSORT_H
#define SORT_QUICKSORT_H
#define MAX_LENGTH_INSERT_SORT 7 //数组长度阈值
#include "Prelimitation.h"
#include "InsertSort.h"
/**
* 交换顺序表L中子表的记录,使枢纽记录到位,并返回其所在位置
* 此时在他之前(后)的记录均不大(小)于它
* @param L
* @param low
* @param high
* @return
*/
int Partition(SqList *L, int low, int high){
int pivotKey;
pivotKey = L->r[low]; //用子表的第一个记录作为枢纽记录
while(low < high){ //从标的两端交替向中间扫描
while(low < high && L->r[high] >= pivotKey){
high--;
}
swap(L, low, high); //将比枢纽记录小得记录交换到低端
while(low < high && L->r[low] <= pivotKey){
low++;
}
swap(L, low, high); //将比枢纽记录大得记录交换到高端
}
return low; //返回枢纽所在位置
}
/**
* 对顺序表L中的子序列L->r[low..high]做快速排序
* @param L
* @param low
* @param high
*/
void QSort(SqList *L, int low, int high){
int pivot;
if(low < high){
pivot = Partition(L, low, high); //将L->r[low..high]一分为二
QSort(L, low, pivot - 1); //对低子表递归排序
QSort(L, pivot + 1, high); //对高子表递归排序
}
}
/**
* 快速排序
* @param L
*/
void QuickSort(SqList *L){
QSort(L, 1, L->length);
}
//优化
/**
* 优化不必要的交换
* @param L
* @param low
* @param high
* @return
*/
int Partition1(SqList *L, int low, int high){
int pivotKey;
/**
* 三数取中法
* 取三个关键字先进行排序,将中间数作为枢纽,一般是取左端、右端和中间三个数,也可以随机选取
*/
int m = low + (high - low) / 2;//计算数组中间的元素下标
if(L->r[low] > L->r[high]){
swap(L, low, high); //交换左端与右端数据,保证左端较小
}
if(L->r[m] > L->r[high]){
swap(L, high, m); //交换中间与右端数据,保证中间较小
}
if(L->r[m] > L->r[low]){
swap(L, m, low); //交换中间与左端数据,保证左端较小
}
//此时L.r[low]已经为整个序列左中右三个关键字的中间值
pivotKey = L->r[low]; //用子表的第一个做枢纽记录
L->r[0] = pivotKey; //将枢纽关键字备份到L->r[0]
while (low < high){ //从表的两端交替向中间扫描
while(low < high && L->r[high] >= pivotKey){
high--;
}
L->r[low] = L->r[high]; //采用替换而不是交换的方式进行操作
while(low < high && L->r[low] <= pivotKey){
low++;
}
L->r[high] = L->r[low]; //采用替换而不是交换的方式进行操作
}
L->r[low] = L->r[0]; //将枢纽数值替换回L.r[low]
return low; //返回枢纽所在位置
}
/**
* 对顺序表L中的子序列L.r[low..high]做快速排序
* @param L
* @param low
* @param high
*/
void QSort(SqList &L, int low, int high){
int pivot;
if((high - low) > MAX_LENGTH_INSERT_SORT){//当high-low大于常数时用快速排序
pivot = Partition(&L, low, high); //将L.r[low..high]一分为二,并算出枢纽值pivot
QSort(L, low, pivot - 1); //对低子表递归排序
QSort(L, pivot + 1, high); //对高子表递归排序
} else{ //当high-low小于等于常数时用直接插入排序
InsertSort(&L);
}
}
/**
* 实施尾递归优化
* @param L
* @param low
* @param high
*/
void QSort1(SqList *L, int low, int high){
int pivot;
if((high - low) > MAX_LENGTH_INSERT_SORT){
while(low < high){
pivot = Partition(L, low, high); //将L.r[low..high]一分为二,并算出枢纽值pivot
QSort(L, low, pivot - 1); //对低子表递归排序
low = pivot + 1; //尾递归
}
} else{
InsertSort(L);
}
}
#endif //SORT_QUICKSORT_H
#ifndef SORT_TOPOLOGICALSORT_H
#define SORT_TOPOLOGICALSORT_H
#include
#include
#include "Prelimitation.h"
#define MAXVEX 100
typedef struct EdgeNode{ //边表结点
int adjVex; //邻结点域,存储该顶点对应的下标
int weight; //用于存储权值,对于非网图可以不需要
struct EdgeNode *next; //链域,指向下一个邻结点
}EdgeNode;
typedef struct VertexNode{ //顶点表结点
int in; //顶点入度
int data; //顶点域,存储定点信息
EdgeNode *firstEdge; //边表头指针
}VertexNode, AdjList[MAXVEX];
typedef struct {
AdjList adjList;
int numVertexes, numEdges; //图中当前顶点数和边数
}graphAdjList, *GraphAdjList;
/**
* 拓扑排序,若GL无回路,则输出拓扑排序序列并返回1,若有活路则返回0
* @param GL
* @return
*/
int TopologicalSort(GraphAdjList GL){
EdgeNode *e;
int i ,k, getTop;
int top = 0; //用于栈指针下标
int count = 0; //用于统计输出顶点的个数
int *stack; //建栈存储入度为0的顶点
stack = (int *)malloc(GL->numVertexes * sizeof(int));
for(i = 0; i < GL->numVertexes; i++){
if(GL->adjList[i].in = 0){
stack[++top] = i; //将入度为0的顶点入栈
}
}
while(top != 0){
getTop = stack[top--]; //出栈
printf("%d ->", GL->adjList[getTop].data); //打印此点
count++; //统计输出定点数
for(e = GL->adjList[getTop].firstEdge; e; e = e->next){ //对此顶点弧表遍历
k = e->adjVex;
if(!(--GL->adjList[k].in)){ //将k号顶点邻结点的入度-1
stack[++top] = k; //若为0则入栈,以便于下次循环输出
}
}
}
if(count < GL->numVertexes){ //如果count小于定点数,说明存在环
return 0;
} else{
return 1;
}
}
#endif //SORT_TOPOLOGICALSORT_H
编译器:Clion
参考书籍:《大话数据结构》