快速排序 数组 单链表
来源:互联网 发布:闲鱼淘宝介入提交凭证 编辑:程序博客网 时间:2024/05/17 01:29
数组快速排序
快排注意知识点:
- 每一趟排序,都有一个元素会放到其最终的位置上
- 快排是个不稳定的算法
- 最好情况 最坏情况的区别
–运行时间 与 划分的区间是否对称 相关
最好, 时间复杂度 O(nlog2n)
最坏, 时间复杂度 O(n^2)
下面是参考严版教材的快排,可以敲上n遍了,debug运行 看每一步的结果
#include <stdio.h>int a[50] = { 21, 25, 5, 17, 9, 23, 30, 0, 25, 21 };int partion(int low, int high) { // 一趟排序 int pivot = a[low]; while (low < high) { while (low < high && a[high] >= pivot) --high; a[low] = a[high]; while (low < high && a[low] < pivot) ++low; a[high] = a[low]; } a[low] = pivot; // 此时low 就是pivot 最终的位置 return low; // 返回最终确定的位置}void myqsort(int low, int high){ if (low >= high) return ; int left = low; int right = high; // 一趟排序 int pivot = a[low]; while (low < high) { // 从右往左 找到第一个小于pivot的 进行交换 while (low < high && a[high] >= pivot) --high; a[low] = a[high]; // 从左往右 找到第一个大于等于pivot的 进行交换 while (low < high && a[low] < pivot) ++low; a[high] = a[low]; } a[low] = pivot; // 此时low 就是pivot 最终的位置 // 下面递归 myqsort(left, low - 1); myqsort(low + 1, right);}void pf(int n){ int i; for (i = 0; i < n; i++) { printf("%d ", a[i]); } printf("\n");}int main(){ int n = 10; myqsort(0, n-1); pf(n); return 0;}
单链表快速排序
leetcode上面用来检测自己的代码正确性,时空复杂度
https://leetcode.com/problems/insertion-sort-list/
参考
http://www.jb51.net/article/37300.htm
http://blog.csdn.net/wumuzi520/article/details/8078322
代码总结
partion 思路
- 支点的选取,由于不能随机访问第K个元素,因此每次选择支点时可以取待排序那部分链表的头指针。
- 遍历量表方式,由于不能从单链表的末尾向前遍历,因此使用两个指针分别向前向后遍历的策略实效,
事实上,可以可以采用一趟遍历的方式将较小的元素放到单链表的左边。具体方法为:- 定义两个指针pslow,pfast,其中pslow指向单链表的头结点,pfast指向单链表头结点的下一个结点;
- 使用pfast遍历单链表,每遇到一个比支点小的元素,就先令pslow=pslow->next,然后pslow与pfast进行数据交换。
- 交换数据方式,直接交换链表数据指针指向的部分,不必交换链表节点本身。
struct ListNode { int val; ListNode *next; ListNode(int x) : val(x), next(NULL) {}};/*1、支点的选取,由于不能随机访问第K个元素,因此每次选择支点时可以取待排序那部分链表的头指针。2、遍历量表方式,由于不能从单链表的末尾向前遍历,因此使用两个指针分别向前向后遍历的策略实效,事实上,可以可以采用一趟遍历的方式将较小的元素放到单链表的左边。具体方法为:1)定义两个指针pslow,pfast,其中pslow指向单链表的头结点,pfast指向单链表头结点的下一个结点;2)使用pfast遍历单链表,每遇到一个比支点小的元素,就令pslow=pslow->next,然后和pslow进行数据交换。3、交换数据方式,直接交换链表数据指针指向的部分,不必交换链表节点本身。*/ListNode* partion(ListNode* head, ListNode* end){ if (head == end) return head; ListNode* pHead = head; ListNode* pSlow = head; // pSlow和pSlow之前的都要小于等于pHead ListNode* pFast = head->next; while (pFast != end) { if (pFast->val < pHead->val) { pSlow = pSlow->next;// pSlow 先向后移动 int tmpVal = pFast->val; //交换pSlow和pFast的值 pFast->val = pSlow->val; pSlow->val = tmpVal; } pFast = pFast->next; } int tmpVal = pSlow->val; // 最后与头节点交换 pSlow->val = pHead->val; pHead->val = tmpVal; return pSlow;}void qsortList(ListNode* head,ListNode* end){ if (head == NULL || head == end || head->next == end) return; ListNode* mid = partion(head, end); qsortList(head, mid); qsortList(mid->next, end);}int main(){ ListNode* p1 = new ListNode(4); ListNode* p2 = new ListNode(2); ListNode* p3 = new ListNode(5); ListNode* p4 = new ListNode(3); ListNode* p5 = new ListNode(7); ListNode* p6 = new ListNode(9); ListNode* p7 = new ListNode(0); ListNode* p8 = new ListNode(1); p1->next = p2; p2->next = p3; p3->next = p4; p4->next = p5; p5->next = p6; p6->next = p7; p7->next = p8; //partion(p1, NULL); qsortList(p1, NULL);}
交换节点,但是复杂度会比较大,应为每次都要遍历重复的
struct ListNode { int val; ListNode *next; ListNode(int x) : val(x), next(NULL) {}};ListNode* partion(ListNode* head, ListNode* end){ if (head == end || head->next == end) return head; ListNode* pHead = head; ListNode* lpart = NULL; ListNode* lend = NULL; ListNode* rpart = NULL; ListNode* rend = NULL; ListNode* pScan = head->next; while (pScan != end) { if (pScan->val < pHead->val) { if(lpart == NULL) { lpart = lend = pScan; }else{ lend->next = pScan; lend = lend->next; } }else{ if(rpart == NULL) { rpart = rend = pScan; }else{ rend->next = pScan; rend = rend->next; } } pScan = pScan->next; } if(lend != NULL) lend->next = NULL; if(rend != NULL) rend->next = NULL; // 按照左部分,partion节点,右部分再次连接成新的链表 ListNode* le = partion(lpart,NULL); ListNode* re = partion(rpart,NULL); ListNode *newHead = pHead; if(le != NULL){ newHead = le; ListNode* leTail = le; //找到le的尾节点 ListNode* letmp = le; while(letmp != NULL){ leTail = letmp; letmp = letmp->next; } leTail->next = pHead; } pHead->next = re; return newHead;}int main(){ ListNode* p1 = new ListNode(4); ListNode* p2 = new ListNode(2); ListNode* p3 = new ListNode(5); ListNode* p4 = new ListNode(3); ListNode* p5 = new ListNode(7); ListNode* p6 = new ListNode(9); ListNode* p7 = new ListNode(0); ListNode* p8 = new ListNode(1); p1->next = p2; p2->next = p3; p3->next = p4; p4->next = p5; p5->next = p6; p6->next = p7; p7->next = p8; ListNode * pp = partion(p1, NULL); return 0;}
0 0
- 快速排序 数组 单链表
- 数组排序-快速排序
- 二维数组快速排序
- 数组实现快速排序
- JAVA数组快速排序
- iOS数组快速排序
- 数组快速排序,selecter
- int数组快速排序
- 数组和快速排序
- 快速排序:数组
- php数组快速排序
- 数组快速排序
- 数组&链表 快速排序
- 数组快速排序
- 二维数组快速排序
- js数组快速排序
- 数组 冒泡排序 , 快速排序
- 数组 快速排序 递归算法
- Linux 目录结构
- svn error:Subversion requires SQLite解决
- Leetcode: Sqrt(x)
- excel 宏脚本开发小案例
- Eclipse Maven 编译错误 Dynamic Web Module 3.0 requires Java 1.6 or newer 解决方案
- 快速排序 数组 单链表
- Android 开发和学习资源总结
- AngularJs学习总结
- mysql字段长度的问题
- 基本排序算法--插入排序
- Java开发熟手该当心的错误
- 放苹果(递归)
- WiFi芯片的主要厂家
- 制作Linux发行版U盘运行系统