算法二,深入与优化

  选择:1、外循环i,范围N-1,最后一位必为最小。

      2、对于N大小,需要N次比较。

      3、运行时间和输入的有序无序随机都无关,因为必须遍历

      4 、数据移动是最少。

      5、优化是堆排序

// public static void SelectSort(Comparable[] a) {
// int N = a.length;
// int mins;
// for (int i = 0; i < N - 1; i++) {
// mins = i;
// for (int j = i + 1; j < N; j++) {
//
// if (SortUtils.less(a[j], a[mins])) {
// mins = j;
// }
// SortUtils.exch(a, i, mins);
// }
// }
// }

插入排序 :1、一般是N2/4比较和交换,最坏是N2/2,最好是N-1比较和0次交换

      2、排有序会比随机和逆序数快得多

    3、小数组经常是用插入,会比递归快,例如快排和归并

// public static void insertsort(Comparable [] a ){
// int n = a.length;
//
// for (int i = 1; i < n; i++) {
// for (int j = i; j >0 && SortUtils.less(a[j], a[j-1]); j--) {
// SortUtils.exch(a, j, j-1);
// }
// }

希尔: 1、插入的优化

    2、通过h有序数据,避免了如果主键最小的元素正好在数组尽头,那么插入排序效率不高的情况

    3、递增序列 h= 3h+1,测试中效率最高

    4、通过while循环实现h,再通过h>=1的循环来控制分组,由h=h/3来减少分组距离

  

// public static void shellsort(Comparable[] a ){
//
// int n = a.length;
// int h1 = 1 ;
// while (h1<n/3) {
// h1 = 3*h1+1;
//
//
// }
// while (h1>=1) {
// for (int i = h1; i < n; i++) {
//
// for (int j = i+1; j >=h1 && SortUtils.less(a[j],a[j-h1]); j=j-h1) {
// SortUtils.exch(a, j, j-h);
// }
// }
// h1=h1/3;
//
// }
// }

归并:

  1、分治思想

   2、对小规模数据 N=15左右,使用插入排序,测试快10%-15%

    3、测试数据是否已经有序,就是a[mid]<a[mid+1]就是有序,跳出merge方法

  4、使用arraycope不讲元素复制到辅助数组。底层jni。并且辅助数组aux不声明在merge中为局部变量,因为会减低效率

5、4个条件判断:左边板用尽(取右半边的元素)、右半边用尽(取左边板的元素)、右半边的当前元素小于左半边的当前元素(取右半边的元素)、右半边的当前元素大于左边的当前元素(取半边)

6、原地归并的循环K,是循环c【】a数组,i=lo,j=mid+1,是aux数组辅助a数组

public static void ms(Comparable[] a) {
Comparable[] aux1 = a.clone();

ms(a, aux1, 0, a.length - 1);
}

private static void ms(Comparable[] a, Comparable[] aux1, int lo, int hi) {
if (lo>=hi+10) {
Insertion.sort(a);
return;
}
int mid = lo + (hi - lo) / 2;
ms(a, aux1, lo, mid);
ms(a, aux1, mid + 1, hi);

if (!SortUtils.less(aux1[mid + 1], aux1[mid])) {
System.arraycopy(aux1, lo, a, lo, hi - lo + 1);
return;
}

m(a, aux1, lo,mid, hi);
}

private static void m(Comparable[] a, Comparable[] aux1, int lo, int mid,
int hi) {

int j = mid +1;
int i = lo;

for (int k = lo; k < hi; k++) {
if (i>mid) {
a[k]=aux1[j++];
}else if (j>hi) {
a[k]=aux1[i++];
}else if (SortUtils.less(aux1[j], aux1[i])) {
a[k]=aux1[j++];
}else {
a[k]=aux1[i++];
}
}
}

快排:

1、选择基准:在待排序列中,按照某种方式挑出一个元素,作为 "基准"

2、分割操作:以该基准在序列中的实际位置,把序列分成两个子序列。此时,在基准左边的元素都比该基准小,在基准右边的元素都比基准大

3、递归地对两个序列进行快速排序,直到序列为空或者只有一个元素。

4、三次取中+插排+聚合相等元素+尾递归 +(多核心多线程)  stl sort 两者效率差不多

private static int partition(Comparable[] a, int lo, int hi) {

int i = lo;
int j = hi + 1;
Comparable v = a[lo];

while (true) {
while (SortUtils.less(a[++i], v)) {
if (i == hi)
break;
}
while (SortUtils.less(v, a[--j])) {
if (j == lo)
break;
}
if (i >= j) {
break;
}
SortUtils.exch(a, i, j);
}
SortUtils.exch(a, j, lo);

return j;
}

public static void QuickSort(Comparable[] a, int lo, int hi) {

if (hi <= lo + 10) {
Insertion.sort(a);
return;
}
int k = partition(a, lo, hi);
QuickSort(a, lo, k - 1);
QuickSort(a, k + 1, hi);

}

堆排序:

  1、10亿中取10个最大

2、从a【1】使用,跳去a【0】,在exch和less中,减一

3、for循环中sink构造有序堆,while循环中,sink用来排序

4、sink中的while,2j<=h,先是两子节点比较,右边一定小于左边,像一个退役的老人,跟新晋比较,一步一步下滑,swim则是上浮

5、而不使用swim是因为效率

6、先下沉后上浮。字符串或者其他兼职较长进行排序

7、无法利用缓存

8、是我们所知的唯一能够同时最有地利用空间和时间的方法。最坏也是 2NlgN的比较

// public static void hs(Comparable[] a) {
// int N = a.length;
// for (int i = N / 2; i > 0; i++) {
// sink1(a, i, N);
// }
// while (N > 1) {
// exch(a, 1, N--);
// sink(a, 1, N);
// }
// }
//
// private static void sink1(Comparable[] a, int i, int n) {
// while(2*i<n){
// int h = 2*i;
// if (h<n && less(a, h, h+1)) {
// h++;
// }if (!less(a,i,h)) {
// break;
// }
// exch(a,i,h);
// i=h;
// }
// }

时间: 2024-10-13 16:19:15

算法二,深入与优化的相关文章

EOJ 1848 你是ACM吗? 用二叉堆优化dijkstra + spfa算法的学习

Description  随着中国经济的腾飞,中国的物流产业迎来了发展的春天.特别是在上海这样一个拥有广阔国内腹地的国际化大都市,物流业以空前的速度膨胀. 当然是大蛋糕就会吸引许多馋嘴猫,馋嘴猫多了就会有残酷的竞争.当大量资金流入物流产业时,KOP 集团为了稳坐在国内物流业的第一把交椅,决定对现行的运输方案进行改良,以减少自己的成本同时使其它竞争者知难而退. 作为世界100强的KOP集团当然知道要找到最优运输方案,肯定得靠数学和算法很好的软件工程师,于是他们理所当然地找到华东师范大学软件学院.决

eoj1817 dijkstra单元最短路径 普通方法+二叉堆优化

求出有n(1 < n < 600)个结点有向图中,结点1到结点n的最短路径. Input 第一行有2个整数n和m(0 < m <= n*(n-1)/2),接下来m行每行有三个整数u,v,w结点u到v之间有一条权为w的边(w<1000000). Output 输出结点1到结点n之间的最短路径,如果1到n之间不存在路径,输出 -1. Sample Input 3 3 1 2 10 2 3 15 1 3 30 题目分析:dijkstra单元最短路径. 一.最短路径的最优子结构性质

优化页面访问速度(二) ——数据库优化

优化页面访问速度(二) ——数据库优化 一.概述 数据库优化,主要包括数据表设计.索引.sql语句.表拆分.数据库服务器架构等方向的优化. 二.数据库设计 在建表的时候,就需要考虑到将来的使用场景,尽量在建表初期就设计好. 1.存储引擎 Mysql常被提到的存储引擎就是InnoDB和MySIAM,其实现在主要都在用InnoDB了.两者的区别: InnoDB支持事务,索引和数据存在一个文件,主键查询速度快(主键就是索引B+树的叶子节点,而数据就绑定在叶子节点),行级锁,支持外键,恢复起来较快. M

数据结构与算法二

1.课程安排表: 1. 线性表 2. 字符串 3. 栈和队列 4.树 5.查找 6.排序 7.暴力枚举法 8.广度优先搜索 9.深度优先搜索 10.分治 11.贪心 12.动态规划 13.图 14.数学方法与常见模型 15.大整数运算 16. 基础功能 2.   编程技巧: 1.把较大的数组放在main 函数(全局变量)外,作为全局变量,这样可以防止栈溢出,因为栈的大小是有限制的.GCC (C编译器) 段错误 2.如果能够预估栈,队列的上限,则不要用stack,queue,使用数组来模拟,这样速

hdu3480之二维斜率优化DP

Division Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 999999/400000 K (Java/Others) Total Submission(s): 2664    Accepted Submission(s): 1050 Problem Description Little D is really interested in the theorem of sets recently. There's a pro

Graham算法—二维点集VC++实现

一.凸包定义 通俗的说就是:一组平面上的点,求一个包含所有点的最小凸多边形,这个最小凸多边形就是凸包. 二.Graham算法思想 概要:Graham算法的主要思想就是,最终形成的凸包,即包围所有点的凸多边形,假定多边形是按逆时针方向生成的,那么多边形内部包围的所有点与多边形每个有向边的关系都是:点在有向边的左边.依照此思想,只要找到一个出发点,然后依此出发点按逆时针方向构建多边形,并保证每加入一条有向边时,都要满足其余点都在该边的左边. ***点与线的关系定义:平面上的三点P1(x1,y1),P

Kruskal算法(二)之 C++详解

本章是克鲁斯卡尔算法的C++实现. 目录 1. 最小生成树 2. 克鲁斯卡尔算法介绍 3. 克鲁斯卡尔算法图解 4. 克鲁斯卡尔算法分析 5. 克鲁斯卡尔算法的代码说明 6. 克鲁斯卡尔算法的源码 转载请注明出处:http://www.cnblogs.com/skywang12345/ 更多内容:数据结构与算法系列 目录 最小生成树 在含有n个顶点的连通图中选择n-1条边,构成一棵极小连通子图,并使该连通子图中n-1条边上权值之和达到最小,则称其为连通网的最小生成树. 例如,对于如上图G4所示的

每周算法(二)

每周算法 二 视屏地址:http://edu.51cto.com/course/course_id-5113.html 1.  递归实现my_strlen <1> 题目描述:实现求字符串长度函数my_strlen <2> 方法一:直接法 <3> 方法二:递归法 2.  递归实现n! <1> 题目描述:输入n值,求解n的阶乘 <2> 方法一:累乘法 <3> 方法二:递归法 3.  递归实现斐波那契数列Fib(n) <1> 题

白话经典算法二叉堆排序之思想简介

常用的排序算法有冒泡排序,插入排序和选择排序.他们的时间复杂度是o(n2),与数据量的平方成正比.他们的效率还是比较低的.现在来说说他们的效率为什么比较低下.以冒泡排序为例,它每一轮都是与相邻的元素进行交换,交换的距离为1,每次每个(没有冒泡出来的)元素都要与前一个比较再交换.每次相邻的比较只能比较出两个元素的大小,不能以整个数组进行参照来确定在整个数组里的大小,也就是说每次的比较不能确定其他元素的相对位置,因而每次比较的贡献不大,所以这样的比较是笨拙的,进而需要完全比较O(n2)次才能得出正确

SPFA算法及其应用和优化

by mps [问题引入] 又是一年春运时,因为睡懒觉而导致抢不到票的你,只能打车回家了,而无疑会消耗许多钱财(黑车...),为了尽可能的节省钱,你希望走的是最短路,路途中会经过n个城市,而你每次经过两个城市之间的高速公路时,都会损耗Ci元,假设其中包含了所有的价钱(邮费,过桥费之类的),你现在在1号城市,希望到达n号城市去,请问最少花费是多少? [输入描述] 第一行,n,m,表示有n个城市,m条高速公路 第二行至第m+1行,每行三个数u,v,w,表示u城市到达v城市的耗费为w元(均为有向边)