1.

堆排序是一种优秀的排序算法,时间复杂度O(nlogn),主要思想是用数组构造一个最大堆,满足跟节点的value>子节点的value,然后将堆顶元素(value最大)与最后一个叶子节点交换,再调整堆,使其满足最大堆的性质,重复上述步骤n-1次后就得到一个有序序列。

 #include<iostream>
#include<cstdio>
#include<cstring>
#define MAX 111111
#define LEFT(i) (i << 1)
#define RIGHT(i) (i << 1|1)
using namespace std;
int a[MAX], Heap_Size, a_Length;
void Max_Heapify(int i){
int largest, l, r;
l = LEFT(i);
r = RIGHT(i);
if(l <= Heap_Size && a[l] > a[i]) largest = l;
else largest = i;
if(r <= Heap_Size && a[r] > a[largest]) largest = r;
if(largest != i){
int temp = a[i];
a[i] = a[largest];
a[largest] = temp;
Max_Heapify(largest);
}
return;
}
void Build_Heap(){
for(int i = a_Length/; i >= ; i --)
Max_Heapify(i);
return;
}
void Heap_Sort(){
Build_Heap();
for(int i = a_Length; i >= ; i --){
int temp = a[];
a[] = a[i];
a[i] = temp;
Heap_Size--;
Max_Heapify();
}
return ;
}
int main(){
freopen("data.cpp", "r", stdin);
freopen("out.cpp", "w", stdout);
while(~scanf("%d", &a_Length)){
Heap_Size = a_Length;
for(int i = ; i <= a_Length; i ++) scanf("%d", a+i);
Heap_Sort();
printf("Length = %d\n", a_Length);
for(int i = ; i < a_Length; i ++) printf("%d ", a[i]);
printf("%d\n\n\n", a[a_Length]);
}
return ;
}

2.

快速排序:主要思想就是随机选定一个数x,以该数为基准,将数组划分,左边都小于或等于它,右边都大于它,这样就将数组划分成左右两部分,而数x则是处于正确位置,然后再重复上述过程分别处理左右部分,直到数组有序。时间复杂度O(nlogn).

 #include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#define MAX 111111
using namespace std;
int a[MAX], a_length;
int Rand_Partition(int p, int r){
int x = a[r], i = p-;
for(int j = p; j < r; j ++){
if(a[j] <= x){
i ++;
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
a[r] = a[i+];
a[i+] = x;
return i+;
}
void Qucik_Sort(int p, int r){
if(p < r){                //与调用Rand_Partition()函数效果一样;
int i = p-;
for(int j = p; j < r; j ++){
if(a[j] <= a[r]){
i ++;
swap(a[i], a[j]);
}
}
swap(a[r], a[i+]);
int q = i+;             //end;
/* int q = Rand_Partition(p, r); */
Qucik_Sort(p, q-);
Qucik_Sort(q+, r);
}
}
int main(){
freopen("data.cpp", "r", stdin);
freopen("Quick_sort_out.cpp", "w", stdout);
while(~scanf("%d", &a_length)){
printf("Length = %d\n", a_length);
for(int i = ; i < a_length; i ++) scanf("%d", a+i);
Qucik_Sort(, a_length-);
for(int i = ; i < a_length-; i ++) printf("%d ", a[i]);
printf("%d\n\n\n", a[a_length-]);
}
return ;
}

3.

归并排序,采用分治策略,主要思想是假定数组a和b已经是有序的,那么可以在O(n)的时间内将他们合并成一个有序序列,现在将数组平均分成两部分,但这两部分并不是有序的,因此需要再次将这两个部分再分,使问题规模逐渐变小,继续递归划分,当子数组足够小时(即只有一个元素),可以直接求解,因为此时一个元素就是有序的。然后就可以合并这两个部分了,合并完之后就形成一个局部有序序列(我们最终要得到整个有序序列),此时向上回溯与其他有序部分进行合并,当回溯到跟节点时,整个序列就合并完毕,因此得到一个有序序列。

分治策略一般分为三步:(1):分解原问题使问题规模变小以便我们直接处理,对于上述问题就是将原序列分解,当分解到子序列只有一个元素时就可直接求解(因为一个元素的序列已经是有序的了);(2)治,即解决问题;(3)合并,将子问题解决之后要向上合并从而得到原问题的解。

分治策略一般使用递归来实现。

 #include<stdio.h>
#include<string.h>
int a[];
int l[];
int r[];
void merge(int p, int mid, int q)
{
int nl = mid - p + ;
int nr = q - mid;
int i, j, k;
for(i = ; i < nl; i ++)
l[i] = a[p+i];
for(i = ; i <= nr; i ++)
r[i - ] = a[mid+i];
l[nl] = << ;
r[nr] = << ;
i = ;
j = ;
for(k = p; k <= q; k ++)
{
if(l[i] <= r[j])
a[k] = l[i++];
else
a[k] = r[j++];
}
} void merge_sort(int l, int r)
{
if(l < r)
{
int mid = (l + r) >> ;
merge_sort(l, mid);
merge_sort(mid + , r);
merge(l, mid, r);
}
} int main(int argc, char const *argv[])
{
int n, i;
freopen("data.cpp", "r", stdin);
freopen("Merge_out.cpp", "w", stdout);
while(~scanf("%d", &n))
{
printf("Length = %d\n", n);
for(i = ; i < n; i ++)
scanf("%d", &a[i]);
merge_sort(, n-);
for(i = ; i < n-; i ++)
printf("%d ",a[i]);
printf("%d\n\n\n", a[i]);
}
return ;
}

4.

最后一个是用二叉搜索树通过中序遍历得到的有序序列,时间复杂度也是O(nlogn)较简单和容易理解。

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
using namespace std;
typedef struct Node{
int key;
Node *left;
Node *right;
Node(){
left = NULL;
right = NULL;
}
}Node;
Node *root;
stack<Node*>s;
void Insert(int key){
Node *tmp = new Node();
tmp->key = key;
Node *ff = root;
Node *flag = NULL;
while(ff){
flag = ff;
if(key <= ff->key) ff = ff->left;
else ff = ff->right;
}
if(flag == NULL){
root = new Node();
root->key = key;
return;
}
if(flag->key >= key) flag->left = tmp;
else flag->right = tmp;
} void Visist_Treee_1(Node *tmp){
if(tmp){
Visist_Treee_1(tmp->left);
printf("%d ", tmp->key);
Visist_Treee_1(tmp->right);
}
} /* void Visist_Treee_2(Node *tmp){ */
/* while(!s.empty()) s.pop(); */
/* s.push(tmp); */
/* while(!s.empty()){ */
/* Node *p = s.top(); */
/* s.pop(); */
/* while(p->left) s.push(p), p = p->left; */
/* Node *q = s.top(); */
/* s.pop(); */
/* printf("%d ", q->key); */
/* if(q->right) s.push(q); */
/* } */
/* } */ int main(){
int n, temp;
freopen("data.cpp", "r", stdin);
freopen("Binary_Tree_out.cpp", "w", stdout);
while(~scanf("%d", &n)){
root = NULL;
printf("Length = %d\n", n);
for(int i = ; i < n; i ++){
scanf("%d", &temp);
Insert(temp);
}
Visist_Treee_1(root);
printf("\n\n\n");
/* Visist_Treee_2(root); */
}
}

排序 O(nlogn)的更多相关文章

  1. 备战秋招之十大排序——O(nlogn)级排序算法

    时间复杂度O(nlogn)级排序算法 五.希尔排序 首批将时间复杂度降到 O(n^2) 以下的算法之一.虽然原始的希尔排序最坏时间复杂度仍然是O(n^2),但经过优化的希尔排序可以达到 O(n^{1. ...

  2. JS实现常用排序算法—经典的轮子值得再造

    关于排序算法的博客何止千千万了,也不多一个轮子,那我就斗胆粗制滥造个轮子吧!下面的排序算法未作说明默认是从小到大排序. 1.快速排序2.归并排序3.冒泡排序4.选择排序(简单选择排序)5.插入排序(直 ...

  3. js实现各种常用排序算法

    1.冒泡排序 var bubbleSort = function (arr) { var flag = true; var len = arr.length; for (var i = 0; i &l ...

  4. 常用的 JS 排序算法整理

    关于排序算法的问题可以在网上搜到一大堆,但是纯 JS 版比较零散,之前面试的时候特意整理了一遍,附带排序效率比较. //1.冒泡排序 var bubbleSort = function(arr) { ...

  5. 我们一起来排序——使用Java语言优雅地实现常用排序算法

    破阵子·春景 燕子来时新社,梨花落后清明. 池上碧苔三四点,叶底黄鹂一两声.日长飞絮轻. 巧笑同桌伙伴,上学径里逢迎. 疑怪昨宵春梦好,元是今朝Offer拿.笑从双脸生. 排序算法--最基础的算法,互 ...

  6. Java实现:数据结构之排序

    Java实现:数据结构之排序 0.概述 形式化定义:假设有n个记录的序列(待排序列)为{ R1, R2 , -, Rn },其相应的关键字序列为 { K1, K2, -, Kn }.找到{1,2, - ...

  7. 各种排序算法的总结、比较与Java实现

    1 快速排序(QuickSort) 快速排序是一个就地排序,分而治之,大规模递归的算法.从本质上来说,它是归并排序的就地版本.快速排序可以由下面四步组成. (1) 如果不多于1个数据,直接返回.(2) ...

  8. 九度OJ 1349:数字在排序数组中出现的次数 (排序、查找)

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:2489 解决:742 题目描述: 统计一个数字在排序数组中出现的次数. 输入: 每个测试案例包括两行: 第一行有1个整数n,表示数组的大小. ...

  9. 几种常见排序算法的java实现

    一.几种常见的排序算法性能比較 排序算法 最好时间 平均时间 最坏时间 辅助内存 稳定性 备注 简单选择排序 O(n^2) O(n^2) O(n^2) O(1) 不稳定 n小时较好 直接插入排序 O( ...

随机推荐

  1. Ambiguous handler methods mapped for HTTP path

    一.问题:映射重复导致的错误 java代码如下: @RequestMapping(value = "/info/{remove}/{id}", method = RequestMe ...

  2. checkbox 选择一个checkbox,其他checkbox也会选择

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xht ...

  3. HDU 3681 Prison Break(状态压缩dp + BFS)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3681 前些天花时间看到的题目,但写出不来,弱弱的放弃了.没想到现在学弟居然写出这种代码来,大吃一惊附加 ...

  4. 暑假集训(1)第六弹 -----简单计算器(Hdoj1237)

    Description 读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值.   Input 测试输入包含若干测试用例,每个测试用例占一行,每行不超过200个字符,整数和运算 ...

  5. 2016.08.06计算几何总结测试day1

    T1 bzoj1132[POI2008]TRO 还是太弱了....测试时看到这题直接懵逼,极角排序什么的根本想不起来,只会n^3暴力怎么破......不过竟然有84.....QAQ 正解是n^2log ...

  6. Google Map 自定义 infowindow

    最近做的东西用到了infowindow,不过google提供的样式太难看了,于是想改变一下样式.看了一下好像infowindow的样式不太好改. 查了半天资料,看到一个infobox,感觉真的挺好用. ...

  7. const和define的使用区别

    在PHP中(PHP 4及以后),我们可以使用函数define()来定义常量,例如: <?php define('PI',3.14159);  //定义一个名为PI的常量 echo PI;     ...

  8. php代码锁

    在为台湾公司开发“保证金交易系统”的过程中,出现了这样的情况: 一个间银行有n个操作员,可以同时在系统中下单,系统需要判断银行的保证金是否足够来决定是否可以下单成功.账号保证金足够,正常下单,账号保证 ...

  9. MySQL簇-cluster

    http://www.php100.com/manual/MySQL/ndbcluster.html 先做个标记吧.

  10. Objective-C中的const ,extern,static

    一.const 1>对于const,记住关键的一点,它只是修饰右边的变量. 例如: - (void)viewDidLoad { [super viewDidLoad]; // const两种用法 ...