1.头文件&&结构体定义
#include<iostream>
#include<ctime>
using namespace std;
#define MaxLength 500 //定义最大长度
typedef int ElemType;
typedef struct SqList
{
int length;//长度
ElemType *data; //定义data指针用于后续申请空间
}SqList;
void InitSqList(SqList &L)//初始化----申请空间
{
L.data = new ElemType[MaxLength + 1];
}
2.插入排序
void InsertSqListSort(SqList&L)//插入排序
{
L.data[0] = 0;
int i = 2, j; //定义i,j用于后续循环计数
for (i; i <= L.length; i++)
{
if (L.data[i] < L.data[i - 1])//如果后一个数比前一个数小
{
L.data[0] = L.data[i];//待插入的数存入哨兵L.data[0]中
L.data[i] = L.data[i - 1];//把大的值直接放在后一个位置
for (j = i - 2; L.data[0] < L.data[j]; j--)//如果哨兵的值比前面的小
{
L.data[j + 1] = L.data[j]; //满足条件就把比它大的数向后移动
}
L.data[j + 1] = L.data[0];//找到哨兵的值应该对应的地方
}
}
}
3.选择排序
void SelectSqListSort(SqList&L) //选择排序
{
for (int i = 1; i < L.length; i++)
{
int k = i; //k指向已排好序序列的下一数,最开始一个都没有排好序
for (int j = i + 1; j <= L.length; j++)
{
if (L.data[j] < L.data[k]) //找到没排好序序列里面的最小数
{
k = j;//j对应的数据比k对应数据小,就把最小数的下标记录下来
}
}
if (k > i) //利用哨兵交换数据
{
L.data[0] = L.data[k];
L.data[k] = L.data[i];
L.data[i] = L.data[0];
}
}
}
4.冒泡排序
void BubbleSqListSort(SqList&L) //冒泡排序
{
int is_changed_flag = 0; //如果没有交换,flag=0,反之flag=1
for (int i = 1; i < L.length; i++)
{
if (L.data[i] > L.data[i + 1]) //利用哨兵交换数据
{
L.data[0] = L.data[i];
L.data[i] = L.data[i + 1];
L.data[i + 1] = L.data[0];
is_changed_flag = 1; //修改flag为1
}
if (!is_changed_flag) break; //如果已经没有交换,终止循环
}
}
5.双向冒泡排序
void DoubleBubbleSort(SqList&L) //双向冒泡排序
{
int low = 1; //最初low指向第一个元素
int high = L.length; //最初high指向最后一个元素
while (low < high) //当low<high时进入循环
{
bool is_changed_flag = true;//置flag为true
for (int i = low; i < high; i++) //从前向后两两比较
{
if (L.data[i] > L.data[i + 1]) //利用哨兵交换
{
L.data[0] = L.data[i];
L.data[i] = L.data[i + 1];
L.data[i + 1] = L.data[0];
}
is_changed_flag = false; //修改flag为false
} //end for
if (is_changed_flag) break; //flag没被修改过就结束
high--; //high指针前移
is_changed_flag = true; //重新置flag为true
for (int j = high; j >= low; j--) //从后向前两两比较
{
if (L.data[j] > L.data[j + 1]) //利用哨兵交换
{
L.data[0] = L.data[j];
L.data[j] = L.data[j + 1];
L.data[j + 1] = L.data[0];
}
is_changed_flag = false; //修改flag为flag
} //end for
if (is_changed_flag) break; //flag没被修改过就结束
low++; //low指针后移
} //end while
}
6.折半插入排序
void BinaryInsertSqListSort(SqList&L)//折半插入排序
{
int low, high, mid; //定义三个指针mid,low,high
for (int i = 2; i <= L.length; i++)
{
L.data[0] = L.data[i]; //把值给哨兵暂存
low = 1; high = i - 1;
while (low <= high) //当low<=high,进入循环
{
mid = (low + high) / 2; //mid
if (L.data[i] < L.data[mid]) high = mid - 1;
else low = mid + 1;
}
for (int j = i - 1; j >= high + 1; j--) //把插入位置之后到i-1的内容全部都后移
L.data[j + 1] = L.data[j];
L.data[high + 1] = L.data[0]; //利用哨兵,将插入的值插进去
}
}
7.希尔插入排序
void ShellInsert(SqList&L,int index) //希尔插入法
{
int i, j;
for (i = index + 1; i <= L.length; i++)
{
if (L.data[i] < L.data[i - index])
{
L.data[0] = L.data[i]; //哨兵暂存L.data[i]的值
L.data[i] = L.data[i - index];//把大的值直接放在后一个位置
for (j = i - index; j >= 0 && L.data[0] < L.data[j]; j = j - index)
{
L.data[j + index] = L.data[j];
}
L.data[j + index] = L.data[0];
}
}
}
void ShellInsertSqListSort(SqList&L,int dt[],int dtlength) //调用插入进行排序
{
for (int k = 0; k < dtlength; k++)
{
ShellInsert(L, dt[k]);
}
}
8.快速排序
int QuickSortPart(SqList&L,int low,int high) //快速排序
{
L.data[0] = L.data[low];
int piv = L.data[0];
for (int i = 1; i < L.length; i++)
{
while (low < high)
{
while (low < high&&piv <= L.data[high]) high--;//先把指挥棒交给high
L.data[low] = L.data[high];
while (low < high&&L.data[low] <= piv) low++;//把指挥棒交给low
L.data[high] = L.data[low];
} //end while
} //end for
L.data[low] = L.data[0];
return low; //返回下标
}
void QuickSort(SqList&L,int low,int high) //快速排序
{
int piv;
if (low < high)
{
piv = QuickSortPart(L, low, high); //用piv记录返回值(low)
QuickSort(L, low, piv - 1); //调用递归
QuickSort(L, piv+1, high);
}
}
void QuickSqListSort(SqList&L) //快速排序
{
int low = 1, high = L.length;
QuickSort(L, low, high);
}
9.归并排序
void Merge(int a[], int low, int high, int mid)//合并两组数字
{
int k = 0;
int left = low;
int right = mid + 1; //将数组a分为两个部分,left指向左一,right指向右一
int *temp=new int[high - low + 1];//用来存排序数的临时数组
while (left <= mid && right <= high)//当两组数字都未全部移入临时数组
{
if (a[left] > a[right]) //把小数存入temp中,指针后移
temp[k++] = a[right++];
else
temp[k++] = a[left++];
}
while (left <= mid) //当第二组数中还有数未移入临时数组
temp[k++] = a[left++];
while (right <= high) //当第二组数中还有数未移入临时数组
temp[k++] = a[right++];
k = 0;
for (int t = low;t <= high; t++,k++) //将临时数组的数移入原数组
a[t] = temp[k];
delete[]temp;
}
void MergeSort(int a[], int low, int high)//归并排序
{
if (low < high - 1)//如果该组数字个数大于2
{
int mid = (low + high) / 2;
MergeSort(a, low, mid);
MergeSort(a, mid + 1, high);//分割
Merge(a, low, high, mid);//合并
}
else if (low == high - 1)//如果该组数字个数等于2
{
if (a[low] > a[high]) //如果前一个数字比后一个数字大,交换
{
int temp = a[low];
a[low] = a[high];
a[high] = temp;
}
}
//如果该组数字只剩一个,不用处理
}
void MergeSqListSort(SqList&L) //调用归并排序
{
MergeSort(L.data, 1, L.length);
}
10.堆排序
void HeapAdjust(SqList&L, int s, int m) //堆调整
{
int temp = L.data[s]; //用temp记录L.data[s]
for (int j = 2 * s; j <= m; j *= 2)
{
if (j < m&&L.data[j] < L.data[j + 1]) ++j; //j记录值大的结点下标
if (temp >= L.data[j]) break;
L.data[s] = L.data[j]; s = j;
}
L.data[s] = temp; //用temp恢复L.data[s]的值
}
void CreateHeap(SqList&L) //创建堆
{
/*利用L.length/2求得最后一个分支结点,依次-1求得之前的分支结点*/
for (int i = L.length / 2; i > 0; i--)
HeapAdjust(L, i, L.length); //调用堆调整进行创建
}
void HeapSort(SqList &L) //堆排序
{
CreateHeap(L);
for (int i = L.length; i > 1; i--)
{
int temp = L.data[1]; //借用临时变量temp互换L.data[1]和L.data[i]
L.data[1] = L.data[i];
L.data[i] = temp;
HeapAdjust(L, 1, i - 1); //堆调整
}
}
11.基数排序
#define MaxSize 200 //待排序元素的最大个数
#define N 8 //待排序元素的实际个数
#define Key_MaxNum 6 //关键字项数的最大值
#define Radix 10 //关键字基数,10表示十进制数字可以分为十组
typedef struct
{
int key[Key_MaxNum]; //存放关键字
int next;
}SListCell; //静态链表的结点,存放待排序元素
typedef struct
{
SListCell data[MaxSize]; //存储元素,data[0]为头结点
int keynum; //每个元素的当前关键字个数
int length; //静态链表的当前长度
}*SLList; //静态链表,存放元素序列
int trans(char c) //将字符c转化为对应的整数
{
return c - '0';
}
void Distribute(SListCell data[], int i, addr f, addr r)
{
int j, p;
for (j = 0; j < Radix; j++) //初始化各个子表
f[j] = 0;
for (p = data[0].next; p; p = data[p].next)
{
j = trans(data[p].key[i]); //将关键字转换为数字
if (!f[j]) //f[j]是空表,则f[j]指示第一个元素
f[j] = p;
else
data[r[j]].next = p;
r[j] = p; //将p所指的结点插入第j个子表中
}
}
void Collect(SListCell data[], addr f, addr r)
//收集,按key[i]将f[0..Radix-1]所指各子表依次链接成一个静态链表
{
int j, t;
for (j = 0; !f[j]; j++); //找第一个非空子表
data[0].next = f[j];
t = r[j]; //r[0].next指向第一个非空子表中第一个结点
while (j < Radix - 1)
{
for (j = j + 1; j < Radix - 1 && !f[j]; j++); //找下一个非空子表
if (f[j]) //将非空链表连接在一起
{
data[t].next = f[j];
t = r[j];
}
}
data[t].next = 0; //t指向最后一个非空子表中的最后一个结点
}
void RadixSort(SLList L)
//基数排序,使得L成为按关键字非递减的静态链表,L.r[0]为头结点
{
int i;
addr f, r;
for (i = 0; i < L.keynum; i++) //由低位到高位依次对各关键字进行分配和收集
{
Distribute(L.data, i, f, r); //第i趟分配
Collect(L.data, f, r); //第i趟收集
}
}
来源:CSDN
作者:山有木兮°
链接:https://blog.csdn.net/Wannna/article/details/103754862