一些能想到的算法

冒泡排序
思路:共比较n-1轮,每次比较相邻的两个数,将大数放在后面,经过第一轮比较后最后面的就会是最大的
第二轮除了最后一个比较剩余的,第二轮会将第二大的数放在倒数第二位。直到最后。

插入排序
数组分成两个部分,前半部分是拍好序的,每次取后半部分的第一个数据,依次和前半部分的每个数比较,如果小于向后移,如果大于将数固定在这个下标,后面的部分依次后移
有这样个数组 [1 5 6 3 7 9 4 8]

[1| 5 6 3 7 9 4 8] 分成 1  和后边两个部分(只是抽象上的分成两个部分)[1 5| 6 3 7 9 4 8] 第一次排序 5>1 放在1的后面 现在分成 [1 5]  和剩下的部分[1 5 6| 3 7 9 4 8] 第二次排序 6>1 6>5 6放在5的后面 |将数组分成两个部分[1 3 5 6| 7 9 4 8] 第三次排序 3>1 3<5 将3放在原来5的位置,5 6 依次向后平移。

剩下的就不写了,就是这个意思。代码也好实现,唯一可能有问题的地方就是找到位置后,后面的每一个都需要向后移动一位,只要细心就可以了。

选择排序

第一轮选出最小的放在第一位,第二轮选出剩下的最小的放在第二位。一直到最后。

快速排序

算是上面中比较复杂的一个。
整体的思路选择一个基数,将大于这个基数的放在右边,小于这个基数的放在左边。在从左边的部分选择一个基数,将左边在按照上面的方法分成两部分。直到最终左边只剩两个数后,在依次给右边排序。
这样一个数组 [7 5 10 3 7 9 4 8],一轮一轮的说

第一轮:将7作为基数先从右边开始找,8>7跳过8[4l 5 10 3 7 9 4h 8]    4<7 将7换成4 h表示high的位置,这个位置是等待着被替换的右边找到一个小于基数7的数后在去找左边[4 5 10l 3 7 9 4h 8]    现在第一个位置是4, 4 5<=7跳过,10大于7,将10的位置标为l(小写的L low)[4 5 10l 3 7 9 10h 8]   将high的数据(原来的4)换成low的数据(10)    到这里完成依次循环但还没完成第一轮[4 5 10l 3 7h 9 10 8]]  接下来第二次循环先判断右边大于基数的位置。high的位置继续前移 9>7 跳过,到了7的位置,                        一般如果遇到了相同的数,是算在比基数小的部分,就是在判断大于基数时用numbers[high] > temp                         判断小于基数时用numbers[low] <= temp,这个temp是基数(这里的原始数据的第一个位置的7)                        遇到7不大于基数7,将7的位置标为h[4 5 7l 3 7h 9 10 8]    将high的数据给low,low的位置由原来的10变成7[4 5 7 3 7lh 9 10 8]    7<=7 3<=7 现在low high在相同位置跳出循环,将low的位置赋值为基数7。                        现在的lh位置的7其实是原数组中第五个位置的7的副本,也就是现在其实并没有原数组中第一个位置的基数7。不要被这两个7弄混了。                        假设原数组中第五个位置不是7是6,那么在想在的情况将会是[4 5 6 3 6lh 9 10 8],重复出现两个6,原来的基数在数组中没有了。

到这里第一层排序结束,已经实现基数7的左边<=7,右边>=7,并且基数7已经到了正确的位置。接下来就是按照上面的方法将左边进行排序,在将右边进行排序。贴上java代码

  public static void main(String[] args) {
    int[] numbers = {1, 3, 9, 5, 6, 7, 2, 0, 8, 4, 9};
    QuickSort.quick(numbers);
    for (int i : numbers)
      System.out.print(i + " ");
  }

  public static class QuickSort {
    public static void quick(int[] numbers) {
      if (numbers.length > 0) {
        quickSort(numbers, 0, numbers.length - 1);
      }
    }

    private static void quickSort(int[] numbers, int low, int high) {
      if (low < high) {
        int middle = sortAndGetMiddle(numbers, low, high);
        quickSort(numbers, low, middle - 1);
        quickSort(numbers, middle + 1, high);
      }
    }

    private static int sortAndGetMiddle(int[] numbers, int low, int high) {
      int temp = numbers[low];
      while (low < high) {
        while (low < high && numbers[high] > temp) {
          high--;
        }
        numbers[low] = numbers[high];
        while (low < high && numbers[low] <= temp) {
          low++;
        }
        numbers[high] = numbers[low];
      }
      numbers[low] = temp;
      return low;
    }
  }

快速排序性能比较不稳定,加入是这样的数据[9, 8, 7, 6, 5, 4, 3, 2, 1]那么就成了冒泡。怎么选这个基数可以具体调整。

二差树

平衡二叉树

时间: 2024-10-16 01:20:10

一些能想到的算法的相关文章

Codeforces Round #263 (Div. 2)C(贪心,联想到huffman算法)

数学家伯利亚在<怎样解题>里说过的解题步骤第二步就是迅速想到与该题有关的原型题.(积累的重要性!) 对于这道题,可以发现其实和huffman算法的思想很相似(可能出题人就是照着改编的).当然最后只是输出cost,就没必要建树什么的了.只要理解了huffman算法构造最优二叉树的思路,就按那么想就知道每个a[i]要加多少次了. 当然这道题没想到这些也可以找出规律的,就是一种贪心思想. #include<iostream> #include<cstdio> #include

算法入门(C++)

iostream,这个头文件里有很多常用的函数,比如swap交换两个变量的值,max求两个值的最大值等. cstdio头文件,这个头文件里包含C风格的输入输出.如果你之前学习过C++语言应该知道cin读入和cout输出的方法.那么我们为什么还要用C的scanf和printf呢?因为scanf和printf要比cin和cout的效率高得多. using namespace std 如果没这行的话,swap就要写成std::swap,代码写起来会麻烦些. main函数它的返回值是int类型的.那么它

最近公共祖先(三种算法)

最近研究了一下最近公共祖先算法,根据效率和实现方式不同可以分为基本算法.在线算法和离线算法.下面将结合hihocoder上的题目分别讲解这三种算法. 1.基本算法 对于最近公共祖先问题,最容易想到的算法就是从根开始遍历到两个查询的节点,然后记录下这两条路径,两条路径中距离根节点最远的节点就是所要求的公共祖先. 题目参见 #1062 : 最近公共祖先·一 附上AC代码,由于记录的方式采取的是儿子对应父亲,所以实现的时候有点小技巧,就是对第一个节点的路径进行标记,查找第二个节点的路径时一旦发现访问到

算法重拾之路——最长公共子序列(LCS)

***************************************转载请注明出处:http://blog.csdn.net/lttree******************************************** 第二章:动态规划 最长公共子序列 算法描述: 一个给定序列的子序列是该序列中删去若干元素后得到的序列.确切的说,若给定序列 X={ x1,x2,...,xm },则另一序列 Z = { z1,z2, ... ,zk },是X的子序列是指存在一个严格递增下标序列

zoj1967 poj2570 Fiber Network (floyd算法)

虽然不是最短路,但是询问时任意两点之间的信息都要知道才能回答,由此联想到floyd算法,只要都floyd算法的原理理解清楚了就会发现:这道题的思想和求任意两点之间的最短路的一样的,只不过是更新的信息不同而已. 这道题还有一个难点在于状态压缩:如果直接用字符串来表示maps[i][j],那么在floyd中还需要再加一层循环来找maps[i][k]和maps[k][j]有哪些一样的字母,这样时间复杂度太高,实际测试表明会TLE.那么可以用状态压缩的技巧,用二进制表示集合,最多就26位(代表26个字母

莫队算法详解和c实现

解析和实现 摘要:        莫队算法是一个对于区间.树或其他结构离线(在线)维护的算法,此算法基于一些基本算法,例如暴力维护,树状数组,分块,最小曼哈顿距离生成树,对其进行揉合从而产生的一个简单易懂且短小好写的算法.此算法在很多情况下可以很轻松的切掉一些复杂而且难写的数据结构问题. 关键词: 程序设计.算法.算法优化,暴力算法,分块算法,最小曼哈顿距离生成树. 背景: 众所周知,在OI竞赛.软件的设计中都会要求我们去处理各种各样的棘手的问题,而这些问题之中,有一大类就是维护问题:比如说对于

稀疏矩阵的普通转置与快速转置算法

稀疏矩阵的普通转置与快速转置算法 一般来说,对于系数矩阵,我们使用三元组来存储.即就是将矩阵的所有非零元素的三元组存放在一个顺序表中,如图所示: 注意一个转置的前提:该顺序表是排好序的,即行优先,列其次. 一.普通转置 这种算法比较简单,也很容易想到: 算法思想: 对M.data从头至尾扫描: ?第一次扫描时,将M.data中列号为1的三元组赋值到T.data中 ?第二次扫描时,将M.data中列号为2的三元组赋值到T.data中 ?依此类推,直至将M.data所有三元组赋值到T.data中 代

算法为啥子那么难【转】

转自:http://blog.csdn.net/azheng51714/article/details/8094626 广大码农同学们大多都有个共识,认为算法是个硬骨头,很难啃,悲剧的是啃完了还未必有用——除了面试的时候.实际工程中一般都是用现成的模块,一般只需了解算法的目的和时空复杂度即可. 不过话说回来,面试的时候面算法,包括面项目中几乎不大可能用到的算法,其实并不能说是毫无道理的.算法往往是对学习和理解能力的一块试金石, 难的都能掌握,往往容易的事情不在话下.志于高者得于中.反之则不成立.

ios开发——常用经典算法OC篇&amp;冒泡/快速

冒泡排序与快速排序 1.序言 ios开发中涉及到算法的地方还真不多,除非你的应用程序真的非常大,或者你想你的应用程序性能非常好才会去想到关于算法方面的性能优化,而在ios开发中真的能用得到的也就是关于排序的,当然如果你是做游戏的话那么你可能会涉及到不少的算法或者优化问题,但是这不是本篇文章讨论的范围. 后面的文章中,我将会给大家详细介绍八大算法. 2.冒泡排序 2.1 引出 前面的两篇博客里讲的插入排序是基于“逐个记录插入”,选择排序是基于“选择”,那么冒泡排序其实是基于“交换”.每次从第一个记