快速排序(数组和链表)
来源:互联网 发布:知之阅读 pdf 编辑:程序博客网 时间:2024/06/04 01:05
本文介绍的是数组和单链表的快速排序。
首先介绍一下快速排序:
快速排序的思想是基于分治的。在待排序表L[ 1,2...N ] 中任取一个元素作为基准 pivot ,通过一趟排序将待排序表划分为独立的两个部分 L[ 1,2...K-1 ] 和 L[ K+1...N ],
使得 L[ 1,2...K-1 ] 中所有元素的值都小于 pivot ,L[ K+1...N ] 中的所有元素都大于等于 pivot 的值,则 pivot 放在中间的 L[K] 的位置上,这个过程完成了一次快速排序。
然后分别对两个字表进行递归 ,重复上面两个动作,直到每个部分都只有一个元素或者为空为止,这就会使每个元素都放在了最终的位置。
效率分析:
空间:因为是递归完成的,所以需要借助一个递归栈来完成。当已经有序时,会进行 N-1 次递归,此时的递归层次最多,栈的深度为O(N)。但平均情况下,还是比较好的,
为O(LogN)。
时间:运行时间与划分是否对称有关系,所以中枢值得选择就是比较重要的了。可以参照STL中对于中枢值得选取。一般情况下,时间复杂度是O(NLogN)。
以下给出对于 数组 的快速排序算法:
首先,声明了一个容器 Vector:
// 以下是对容器的声明vector<int> v{10,4,9,12,7,6,18,1,25};
容器声明完成以后,就可以对其进行快速排序:
void QuickSort( vector<int> &v, int low, int high ){ // 满足递归的条件 if ( low < high ) { // 这里是对容器的划分的方法 int key = Partition( v,low,high ); // 依次对其左右两个区间进行快速排序操作 QuickSort( v, low, key ); QuickSort( v, key+1, high); }}
int Partition( vector<int> &v, int low, int high ){ // 获取中枢值 int key = v[low]; // 划分的主程序 while( low < high ) { while( v[high] > key && high > low ) high--; v[low] = v[high]; while( v[low] < key && low < high) low++; v[high] = v[low]; } v[low] = key; return low;}
对以上声明的容器调用快速排序和排序后的结果输出:
// 调用快速排序QuickSort( v,0,v.size()-1 );// 输出,通过调用仿函数实现for_each( v.begin(),v.end(), print<span style="font-family: Arial, Helvetica, sans-serif;">() );</span>以下给出仿函数的定义:
具体仿函数的使用,参照其他博客
class print{public: void operator()( const int i ) { cout << i << " "; }};以上就是对数组的快速排序。
下面给出相对于链表的快速排序的算法:
先给出链表节点的定义:
struct Link{ int value; struct Link *next; Link():value(0),next(nullptr){} Link(int x):value(x),next(nullptr){}};typedef struct Link node;
以下给出快速排序的思想,具体解释见注释:
// 注意这里形参的声明方法,一定要加上 & 符号// 仔细想想为什么void QuickSort( node* &head , node* &end ){ // 声明四个节点,方便保存分开后的左右两个链表 node *head1,*end1,*head2,*end2; head1 = end1 = head2 = end2 = nullptr; if ( head == nullptr ) return; node *p,*pre1,*pre2; p = pre1 = pre2 = nullptr; // 取出一个节点作为中枢点 int key = head->value; // 将头节点孤立出来 p = head->next; head->next = nullptr; while( p != nullptr ) { // 左 if( p->value < key ) { // 头结点为空的情形 if ( head1 == nullptr ) { head1 = p; pre1 = p; } else // 头结点非空的情形 { pre1->next = p; pre1 = p; } p = p->next; pre1->next = nullptr; } else { if ( head2 == nullptr ) { head2 = p; pre2 = p; } else { pre2->next = p; pre2 = p; } p = p->next ; pre2->next = nullptr; } } // 给出尾节点 end1 = pre1; end2 = pre2; // 分别对左右两个区间进行快速排序 QuickSort(head1,end1); QuickSort(head2,end2); // 排序之后,链表的融合 if ( head1 != nullptr && head2 != nullptr) { end1->next = head; head->next = head2; head = head1; end = end2; } else if ( head1 != nullptr ) { end1->next = head; end = head; head = head1; } else if ( head2 != nullptr ) { head->next = head2; end = end2; }}
1 0
- 快速排序(数组和链表)
- 快速排序(数组和链表版本)
- 数组和快速排序
- 数组的插入排序和快速排序
- 数组冒泡排序 和 快速排序
- 快速排序-c++(分别用数组和容器实现)
- 快速排序(二维数组)
- 数组(五)--快速排序
- 数组去重和快速排序
- php关联数组排序(快速排序)
- 数组排序-快速排序
- 单向链表排序:快速排序和归并排序
- Java实现数组的快速排序(快速排序算法)
- 测试int和Integer数组的排序/快速排序实现
- Go语言对数组进行冒泡排序和快速排序
- 用数组实现快速排序(C++)
- 快速排序+划分数组(java实现)
- 单向链表的冒泡排序和快速排序
- hibernate3.3.2学习笔记---将一棵树存进数据库
- LeetCode 409. Longest Palindrome 题解(C++)
- python学习之 图片隐写术
- 树莓派3b下如何安装ubuntu
- linux 中的编译指令make 和make clean
- 快速排序(数组和链表)
- PHP中WEB典型应用技术
- 课时09 第二节课程:解析网页中的元素
- XCoreRedux框架:Android UI组件化与Redux实践
- Swift 04 观察者模式 Observer Pattern
- springMVC简单描述
- python3 CGI编程
- 博客搬家
- linux之grep、find、wc