各种排序算法的代码总结(可直接执行)

news/2024/11/20 9:24:19/

常见八大排序算法

写于大二上期末数据结构考试前,做一个排序算法的总结。也是严蔚敏那版本教材上代码具体的编译实现。

1.简单选择排序

。 一句话说,就是每次遍历挑选遍历最小的那个数填入相应的位置。并互换位置。
~~ 改进的一种思路是每次不仅选最小的往前放,也挑最大的往后放。这样只需遍历一半的次数就可以完成排序。简单排序代码过程简单,就不写注释了。

#include<iostream>
using namespace std;
void print(int a[], int n) {  for (int i = 0; i <= n; i++) {cout << a[i] << " ";}cout << endl;
}void selectSort(int a[], int n) {int min,temp;for (int i = 0; i <= n-1; i++) {min = i;for (int j = i + 1; j <= n; j++) {if (a[j] < a[min])min = j;}if(i!=min){temp = a[i];a[i] = a[min];a[min] = temp;}print(a, n);}
}
int main() {int a[8] = { 42,38,65,97,76,13,27,49 };cout << "初始序列如下" << endl;print(a, 7);cout << "下面输出每趟排序后的序列" << endl;selectSort(a,7);
//	print(a, 7);return 0;
}

2.直接插入排序

~~思路:首先将第一个元素看成有序表,第二个元素开始往后遍历时,在这个有序表找到插入的位置,比他大的元素后移,然后存放进去实现排序。
代码实现有个细节需注意,因为对当前元素排序,这个元素之前是有序表。所以对第i个元素先与第i-1 先比较一下,如果比它大,那就进入下个元素,比它小再放入哨兵,然后找插入的位置,元素后移,再插入。
void print(int a[], int n) {for (int i = 0; i <= n; i++) {cout << a[i] << " ";}cout << endl;
}void sort(int a[], int n) {int i, j;for (int i = 2; i <= n; i++) {if (a[i] <= a[i - 1]) {a[0] = a[i];   //a[0]做存储的哨兵for (j = i - 1; a[0] < a[j]; j--) {a[j + 1] = a[j];}a[j + 1] = a[0];}print(a, n);}
}int main() {int a[9] = {0,49,38,65,97,76,13,27,49 };cout << "初始序列如下,其中第一个元素作为哨兵" << endl;print(a, 8);cout << "下面输出每趟排序后的序列" << endl;sort(a, 8);return 0;
}

3.折半插入排序

~~折半插入排序是对直接插入排序的优化,在查找插入位置的时候。用折半查找比顺序查找性能要好。

void print(int a[], int n) {for (int i = 0; i <= n; i++) {cout << a[i] << " ";}cout << endl;
}void InsertSort(int a[], int n) {int i, j, low,high, mid;for (i = 2; i <= n; i++) {a[0] = a[i];low = 1;high = i-1;while (low <= high) {int mid = (high + low)/2;if (a[0] < a[mid])   high = mid - 1;else   low = mid + 1;}for (j =i-1; j>=high+1; j--) {a[j + 1] = a[j];}a[high + 1] = a[0];print(a, 8);}}
int main() {int a[9] = { 0,49,38,65,97,76,13,27,49 };cout << "初始序列如下,其中第一个元素作为哨兵" << endl;print(a, 8);cout << "下面输出每趟排序后的序列" << endl;InsertSort(a, 8);return 0;
}

4.快速排序

首先还是直观地说,快排其实就是把比它小的往左扔,把比它大的元素往右扔,这样这个元素就排到了它应该在的位置。
~~然后说下具体的算法,第一,怎么实现 “比它小的往左扔,把比它大的元素往右扔”,这里一般情况对数组分割后取第一个元素做排序数,就是在这数组定好最低点Low和最高点High。然后把待排序数赋给另一个辅助空间。先从后向前扫描,只要后面元素比它大,那high–,如果出现比它小的元素,那把小的元素换到low的位置,low++,但这注意这个high的位置是一个“坑”,我们不必每次都交换元素,而是留最后把坑填上。在从low的位置往后扫如果都比它小,则low++。若比它大,就把这个大的元素换过去。在从low往后扫描。如此反复,直到low<high条件不成立为止退出循环。
~还要注意运用递归。因为这是一个“分治法”的运用,上面只是让第一个元素达到它该在的位置,每次排序后都会把数组分割后,数组成倍增长,要对美观数组依次上述排序过程。

int Partition(int a[], int low, int high) {int hhh = a[low];while (low < high) {		while (hhh <a[high]) 	high--;//a[low] = a[high];if (hhh > a[high]) {int temp;temp = a[high];a[high] = hhh;a[low] = temp;low++;  print(a, 8);}while ( hhh > a[low])low++;//a[high] = a[low];if (hhh < a[low]) {int Temp;Temp = a[low];a[low] = hhh;a[high] = Temp;high--; print(a, 8);}}//   a[low] = hhh;//print(a, 8);return low;
}
void quickSort(int a[],int low,int high) {if(low<high){int pivotpos;pivotpos = Partition(a, low, high);quickSort(a, low, pivotpos - 1);quickSort(a, pivotpos + 1, high);}}int main() {int a[8] = { 42,38,65,97,76,13,27,49 };cout << "初始序列如下" << endl;print(a, 8);cout << "下面输出每趟排序后的序列" << endl;quickSort(a, 0,7);print(a, 8);return 0;
}

5.冒泡排序

所谓“冒泡”就是把小的数往上浮(又或者把最大的数往下沉)但把小的数往上排会更好。每相邻的数都会比较一次,这样用一个bool型变量进行判断,若一趟的交换元素,则说明已经是有序的。就直接退出。


void bubbleSort(int a[], int n) {bool flag;int i, j,temp;for (i = 0; i <= n - 1; i++) {flag = 0;for (j = n - 1; j > i; j--) {if (a[j - 1] > a[j]) {temp = a[j];a[j] = a[j - 1];a[j - 1] = temp;flag = 1;}}print(a, n);if (flag == 0)return;}
}
int main() {int a[8] = {42,38,65,97,76,13,27,49};cout << "初始序列如下" << endl;print(a, 8);cout << "下面输出每趟排序后的序列" << endl;bubbleSort(a, 8);//print(a, 8);return 0;
}

6.堆排序

对一个数组来说,大顶堆:需建立每个i<n/2 a[i]>a[2i]&&a[i]>a[2i+1]

大观上看就是建大顶堆——>交换第一个与最后一个元素——>再调整为大顶堆。
其中建大顶堆与调整的算法基本一样。所以算法主要的难点在于调整。

void AdjustDown(int a[], int k,int len)
{a[0] = a[k];int i;for (i=2*k; i < len;i=2*i) {//这个循环是因为如果小,要往//下调接着调if (i < len && a[i] < a[i + 1]) {i++;   //先挑出两个中较大的那个}if (a[0] > a[i])  break;else {a[k] = a[i];k=i;}}a[k] = a[0];print(a, len);
}void Swap(int l[],int a,int b) {int temp = l[b];l[b] = l[a];l[a] = temp;
}void BuildMaxHeap(int a[], int len) {for (int i = len / 2; i > 0; i--) {AdjustDown(a, i, len);}
}void HeapSort(int a[], int n){BuildMaxHeap(a, n);for (int i = n; i > 1; i--) {Swap(a,i,1);AdjustDown(a, 1, i - 1);   //为什么传1,有建大顶堆后//只要调整第一个,一次就能//调最大}
}int main() {int a[11] = {0,503,87,512,61,908,170,897,275,653,426};cout << "初始序列如下,其中第一个元素作为哨兵" << endl;print(a, 10);cout << "下面输出排序后的序列" << endl;HeapSort(a, 10);print(a, 10);return 0;
}

7.归并排序

归并的思想,主要是:递归拆分。将两个有序表合并。
算法的难点也就在于两个表的合并,由于用到了辅助数组,变量较多,需要有清晰的逻辑。

int* b = (int*)malloc((7 + 1) * sizeof(int));
void Merge(int a[], int low, int mid, int high) {int i, j, k;for (k = low; k <= high; k++)b[k] = a[k];for (i = low, j = mid + 1, k = i; i <= mid && j <= high; k++) {if (b[i] <= b[j])a[k] = b[i++];elsea[k] = b[j++];}while (i <= mid)   a[k++] = b[i++];while (j <= high)   a[k++] = b[j++];}
void MergeSort(int a[], int low, int high) {if (low < high) {int mid = (low + high) / 2;MergeSort(a, low, mid);MergeSort(a, mid + 1, high);Merge(a, low, mid, high);print(a, 7);}
}int main() {int a[8] = { 42,38,65,97,76,13,27,49 };cout << "初始序列如下" << endl;print(a, 7);cout << "下面输出每趟排序后的序列" << endl;MergeSort(a,0,7);print(a, 7);return 0;
}

8.希尔排序

希尔排序实际是插入排序的衍生。只是取间隔进行插入排序。具体的好处参见别处啦。主要说代码实现思路。
注意的是这个取间隔排序并不是一趟就排序完,而是逐个往后。比如长度为8的数组或顺序表 取间隔 4 应该是1 5 ,2 6 ,3 7 , 4 8, 间隔 变2, 1 3, 2 4 , 1 3 5, 2 4 6 ,1 3 5 7,2 4 6 8。 间隔取 1 ,1 2 3 4 5 6 7 8 这样的次序进行插入排序

void sort(int a[], int n) {int i, j, dk;for (dk = n / 2; dk >= 1; dk = dk / 2){cout << "增量为" << dk << "   排序后" << endl;for (i = 1+dk; i <= n; i++) {if (a[i] <= a[i - dk]) {a[0] = a[i];for (j = i - dk; j>0 && a[0]< a[j]; j-=dk) {a[j + dk] = a[j];}a[j + dk] = a[0];}//	print(a, n);}print(a, n);}
}int main() {int a[9] = { 0,49,38,65,97,76,13,27,49 };cout << "初始序列如下,其中第一个元素作为哨兵" << endl;print(a, 8);cout << "下面输出每趟排序后的序列" << endl;sort(a, 8);return 0;
}

这里总结了我自己对排序算法的代码实现理解,侧重在代码实现。网上也有很多保姆级解释各种排序思想。若对你有帮助点个赞吧。


http://www.ppmy.cn/news/379409.html

相关文章

《电脑维护技巧》(N条举措N条理由)(转载)

下面原文转载如下—— 一、每天关机前要做的清洗: 双击“我的电脑”— —右键点C盘——点“属性”——点“磁盘清理”——点“确定”——再点“是”——再点“确定”。清理过程中&#xff0c;您可看得到未经您许可&#xff08;您可点“查看文件”看&#xff0c;就知道了&#x…

MySQL数据库常见错误及解决方案

MySQL数据库常见错误及解决方案 1 MySQL无法重启问题解决Warning: World-writable config file ‘/etc/my.cnf’ is ignored 原因 今天帮朋友维护服务器&#xff0c;在关闭数据库的命令发现mysql关不了&#xff0c;提示Warning: World-writable config file /etc/my.cnf is …

[转贴]付费空间投诉、空间骗子大曝光,大家来看看黑名单

---------------------------------------------------------------------------- 请用CTRLF查找 中国频道、有个网络、中资源、对呀网、西部数据、E动网络、世纪东方、顶尖网络、蓝网、厦门数字引擎、网盟个人主页、网容科技、数据天空、胜利网络商务、E时代网络、中国数据、…

「微服务架构模式」编曲与编舞——让系统协同工作的不同模式

介绍 Krzysztof&#xff08;采访者&#xff09;&#xff1a;商业组织是由专家组成的&#xff0c;他们在他们最了解的领域提供产品或服务&#xff0c;以获得共同的商业成果。例如&#xff0c;营销团队努力争取新客户&#xff0c;销售团队向这些客户销售产品&#xff0c;客户关系…

【AIX】LPar分区技术、逻辑CPU、虚拟CPU、物理CPU

【AIX】LPar分区技术、逻辑CPU、虚拟CPU、物理CPU IBM硬件管理控制台&#xff08;Hardware Management Console&#xff09;提供了标准的用户接口来配置和管理Power System系列服务器以及服务器上的分区。系统管理员通过HMC对Power System服务器上的分区进行配置和日常管理。 …

JAVA面经(SE)

前言&#xff1a;作为2021届毕业生&#xff0c;受疫情影响&#xff0c;工作机会竞争压力非常大. 对于开学之后马上要开始的秋季校招&#xff0c;我们必须认真扎实的复习. 经过我亲身体验&#xff0c;只在网络上阅读面经效果不太理想. 俗话说&#xff1a;好记性不如烂笔头&#…

【烈日炎炎战后端】MySQL理论(2.8万字)

MySQL理论 1. 数据库三大范式2. char 和 varchar 的区别&#xff1f;3. Mysql的存储引擎以及区别4. 一条SQL查询是如何执行的&#xff1f;5. 什么是回表6. MySQL是如何解决幻读的7. 主从复制原理8.mysql日志中redo和undo日志概念以及应用【MySQL索引】[1] 什么是MySQL索引&…

【烈日炎炎战后端】JAVA多线程(11.2万字)

【8月后端】JAVA多线程&#xff08;112000字&#xff09; 1. 多线程环境下的线程安全体现在哪些方面&#xff1f;2. 创建线程的方式及其区别&#xff1f;3. 说一下从Java API层面上的6种线程状态4 final原理4 ThreadLocal有了解吗&#xff1f;5. synchronized 和Lock区别6. as-…