面试常见排序算法(上)

来源:互联网 发布:已备案域名购买转入 编辑:程序博客网 时间:2024/06/01 07:31

       查找和排序是算法的的入门知识,其思想可用于很多算法当中,应用性比较常见。所以在面试中经常会问到排序算法及相关的问题。下来是我对这些简单排序算法的思想及其特点的整理。

冒泡排序

      冒泡排序是最原始的排序方式之一。它的原理就是通过相邻两个数的比较和交换将小的数字交换到最前面。这个过程类似于水泡上升的过程,因此而得名。举个例子:例如4,3,6,1,8;第一次8与1比较,无需交换;然后1与6比较1<6,将6与1交换变成4,3,1,6,8;然后1和3比较同理交换变为4,1,3,6,8;然后4与1比较同理交换得1,4,3,6,8;这就是一次冒泡的结果,然后将最小的数1排在最前面。对剩下的序列一次冒泡就会得到一个有序序列。冒泡排序的时间复杂度为O(n^2);

实现代码:

void BubbleSort(int* arr, int size)//冒泡排序{if (arr == NULL || size == 0)return;for (int i = 0; i < size-1; ++i){for (int j = size - 1; j > i; j--){if (arr[j - 1] > arr[j]){int temp = arr[j];arr[j] = arr[j-1];arr[j - 1] = temp;}}}}

选择排序

选择排序的思想其实和冒泡排序有相似之处,都是在依次排序后将最小的数放在最前面;但不同的是冒泡排序是对相邻两个数进行比较和交换,但选择排序是对整体进行比 选择。举一个例子,例如4,7,9,2,7,1;第一次排序应选择除4以外最小的数与之交换,则选择1与之交换,变为1,7,9,2,7,4;然后再对剩下的序列进行下一次的选择与交换。其实选择排序是对冒泡排序的一种优化,选择排序大大减少了交换的次数。但是选择排序的时间复杂度仍为O(n^2);

代码实现:

void SelectSort(int* arr, int size)//选择排序{if (arr == NULL && size == 0)return;int min = 0;int i;for (i = 0; i < size - 1; i++){min = i;for (int j = i + 1; j < size; j++){if (arr[j] < arr[min])min = j;}}if (min != i){int temp = arr[i];arr[i] = arr[min];arr[min] = temp;}}



插入排序

插入排序是通过直接找到合适的插入位置直接插入来达到排序的目的。例如4,3,9,2,7,1;首先假设第一个数的位置是正确的,3要在4的前面,则将4向后移动一位,将3插入变为3,4,9,2,7,1;然后从9向后依次判断插入。

代码实现:

void InsertSort(int* arr,int size){if (arr == NULL || size == 0)return;for (int i = 1; i < size; ++i)  //保证第一个位置是正确的{int j = i;int temp = arr[i];while (j>0 && temp < arr[j - 1]){arr[j] = arr[j - 1];j--;}arr[j] = temp;  //插入}}

希尔排序

希尔排序通也称为缩小增量排序。基本思想是:先将整个序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录基本有序时,再对全体记录进行一次直接插入 排序。进而达到排序的目的。例如2,4,6,1,9,7,10;第一次缩进量为3,第二次排序缩进量为1;则将达到排序的结果。下面我用图简单剖析洗一下:


希尔排序的分析是复杂的,当n在一定范围时,时间复杂度可以达到O(n^1.3).

代码实现:

void ShellSort(int* arr, int size){int tag = size / 2;while (tag >= 1){for (size_t i = 0; i < size - tag; ++i){int end = i;int tmp = arr[i + tag];while (end >= 0)     //从后向前进行循环{if (arr[end] > tmp)arr[end + tag] = arr[end];  //向后挪动elsebreak;end -= tag;}arr[end + tag] = tmp;}tag/= 2;}}

其余几种常用也是重要的排序算法,在下篇博客会进行进一步分析。

9 5