【数据结构】常见七大排序总结
创始人
2024-01-15 12:11:43
0

目录

一、插入排序:直接插入排序【稳定排序方法】

二、插入排序:希尔排序【不稳定排序方法】

三、选择排序:直接选择排序【不稳定排序方法】

四、选择排序:堆排序【不稳定排序方法】

五、交换排序:冒泡排序【稳定排序方法】

六、交换排序:快速排序【不稳定排序方法】

七、归并排序:归并排序【稳定排序方法】


前言

排序是计算机程序设计中的一种重要操作,其功能是对一个数据元素集合或序列重新排列成一个按数据元素某个相知有序的序列。排序分为两类:内排序和外排序。

 今天为大家总结一下,常见的七大排序:

一、插入排序:直接插入排序【稳定排序方法】

1.概述

1.1 插入排序,一般也被称为直接插入排序。

1.2 插入排序:每次将一个待排序的记录,按其关键字的大小插入到前面已排序好的记录序列中的适当位置,直到全部记录插入完成为止。

1.3  直接插入排序是一种最简单的排序方法,其基本操作是将一条记录插入到已排好的有序表中,从而得到一个新的、记录数量增1的有序表。

2. 算法实现:

2.1不带监视哨  

//【算法1】 不带监视哨的直接插入排序算法
public void insertSort() {RecordNode temp;int i, j;for (i = 1; i < this.curlen; i++) {		// n-1趟扫描temp = r[i];  						// 将待插入的第i条记录暂存在temp中for (j = i - 1; j >= 0 && temp.key.compareTo(r[j].key) < 0; j--) { r[j + 1] = r[j];				// 将前面比r[i]大的记录向后移动}r[j + 1] = temp;          			// r[i]插入到第j+1个位置//System.out.print("第" + i + "趟: ");//display();}
}

2.2带监视哨

//【算法2】带监视哨的直接插入排序算法
public void insertSortWithGuard() {int i, j;
//        System.out.println("带监视哨的直接插入排序");for (i = 1; i 

二、插入排序:希尔排序【不稳定排序方法】

1.概述

希尔排序(Shell's Sort)是插入排序的一种又称“缩小增量排序”,是直接插入排序算法的一种更高效的改进版本。希尔排序是非稳定排序算法

 2. 算法实现

//【算法3】希尔排序算法
public void shellSort(int[] d) { //d[]为增量数组RecordNode temp;int i, j;System.out.println("希尔排序");//控制增量,增量减半,若干趟扫描for (int k = 0; k < d.length; k++) {//一趟中若干子表,每个记录在自己所属子表内进行直接插入排序int dk = d[k];for (i = dk; i < this.curlen; i++) {temp = r[i];for (j = i - dk; j >= 0 && temp.key.compareTo(r[j].key) < 0; j -= dk) {r[j + dk] = r[j];}r[j + dk] = temp;}System.out.print("增量dk=" + dk + "  ");display();}
}

三、选择排序:直接选择排序【不稳定排序方法】

1.概述

  • 首先在所有记录中选出关键字值最小的记录,把它与第一个记录进行位置交换,

  • 然后在其余的记录中再选出关键字值次小的记录,与第二个记录进行位置交换。

  • 依次类推,直到所有记录排好序。

 2. 算法实现

//【算法】直接选择排序
public void selectSort() {//   System.out.println("直接选择排序");RecordNode temp; //辅助结点for (int i = 0; i < this.curlen - 1; i++) {//n-1趟排序//每趟在从r[i]开始的子序列中寻找最小元素int min = i;               //设第i条记录的关键字最小for (int j = i + 1; j < this.curlen; j++) {//在子序列中选择关键字最小的记录if (r[j].key.compareTo(r[min].key) < 0) {min = j;             //记住关键字最小记录的下标}}if (min != i) {    //将本趟关键字最小的记录与第i条记录交换temp = r[i];r[i] = r[min];r[min] = temp;}System.out.print("第" + (i + 1) + "趟: ");display();}
}

四、选择排序:堆排序【不稳定排序方法】

1.概述

堆排序(英语:Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。

  • 大顶堆:每个节点的值都大于或者等于它的左右子节点的值。

  • 小顶堆:每个节点的值都小于或者等于它的左右子节点的值。

  • 一般升序采用大顶堆,降序采用小顶堆

2.示意图

3.算法实现

基本思想:

1. 首先将这n条记录按关键字值的大小建立堆(称为初始堆),将堆顶元素r[0]与r[n-1]交换

2. 然后,将剩下的{r[0]..r[n-2]}序列调整成堆

3. 再将 r[0]与r[n-2]交换,再将剩下的{r[0]..r[n-3]}序列调整成堆

4. 如此反复,直到整个序列有序。

5. 这个过程称为堆排序
 

3.1 筛选法调整堆:算法

//【算法】将以筛选法调整堆算法
//将以low为根的子树调整成小顶堆,low、high是序列下界和上界
public void sift(int low, int high) {int i = low;                                //子树的根int j = 2 * i + 1;                         //j为i结点的左孩子RecordNode temp = r[i];while (j < high) {  //沿较小值孩子结点向下筛选if (j < high - 1 && r[j].key.compareTo(r[j + 1].key) > 0) {j++; //数组元素比较,j为左右孩子的较小者}if (temp.key.compareTo(r[j].key) > 0) { //若父母结点值较大r[i] = r[j];           //孩子结点中的较小值上移i = j;j = 2 * i + 1;} else {j = high + 1;          //退出循环}}r[i] = temp;                   //当前子树的原根值调整后的位置
//  System.out.print("sift  " + low + ".." + high + "  ");
//  display();
}

3.2堆排序:算法

//【算法】 堆排序算法
public void heapSort() {// System.out.println("堆排序");int n = this.curlen;RecordNode temp;// 从最后一个非叶子节点开始调整堆,直到根结点for (int i = n / 2 - 1; i >= 0; i--) {//创建堆sift(i, n);}System.out.println("堆构建完成");for (int i = n - 1; i > 0; i--) {//每趟将最小值交换到后面,再调整成堆// 第一个元素和无序中的最后一个交换temp = r[0];r[0] = r[i];r[i] = temp;sift(0, i);}
}

五、交换排序:冒泡排序【稳定排序方法】

1.概述

比较相邻的元素。如果第一个比第二个大,就交换他们两个。 

  • 将待排序的数组看成从上到下的存放,关键字较小的记录看成较轻的,关键字较大的记录看成较重的。

  • 较小关键字值的记录,好像水中的气泡一样,向上浮

  • 较大关键字值的记录,好像水中的石块一样,向下沉

  • 当所有的气泡都浮到了相应的位置,并且所有的石块都沉到了水中,排序就结束了

2.算法实现

//【算法】 冒泡排序算法
public void bubbleSort() {
//    System.out.println("冒泡排序");RecordNode temp;                                    // 辅助结点boolean flag = true;                                // 是否交换的标记for (int i = 1; i < this.curlen && flag; i++) {   // 有交换时再进行下一趟,最多n-1趟flag = false;                                   // 假定元素未交换for (int j = 0; j < this.curlen - i; j++) {     // 一次比较、交换if (r[j].key.compareTo(r[j + 1].key) > 0) { // 逆序时,交换temp = r[j];r[j] = r[j + 1];r[j + 1] = temp;flag = true;							//如果发生交换,记录}}System.out.print("第" + i + "趟: ");display();}
}

六、交换排序:快速排序【不稳定排序方法】

1.概述

  • 快速排序:Quick Sort

  • 通过一趟排序将要排序的记录分割成独立的两个部分,其中一部分的所有记录的关键字值都比另外一部分的所有记录关键字值小。

  • 然后再按此方法对这两部分记录分别进行快速排序。

  • 整个排序过程可以递归进行,以此达到整个记录序列变成有序

2.算法实现

2.1一趟快速排序

//【算法】一趟快速排序
//交换排序表r[i..j]的记录,使支点记录到位,并返回其所在位置
//此时,在支点之前(后)的记录关键字均不大于(小于)它
public int Partition(int i, int j) {RecordNode pivot = r[i];          //第一个记录作为支点记录System.out.println(i + ".." + j + ",  pivot=" + pivot.key + "  ");System.out.print("初始值:     ");int c = 0;display();while (i < j) {    //从表的两端交替地向中间扫描// 1.1 从后到前,寻找第一个比支点小的元素while (i < j && pivot.key.compareTo(r[j].key) <= 0) {j--;}// 1.2 将后面较小的元素,移到前面去if (i < j) {r[i] = r[j];   //将比支点记录关键字小的记录向前移动System.out.print("第"+(++c)+"次交换后:");display();i++;}// 2.1 从前到后,选择第一恶比支点大的元素while (i < j && pivot.key.compareTo(r[i].key) > 0) {i++;}// 2.2 将前面较大的元素,移到后面去if (i < j) {r[j] = r[i];   //将比支点记录关键字大的记录向后移动System.out.print("第"+(++c)+"次交换后:");display();j--;}}r[i] = pivot;         //支点记录到位System.out.print("一趟完成:   ");display();return i;             //返回支点位置
}

2.2 完整快排

//【算法】 递归形式的快速排序算法
//对子表r[low..high]快速排序
public void qSort(int low, int high) {if (low < high) {int pivotloc = Partition(low, high);   // 一趟排序,将排序表分为两部分qSort(low, pivotloc - 1);       // 低子表递归排序qSort(pivotloc + 1, high);      // 高子表递归排序}
}//【算法完整快排】顺序表快速排序算法
public void quickSort() {qSort(0, this.curlen - 1);
}

七、归并排序:归并排序【稳定排序方法】

1.概述

归并排序是建立在归并操作上的一种有效,稳定的排序算法。是将合并得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。已有序的子序列

 归并排序:两个或两个以上有序表合并成一个新的有序表。

归并排序分类:

1. 二路归并排序

2. 多路归并排序

2.算法实现

2.1 两个相邻有序序列归并:算法

/**** @param r 待排序的数组(多个有序子序列)* @param order 已经排序号的数组* @param h 第一个子序列开始的位置* @param m 第一个子序列结束的位置,第二个子序列开始的位置为m+1* @param t 第二个子序列结束的位置*/
//【算法】两个有序序列的归并算法
//把r数组中两个相邻的有序表r[h]~r[m]和r[m+1]~r[t]归并为一个有序表order[h]~order[t]
public void merge(RecordNode[] r, RecordNode[] order, int h, int m, int t) {int i = h, j = m + 1, k = h;while (i <= m && j <= t) {                  // 将r中两个相邻子序列归并到order中if (r[i].key.compareTo(r[j].key) <= 0) {// 较小值复制到order中order[k++] = r[i++];} else {order[k++] = r[j++];}}while (i <= m) {                // 将前一个子序列剩余元素复制到order中order[k++] = r[i++];}while (j <= t) {                // 将后一个子序列剩余元素复制到order中order[k++] = r[j++];}
}

2.1 一趟归并:算法

//【算法】一趟归并算法
//把数组r[n]中每个长度为s的有序表两两归并到数组order[n]中
//s 为子序列的长度,n为排序序列的长度
public void mergepass(RecordNode[] r, RecordNode[] order, int s, int n) {System.out.print("子序列长度s=" + s + " ");int p = 0;  //p为每一对待合并表的第一个元素的下标,初值为0while (p + 2 * s - 1 <= n - 1) {  //两两归并长度均为s的有序表merge(r, order, p, p + s - 1, p + 2 * s - 1);p += 2 * s;}if (p + s - 1 < n - 1) {  //归并最后两个长度不等的有序表merge(r, order, p, p + s - 1, n - 1);} else {for (int i = p; i <= n - 1; i++) //将剩余的有序表复制到order中{order[i] = r[i];}}
}

2.1 二路归并: 算法

//打印方法
public void display(RecordNode[] arr) {    //输出数组元素for (int i = 0; i < arr.length; i++) {String str = arr[i].key.toString().length() == 1 ? "  " : " ";System.out.print(str + arr[i].key.toString());}System.out.println();
}//【算法】2-路归并排序算法
public void mergeSort() {System.out.println("归并排序");int s = 1;                              // s为已排序的子序列长度,初值为1int n = this.curlen;RecordNode[] temp = new RecordNode[n];  // 定义长度为n的辅助数组tempwhile (s < n) {mergepass(r, temp, s, n);           // 一趟归并,将r数组中各子序列归并到temp中display(temp);                      // 打印temp临时数组s *= 2;                             // 子序列长度加倍,下一趟归并mergepass(temp, r, s, n);           // 将temp数组中各子序列再归并到r中display();                          // 打印r数组s *= 2;}
}

写到最后

四季轮换,已经数不清凋零了多少, 愿我们往后能向心而行,一路招摇胜!

🐋 你的支持认可是我创作的动力

💟 创作不易,不妨点赞💚评论❤️收藏💙一下

😘 感谢大佬们的支持,欢迎各位前来不吝赐教

相关内容

热门资讯

清明节经典祝福短信 清明节经典祝福短信集锦  1:清明时节,杨柳依依,古人有“折柳赠别”的习俗,我无柳可折,给你发条短信...
营销追踪短信 营销追踪短信总经理室贺电:临淄服务部在5.18节点全面达成45联动计划任务的106%,对你们取得的骄...
沈石溪最后一头战象优秀读后感 沈石溪最后一头战象优秀读后感范文(精选20篇)  读完一本书以后,大家一定对生活有了新的感悟和看法,...
无犯罪记录证明英文 无犯罪记录证明英文无犯罪记录证明英文May 5, 2010To Whom It May Concer...
给好朋友的一封信 给好朋友的一封信精选15篇  在学习、工作或生活中,大家都经常接触到书信吧,书信是一种用文字来表情达...
给孩子鼓励一封信 给孩子鼓励一封信(精选7篇)  无论是在学校还是在社会中,大家都不可避免地会接触到书信吧,书信是一种...
关于经验交流会发言稿范文 关于经验交流会发言稿范文  发言稿的分类  按用途、性质来划分,讲话稿主要有以下几种:  (1)开幕...
工程委托书 工程委托书范文(通用6篇)  委托他人代表自己行使自己的合法权益,被委托人在行使权力时需出具委托人的...
羊年祝福短信 羊年祝福短信15篇  在日常学习、工作抑或是生活中,大家都用到过短信吧,短信可以起到增进人与人之间交...
服饰礼仪原则 服饰礼仪原则  在什么场合,是什么身份,就着什么样的服装,这是第一原则。整洁合体不怪异:一定要整洁、...
本地化服务承诺书 本地化服务承诺书  在现在社会,承诺书使用的情况越来越多,承诺书是承诺人对要约人的要约完全同意的意思...
学校运动会裁判员代表发言稿 学校运动会裁判员代表发言稿  裁判员要及时到位,客观、公正地履行裁判职责。给每一个运动员的付出,进行...
最新幼儿教师师德承诺书 最新幼儿教师师德承诺书  在我们平凡的日常里,接触并使用承诺书的人越来越多,不同的承诺书内容同样也是...
酒店前台接待礼仪标准常识 酒店前台接待礼仪标准常识  了解和践行接待礼仪,对于做好接待工作具有极其重要的意义。下面是小编精心整...
韩国礼仪知识 韩国礼仪知识韩国礼仪知识1  在韩国,长辈对晚辈可以称呼对方的名字,可不带其姓,在社会交往活动中,相...
优秀主持人开场白 优秀主持人开场白(通用10篇)  在当下社会,我们经常会看到一些用到开场白的场景,独具匠心的开场白,...
违反生活纪律检讨书 违反生活纪律检讨书(精选19篇)  在学习、工作或生活中出现了过错后,就需要写一份自我检讨书好好进行...
给医院感谢信 给医院感谢信4篇  在越来越重视感恩意识提升的今天,感谢信的使用者越来越多,我们在写感谢信的时候要注...
三方协议解约证明模板   三方协议一旦签订之后,任何一方不得擅自解除,否则违约方应向权利受损方支付协议条款所规定的违约金,...
淘宝店铺感谢信模板   淘宝店铺感谢信范应该怎么写?下面是unjs整理的关于淘宝店铺感谢信范文,欢迎借鉴!  淘宝店铺感...