您的位置:首页 > 编程语言 > C语言/C++

二分查找 归并排序 快排 详解C++

2017-08-09 10:29 387 查看
这三个排序算法一直是面试的重点,大多数都是C语言写的,今天整理了一下C++的写法,思想都差不多。这几个排序经常忘记,今天抽空记在这,以便自己以后查阅,不对的地方,也欢迎大家评论,不吝指正,谢谢!

二分查找(时间复杂度是O(logn))

二分查找的基本思想是将n个元素分成大致相等的两部分,取a[n/2]与x做比较,如果x=a[n/2],则找到x,算法中止;如果x<a[n/2],则只要在数组a的左半部分继续搜索x,如果x>a[n/2],则只要在数组a的右半部搜索x。优点是比较次数少,查找速度快,平均性能好;其缺点是要求待查表为有序表,且插入删除困难。因此,二分查找方法适用于不经常变动而查找频繁的有序列表。

要求:

1、必须采用顺序存储结构 2、必须按关键字大小有序排列。

下面是二分查找的递归方式和非递归方式的代码:

 C++ Code 
1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

//二分查找 O(logN) 非递归
template <typename T> int BinarySearch(const vector<T> &a, const T &x)

{

    int low = 0, high = a.size() - 1;

    while (low <= high)

    {

        int mid = (low + high) / 2;

        if (a[mid] < x)

            low = mid + 1;

        else if (a[mid] > x)

            high = mid - 1;

        else

            return mid;

    }

    return -1;//NOT_FOUND
}
//递归
template <typename T> int BinarySearch(const vector<T> &a, int low, int high const T &x)

{

    if (low <= high)

    {

        int mid = (low + high) / 2;

        if (a[mid] < x)

            return BinarySearch(a, mid + 1, high, x);

        else if (a[mid] > x)

            return BinarySearch(a, low, mid - 1, x);

        else

            return mid;

    }

    return -1;//NOT_FOUND
}
并排序:

归并排序:(时间复杂度是O(nlogn),空间复杂度是O(n),稳定)

比较a[i]和a[j]的大小,若a[i]≤a[j],则将第一个有序表中的元素a[i]复制到temp[k]中,并令i和k分别加上1;否则将第二个有序表中的元素a[j]复制到temp[k]中,并令j和k分别加上1,如此循环下去,直到其中一个有序表取完,然后再将另一个有序表中剩余的元素复制到temp中从下标k到下标high的单元。归并排序的算法我们通常用递归实现,先把待排序区间[low,high]以中点二分,接着把左边子区间排序,再把右边子区间排序,最后把左区间和右区间用一次归并操作合并成有序的区间[low,high]。

代码如下:

 C++ Code 
1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

//归并
void mergeAray(vector<int> &a, int low, int mid, int high, vector<int> &temp)

{

    int i = low, j = mid + 1;

    int m = mid, n = high;

    int k = 0;

    while (i <= m && j <= n)

    {

        if (a[i] <= a[j])

            temp[k++] = a[i++];

        else

            temp[k++] = a[j++];

    }

    while (i <= m)

        temp[k++] = a[i++];

    while (j <= n)

        temp[k++] = a[j++];

    for (i = 0; i < k; i++)

        a[low + i] = temp[i];

}
void mergeSort(vector<int> &a, int low, int high, vector<int> &temp)

{

    if (low < high)

    {

        int mid = (low + high) / 2;

        mergeSort(a, low, mid, temp);

        mergeSort(a, mid + 1, high, temp);

        mergeAray(a, low, mid, high, temp);

    }

}
void MergeSort(vector<int> &a, int n)

{

    vector<int> p(n);

    if (p.size() == 0)

        return;

    mergeSort(a, 0, n - 1, p);

}
快排(时间复杂度:最好情况O(nlogn) 最坏情况O(n^2) 平均情况O(nlogn)  不稳定)

快速排序算法是对冒泡排序的一种改进。

通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列

即,找一个合适的基准数,比基准数大的移到基准数右边,比基准数小的放到基准数左边。

代码如下:

 C++ Code 
1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

//快速排序
void QuickSort(vector<int> &s, int left, int right)

{

    if (left > right)

        return;

    else

    {

        int temp = s[left], i = left, j = right;

        while (i < j)

        {

            while (i < j && s[j] > temp) j--;

            s[i] = s[j];

            while (i < j && s[i] < temp) i++;

            s[j] = s[i];

        }

        s[i] = temp;

        QuickSort(s, left, i - 1);

        QuickSort(s, i + 1, right);

    }

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: