文章目录
介绍
本人目前正处于考研备考中,在这里整理了数据结构常考的六种排序算法,希望对同数据结构考研的宝子们也有所帮助。
一、直接插入排序
1.排序过程
- 从第二个元素开始,将当前元素视为要插入的值。
- 将当前元素与前一个已经排好序的元素进行比较。
- 如果前一个元素大于当前元素,将前一个元素向后移动一位,腾出位置给当前元素。
- 重复步骤 3,直到找到合适的位置插入当前元素,或者到达数组的开头。
- 将当前元素插入到合适的位置。
- 重复步骤 1 到 5,直到所有元素都被插入到合适的位置。
2.代码实现
//1.直接插入排序(n为待排序元素的个数)
void DirectInsertSort(ElemType a[], int n) {
ElemType temp; //用于存储待插入元素
for (int i = 1; i < n; ++i) { //遍历a[1]-a[n-1]
if (a[i] < a[i - 1]) {
temp = a[i]; //将小于直接前驱的元素存入到保留到temp
//向前寻找比temp大的元素并依次后移
int j;
for (j = i - 1; j >= 0 && a[j] > temp; --j) {
a[j + 1] = a[j];
}
a[j + 1] = temp;
}
}
}
//主函数
int main() {
int a[] = {12, 6, 3, 56, 2, 24, 18};
DirectInsertSort(a, 7);
for (int i = 0; i < 7; ++i) {
printf("%d ", a[i]);
}
}
二、折半插入排序
1.排序过程
- 从第二个元素开始,将当前元素视为要插入的值。
- 利用二分查找在已经排好序的部分序列中找到合适的插入位置。
- 将当前元素插入到找到的合适位置。
- 重复步骤 1 到 3,直到所有元素都被插入到合适的位置。
2.代码实现
//2.折半插入排序
void HalfInsertSort(ElemType a[], int n) {
int low, high, mid;
ElemType temp; //用于存储待插入元素
//采用折半查找找出元素的插入位置
for (int i = 1; i < n; ++i) {
if (a[i] < a[i - 1]) {
temp = a[i];
//当前元素的左半部分折半查找
low = 0;
high = i - 1;
while (low <= high) {
mid = (low + high) / 2;
if (a[mid] > temp) {
high = mid - 1;
} else {
low = mid + 1; //包含了low=high的情况,保证了算法的稳定性
}
}
//后移元素
int j;
for (j = i - 1; j >= high + 1; j--) {
a[j + 1] = a[j];
}
//插入元素
a[j + 1] = temp; //(或a[high+1]=temp)
}
}
}
//主函数
int main() {
int a[] = {12, 6, 3, 56, 2, 24, 18};
HalfInsertSort(a, 7);
for (int i = 0; i < 7; ++i) {
printf("%d ", a[i]);
}
}
三、希尔排序
1.排序过程
- 选择一个增量序列,通常是一系列递减的正整数。常用的增量序列有希尔增量、Hibbard增量等。
- 根据选定的增量,将数组分成多个子序列,每个子序列包含间隔为增量的元素。
- 对每个子序列进行插入排序,将子序列中的元素逐步移动到正确的位置。
- 逐步减小增量,重复步骤 2 和 3,直到增量减至1。
- 最后进行一次增量为1的插入排序,完成整个排序过程。
2.代码实现
//3.希尔排序
void XierSort(ElemType a[], int n) {
int dk; //排序增量
ElemType temp; //用于存储待插入元素
//排序增量每次减半
for (dk = n / 2; dk >= 1; dk = dk / 2) {
for (int i = dk; i < n; ++i) {
if (a[i] < a[i - dk]) {
temp = a[i];
//依次后移元素
int j;
for (j = i - dk; j >= 0 && a[j] > temp; j = j - dk) {
a[j + dk] = a[j];
}
//插入元素
a[j + dk] = temp;
}
}
}
}
//主函数
int main() {
int a[] = {12, 6, 3, 56, 2, 24, 18};
XierSort(a, 7);
for (int i = 0; i < 7; ++i) {
printf("%d ", a[i]);
}
}
四、冒泡排序
1.排序过程
- 从数组的最后一个元素开始,依次比较相邻的两个元素。
- 如果前一个元素大于后一个元素,就交换这两个元素的位置。
- 继续重复步骤 1 和 2,直到第一个元素。这样一轮过去后,数组的最小元素就会“冒泡”到数组的开头。
- 接下来,将数组的范围缩小一个元素,重复步骤 1 到 3。这样进行多轮,直到整个数组有序。
- 如果某趟排序中一次元素交换都没有发生,则说明已经有序,可以提前结束,提高效率。
2.代码实现
//4.冒泡排序
void BubbleSort(ElemType a[], int n) {
for (int i = 0; i < n; ++i) {
int flag = 0; //标志本趟排序是否发生交换
for (int j = n - 1; j > i; --j) {
if (a[j] < a[j - 1]) {
//交换位置
ElemType temp = a[j];
a[j] = a[j - 1];
a[j - 1] = temp;
flag = 1;
}
}
//一趟排序过后如果一次交换都没有发生,则已经有序
if (flag == 0) {
return;
}
}
}
//主函数
int main() {
int a[] = {12, 6, 3, 56, 2, 24, 18};
BubbleSort(a, 7);
for (int i = 0; i < 7; ++i) {
printf("%d ", a[i]);
}
}
五、简单选择排序
1.排序过程
- 首先,找到数组中最小的元素,将其与第一个元素交换位置,这样最小的元素就排在了正确的位置上。
- 接着,在剩余的未排序部分中,找到最小的元素,将其与第二个元素交换位置,这样前两个元素都已经排好序了。
- 依此类推,在每一轮选择过程中,选择未排序部分中的最小元素,将其交换到已排序部分的末尾,直到所有元素都被放到正确的位置为止。
2.代码实现
//5.简单选择排序
void SimpleSelectSort(ElemType a[], int n) {
for (int i = 0; i < n - 1; ++i) { //n-1趟排序,每次选出一个最下元素
int min = i;
//查找最小元素的位置
for (int j = i + 1; j < n; ++j) {
if (a[j] < a[min]) {
min = j;
}
}
//判断min的位置是否改变,如果改变则交换
if (min != i) {
ElemType temp = a[min];
a[min] = a[i];
a[i] = temp;
}
}
}
//主函数
int main() {
int a[] = {12, 6, 3, 56, 2, 24, 18};
SimpleSelectSort(a, 7);
for (int i = 0; i < 7; ++i) {
printf("%d ", a[i]);
}
}
六、快速排序(分治法)
1.排序过程
- 选择一个基准元素(通常是数组的第一个元素)。
- 将数组中比基准元素小的元素移到基准元素的左边,比基准元素大的元素移到右边。这个过程称为分区(Partition)。
- 对基准元素左边的子数组和右边的子数组分别递归地进行快速排序。
- 重复步骤 2 和 3,直到子数组的大小为 1 或 0,此时子数组已经有序。
2.代码实现
//6.快速排序
int Partition(ElemType a[], int low, int high) {
ElemType p = a[low]; //将当前表中第一个元素设置为枢轴
while (low < high) {
//依次向左找到比枢轴元素小的元素
while (low < high && a[high] >= p) {
high--;
}
a[low] = a[high];
//依次向右找到比枢轴元素大的元素
while (low < high && a[low] <= p) {
low++;
}
a[high] = a[low];
}
//插入枢轴元素
a[low] = p;
return low;
}
void QuickSort(ElemType a[], int low, int high) {
if (low < high) {
//对表进行划分
int p = Partition(a, low, high);
//递归排序左子表
QuickSort(a, low, p - 1);
//递归排序右子表
QuickSort(a, p + 1, high);
}
}
//主函数
int main() {
int a[] = {12, 6, 3, 56, 2, 24, 18};
QuickSort(a, 0,6);
for (int i = 0; i < 7; ++i) {
printf("%d ", a[i]);
}
}
总结
头一次写博客,如有错误,请大家指正!