算法

  前 3 篇先后介绍了 链表、数组、map集合,它们都是用来存储数据的,stl 和 util 还提供了很多基于这些集合类的算法:

一 copy

  首先介绍的这个算法好像根本就称不上是算法,不过它确实挺有用的:

  假如我们有一组数据要存到一个集合类中,并假设这组数据在编码过程中经常需要改动,所以我们尽量要做到数据变动的时候不需要改动其他代码。我们可以先临时定义一个数组,列出这些数据,然后用一个 for 循环一个一个地把它们添加进去。但是 stl 告诉我们可以不用循环:

#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>
using namespace std;

// 打印 begin 到 end 之间的所有数据
//   InIt 是输入迭代器,可视为指针
template<class InIt>
void displayAll(InIt begin, InIt end)
{
    if(begin != end)
    {
        --end;
        for(; begin!=end; ++begin)
            cout<<*begin<<",";
        cout<<*end;
    }
    cout<<endl;
}

// 求数组A的长度
#define LENGTH(A) (sizeof(A)/sizeof(A[0]))

int main()
{
    int A[] = {5,3,1,13,8,1,2};
    vector<int> C;

    // 将 A 到 A + LENGTH(A) 之间的数据拷贝到 C 中
    //   inserter 模版函数返回一个插入迭代器,iterator 头文件友情提供
    copy(A, A + LENGTH(A), inserter(C, C.end()));

    displayAll(C.begin(), C.end());
    return 0;
}

  java 中也有类似的功能,但是介绍它之前请允许我先总体地介绍一下算法在 stl 和 util 中的位置:

  从上例中也可以看出 stl 中的算法在头文件 algorithm 中;而 util 中的算法则在 util 包的两个类:Collections、Arrays 中,作为这两个类的静态方法提供给我们使用(直接用类名来引用,不用生成对象)。 从名字就可以看出来 Collections 提供的是基于集合类的算法, Arrays 提供的是基于数组的算法。java 中可以使用 Collecions 的 addAll 方法将数组添加到集合中:

import java.util.*;

public class Temp {

    public static void main(String[] args) {
        Integer[] A = { 5, 3, 1, 13, 8, 1, 2 };
        LinkedList<Integer> C = new LinkedList<Integer>();

        Collections.addAll(C, A);

        // 集合类提供了 toString 方法可打印出所有元素
        System.out.println(C);
    }

}

二 sort

  介绍了 copy 之后,再就介绍一个实实在在的算法—— 排序算法:

// C++ stl 排序
#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>
using namespace std;

// 打印 begin 到 end 之间的所有数据
template<class InIt>
void displayAll(InIt begin, InIt end)
{
    if(begin != end)
    {
        --end;
        for(; begin!=end; ++begin)
            cout<<*begin<<",";
        cout<<*end;
    }
    cout<<endl;
}

// 求数组A的长度
#define LENGTH(A) (sizeof(A)/sizeof(A[0]))

int main()
{
    int A[] = {5,3,1,13,8,1,2};
    vector<int> C;
    copy(A, A + LENGTH(A), inserter(C, C.end()));

    // 给 vector 排序
    displayAll(C.begin(), C.end());
    sort(C.begin(), C.end());
    displayAll(C.begin(), C.end());

    cout<<"----------无情的分割线----------"<<endl;

    // 给数组排序
    displayAll(A, A + LENGTH(A));
    sort(A, A + LENGTH(A));
    displayAll(A, A + LENGTH(A));

    return 0;
}

然后是 java 版,流程一样:

// java util 排序
import java.util.*;

public class Temp {

    public static void main(String[] args) {
        Integer[] A = { 5, 3, 1, 13, 8, 1, 2 };
        LinkedList<Integer> C = new LinkedList<Integer>();
        Collections.addAll(C, A);

        // 给集合类排序
        System.out.println(C);
        Collections.sort(C);
        System.out.println(C);

        System.out.println("----------无情的分割线----------");

        // 给数组排序
        //   数组本身没有重写 toString 方法,但 Arrays 提供了
        System.out.println(Arrays.toString(A));
        Arrays.sort(A);
        System.out.println(Arrays.toString(A));
    }

}

  C++ 中只有能随机访问的集合类能用 sort 排序,也就是说 vector 能排,list 不能排。而 java 中只要是实现了 List 接口的都能排(集合中元素需要实现 Comparable接口(比大小接口)), ArrayList 能排,LinkedList 也能排,从 sort 的源代码可以看到链表排序的真相:

  所以链表的排序只是增加了 O(n) 量级的拷贝代价。

  sort 会检查集合的规模以及是不是大部分已经有序,从而在 插入排序、归并排序、快速排序 中进行选择,所以它的性能还是很不错的。

三 其他算法

  java 中还有一些常用的算法如:

  • shuffle // 随机算法,将 List 集合打乱顺序。
  • binarySearch // 二分查找算法
  • reverse // 逆序算法
  • min
  • max

  以上算法 C++ stl 中都有,C++ 还提供了如下算法:

  • sort_heap // 堆排序
  • stable_sort // 稳定排序
  • nth_element // 找到第 n 大的数

  当然,由于本猿也刚刚入门,还有很多提供了的算法没有用过,也就不提了。总之,多熟悉这些集合类、算法,少造车轮,总是好的。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值