链表的快速排序
来源:互联网 发布:三维软件是什么 编辑:程序博客网 时间:2024/06/05 19:52
首先,回忆一下数组的快排步骤:
函数参数: 数组arr, 起点nLow, 终点nHigh
功能: 把nLow 至 nHigh 段的数组进行一次快排。
结果:【比nMark小的元素】nMark【比nMark大的元素】
#区间分割法 1. 取最后一个元素为标记,用nSmall标记小区间大小,i 用来遍历数组; 2. 遍历值小于标记值:小区间的下一个不是当前位置,需要交换,否则直接小区间位置+1 3. 如此循环到 标记位置(最后一个元素) 4. 将标记元素(即最后一个元素)放到 s+1 的位置;
数组快排的链接: 快速排序(不稳定)挖坑填补法+区间分割法+3种优化方法
由此,我们写一下链表的步骤:
函数参数: List*pBegin,List*pEnd
1. 取第一个元素作为标记元素, 用pSmall指针,指向首元素;2. 使用pTemp遍历链表, 找到找到小于标记的元素,将pSmall移到下一位置; 若下一个位置不是当前位置, 将pSmall 和 pTemp 的元素进行交换;3. 重复 2, 直到pTemp == pEnd;4. 此时pSmall 指向小链表的最后一个元素, 将这个元素和标记元素(链表头)进行交换;5. 分别递归前半部分和后半部分;
先上代码,再分析:
//链表的快排void QuickSort2(List* pBegin, List* pEnd){ if (pBegin == NULL) return; if (pBegin == pEnd) return; int nTemp; //1. 取第一个元素作为标记元素, 用pSmall指针,指向首元素; int nMark = pBegin->nvalue; List* pSmall = pBegin; //2. 使用pTemp遍历链表 List* pTemp = pBegin->pNext; while (pTemp != pEnd) { //2.1 找到找到小于标记的元素,将pSmall移到下一位置; if (pTemp->nvalue < nMark) { pSmall = pSmall->pNext; //2.2 若下一个位置不是当前位置, 将pSmall 和 pTemp 的元素进行交换; if (pSmall != pTemp) { nTemp = pTemp->nvalue; pTemp->nvalue = pSmall->nvalue; pSmall->nvalue = nTemp; } } pTemp = pTemp->pNext; } //把小链表的最后一个元素和头(标记)交换 //这样pSmall 前就是比nMark小的,后就是比nMark大的; //这块就是把: 16,9,5,15,8,23 --》 8,9,5,15,16,23; nTemp = pSmall->nvalue; pSmall->nvalue = pBegin->nvalue; pBegin->nvalue = nTemp; //while 循环判断,刚好不需要判断最后一个元素,因此就把pSmall 跳过了; QuickSort2(pBegin, pSmall); QuickSort2(pSmall->pNext, pEnd);}int main(){ int arr[] = {16,9,23,5,15,8}; Mylist list; List* pList = list.CreateaaList(arr, sizeof(arr) / 4); list.Print(pList); QuickSort2(pList, NULL); list.Print(pList); system("pause"); return 0;}
解释一下, 递归的参数问题:
在数组的快排中,我们是这样写的,先一次快排,将元素分成两部分, 前部分比标记小,后部分比标记大。返回标记位置,再对 标记的前后两部分进行排序;标记元素已经确定位置,不需要再参加排序了。
int nStandard = Sort(arr, nLow, nHigh); QuickSort(arr, nLow, nStandard -1); QuickSort(arr, nStandard+1, nHigh);
在 链表的快排中, 循环判断条件是 pTemp != pEnd, 也就是pEnd 这一位没有进行判断是否加入小链表中。
在函数调用时,我们传入的参数是 QuickSort2(pList, NULL);
所以刚好pTemp是从头判断到尾。
进行递归的时候, 传入的pSmall 刚好就不被判断。完成“已经确定位置的标记元素,不需要再参加排序了。” 这一规则。
QuickSort2(pBegin, pSmall); QuickSort2(pSmall->pNext, pEnd);
在开始写的时候, 总想着需要记录pSmall 的前一个元素, 然后递归的时候传
头 — small 前一个, small 后一个—-尾;
这样看似没问题,但是总是跳过元素,然后程序就崩了, 就是没理解好这块。
阅读全文
0 0
- 链表的快速排序
- 链表的快速排序
- 链表排序--快速排序
- 双向链表的快速排序
- 双向链表的快速排序
- 基于链表的快速排序
- 链表的QuickSort快速排序法
- 算法:链表的快速排序法
- 链表的快速排序法
- 链表快速排序
- 链表快速排序
- 快速排序链表
- 链表快速排序
- 单向链表的冒泡排序和快速排序
- 链表的快速排序及冒泡排序
- 基于链表的快速排序及归并排序
- 单向链表快速排序
- 单向链表快速排序
- 《信号与系统学习笔记》—信号与系统(一)
- 微信回复图文和多图文
- 游戏服务器开发的基本体系与服务器端开发的一些建议
- JavaScript-DOM2和DOM3
- android 点击通知栏消息打开activity,如果app未运行先启动app或打开activity返回后再启动app
- 链表的快速排序
- caffe模型各层的描述
- Ubuntu下安装Opencv(cv2)
- input标签的size和maxlength属性探究
- D3.js实现树图节点为矩形+内容分割+可折叠demo
- Hibernate 一对多注解 实例
- 士兵杀敌(五)
- Python httplib2异常以及互动方式
- Error:Unknown host 'downloads.gradle.org'. Enable Gradle 'offline mode' and sync project