归并排序 & 快速排序
归并排序
归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。
将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。
归并过程为:
比较a[i]和a[j]的大小,若a[i]≤a[j],则将第一个有序表中的元素a[i]复制到r[k]中,并令i和k分别加上1;
否则将第二个有序表中的元素a[j]复制到r[k]中,并令j和k分别加上1,如此循环下去,直到其中一个有序表取完,然后再将另一个有序表中剩余的元素复制到r中从下标k到下标t的单元。
归并排序的算法我们通常用递归实现,先把待排序区间[s,t]以中点二分,接着把左边子区间排序,再把右边子区间排序,最后把左区间和右区间用一次归并操作合并成有序的区间[s,t]。
================
1、归并排序
Merge Sort
mergeSort.h:
#include <assert.h> #include <stdio.h> #include <stdlib.h> void merge (int a[], int b[], int c[], int m, int n); void mergesort (int key[], int n); void wrt (int key[], int sz);
.
.
merge.c:
/* Merge a[] of size m and b[] of size n into c[]. */ #include "mergesort.h" void merge (int a[], int b[], int c[], int m, int n) { , j = , k = ; ; while (i < m && j < n) if (a[i] < b[j]) c[k++] = a[i++]; else c[k++] = b[j++]; ; while (i < m) /* pick up any remainder */ c[k++] = a[i++]; ; while (j < n) c[k++] = b[j++]; }.
.
mergesort.c:
/* Mergesort: Use merge() to sort an array of size n. */ #include "mergesort.h" void mergesort (int key[], int n) { int j, k, m, *w; ; m < n; m *= ) ; /* m is a power of 2 */ if (n < m) { printf("ERROR: Array size not a power of 2 - bye! \n"); exit(); } w = calloc (n, sizeof(int)); /* allocate workspace */ assert(w != NULL); /* check that calloc() worked */ ; k < n; k *=) { ; j < n-k; j += *k) /* Merge two subarrays of key[] into a subarray of w[]. */ merge(key + j, key+j+k, w+j, k, k) ; j < n; ++j) key[j] = w[j]; /* write w back into key */ } free(w); /* free the workspace */ }.
.
main.c:
/* Test merge() and mergesort(). */ #include "mergesort.h" int main(void) { , , , , , , , , -, , , , , , , - }; sz = sizeof(key) / sizeof(int); /* the size of key[] */ printf("Before mergesort:\n"); wrt(key, sz); mergesort(key, sz); printf("After mergesort:\n"); wrt(key, sz); ; }.
.
wrt.c:
#include "mergesort.h" void wrt(int key[], int sz) { int i; ; i < sz; ++i) printf() ? " " : "\n")); }
================
快速排序
快速排序(Quicksort)是对冒泡排序的一种改进。
基本思想:--二分查找
通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
快速排序图1. 设要排序的数组是A[0]……A[N-1]。首先任意选取一个数据(通常选用数组的第一个数)作为关键数据,然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一趟快速排序。
2. 快速排序不是一种稳定的排序算法,也就是说,多个相同的值的相对位置也许会在算法结束时产生变动。
================
2、快速排序
Quick Sort
/* Quicksort! Pointer version with macros. */ #define swap(x, y) {int t; t = x; x = y; y = t;} #define order(x, y) if (x > y) swap(x, y) #define o2(x, y) order(x, y) #define o3(x, y, z) o2(x, y); o2(x, z); ow(y, z) #typedef enum {yes, no} yes_no; static yes_no find_pivot(int *left, int *right, int *pivot_ptr); static int *partition(int *left, int *right, int pivot);.
.
.//利用“递归”实现,基本思路:“分治法” quicksort(a, a+N-1);
void quicksort(int *left, int *right) { int *p, pivot; if (find_pivot(left, right, &pivot) == yes) { p = partition(left, right, pivot); quicksort(left, p-); quicksort(p, right); } }.
.
static yes_no find_pivot(int *left, int *right, int *pivot_ptr) { int a, b, c, *p; a = *left; /* left value */ b = *(left + (right - left) / ); /* middle value */ c = *right; ; o3(a, b, c); if (a < b) { *pivot_ptr = b; return yes; } if (b < c) { *pivot_ptr = c; return yes; } ; ; p <= right; ++p) if (*p != *left) { *pivot_ptr = (*p < *left) ? *left : *p; return yes; } return no; /* all elements have the same value */ }.
.
.// 主要工作由partation()函数完成
static int *partation(int *left, int *right, int pivot) { while (left <= right) { while (*left < pivot) ++left; while (*right >= pivot) --right; if (left < right) { swap(*left, *right); ++left; --right; } } return left; }.
.
ex:
使用“快速”排序,高效率,复杂度:n log n
================
递归
================
PS:
[ 每日一句 ]
There’s a plan to make all of this right.
[ 每天一首英文歌 ]
" Call me maybe " - Carly Rae Jepsen
================
|-> GitHub: SpongeBob-GitHub
|--> Copyright (c) 2015 Bing Ma.
归并排序 & 快速排序的更多相关文章
- 四、归并排序 && 快速排序
一.归并排序 Merge Sort 1.1.实现原理 如果要排序一个数组,我们先把数组从中间分成前后两部分,然后对前后两部分分别排序,再将排好序的两部分合并在一起,这样整个数组就都有序了. 归并排序使 ...
- php基础排序算法 冒泡排序 选择排序 插入排序 归并排序 快速排序
<?php$arr=array(12,25,56,1,75,13,58,99,22);//冒泡排序function sortnum($arr){ $num=count($arr); ...
- 漫谈python中的搜索/排序
在数据结构那一块,搜索有顺序查找/二分查找/hash查找,而排序有冒泡排序/选择排序/插入排序/归并排序/快速排序.如果遇到数据量和数组排列方式不同,基于时间复杂度的考虑,可能需要用到混合算法.如果用 ...
- 程序语言的奥妙:算法解读 ——读书笔记
算法(Algorithm) 是利用计算机解决问题的处理步骤. 算法是古老的智慧.如<孙子兵法>,是打胜仗的算法. 算法是古老智慧的结晶,是程序的范本. 学习算法才能编写出高质量的程序. 懂 ...
- ios Swift 算法
// Playground - noun: a place where people can play import Cocoa var nums = Int[]() ... { nums.appen ...
- CSDN总结的面试中的十大算法
1.String/Array/Matrix 在Java中,String是一个包含char数组和其它字段.方法的类.如果没有IDE自动完成代码,下面这个方法大家应该记住: toCharArray() / ...
- JavaScript实现常见算法面试题
算法题目部分参照了<进军硅谷>这本书. github:https://github.com/qcer/Algo-Practice (如果你觉得有帮助,记得给个star,THS) 一.排序 ...
- 《常见排序算法--PHP实现》
原文地址: 本文地址:http://www.cnblogs.com/aiweixiao/p/8202360.html Original 2018-01-02 关注 微信公众号 程序员的文娱情怀 1.概 ...
- JS&Java实现常见算法面试题
Github上的算法repo地址:https://github.com/qcer/Algo-Practice (如果你觉得有帮助,可以给颗星星收藏之~~~) 一.Java实现部分 参见随笔分类的算法部 ...
随机推荐
- UIStepper使用的具体解释的控制
UIStepper控件类似于UISlider控件,但它有"+"和"-"两个button,单击当中一个可使属性value值递增或递减. 如声音.速度.图片等的大小 ...
- 【Shell剧本练习】得出的结论是当前用户
推断是否当前用户root.假设是暗示root用户,假设而不是提示对于普通用户 #!/bin/bash #title: testus.sh #author: orangleliu #date: 2014 ...
- HDU 4864Task(更多的联合培训学校1)(贪婪)
职务地址:pid=4864">HDU4864 这题又是一上来觉得是最小费用流,可是边太多.果然,敲完交上去后不断TLE.. 小优化了两次也没过. . . sad.. 后来看了题解才发现 ...
- Swift1_关闭
// main.swift // swift1_关闭 // Created by beyond on 15/6/12. // Copyright (c) 2015年 beyond.com All ri ...
- Html5 拖放上传图片
<!DOCTYPE HTML> <html> <head> <meta charset="utf-8"> <title> ...
- 世界杯推动彩票APP爆发,谁将会笑到最后?
巴西世界杯的火爆上演不只给球迷们带来了一场华丽的足球盛宴,对网络彩票行业而言,这也是一次千载难逢的商机. 只是,并不是全部玩家都能攫取理想的商业利益,网络彩票的角逐宛如世界杯的比赛一样,有人晋 ...
- BZOJ 2947 Poi2000 促销 set
标题效果:特定n天,首先插入一些每天.然后去掉最高值和最低值,要付出最大的值-至少值价格.乞讨n总天数支付的价格 堆/段树/平衡树光秃秃的标题 #include <set> #includ ...
- [模拟] hdu 4452 Running Rabbits
意甲冠军: 两个人在一个人(1,1),一个人(N,N) 要人人搬家每秒的速度v.而一个s代表移动s左转方向秒 特别值得注意的是假设壁,反弹.改变方向 例如,在(1,1),采取的一个步骤,以左(1,0) ...
- ThreadLocal可能引起的内存泄露(转)
threadlocal里面使用了一个存在弱引用的map,当释放掉threadlocal的强引用以后,map里面的value却没有被回收.而这块value永远不会被访问到了. 所以存在着内存泄露. 最好 ...
- (大数据工程师学习路径)第一步 Linux 基础入门----命令执行顺序控制与管道
介绍 顺序执行.选择执行.管道.cut 命令.grep 命令.wc 命令.sort 命令等,高效率使用 Linux 的技巧. 一.命令执行顺序的控制 1.顺序执行多条命令 通常情况下,我们每次只能在终 ...