读书人

数据结构口试之十排序2(归并、快速

发布时间: 2012-09-21 15:47:26 作者: rapoo

数据结构面试之十——排序2(归并、快速、堆排序)

题注:《面试宝典》有相关习题,但思路相对不清晰,排版有错误,作者对此参考相关书籍和自己观点进行了重写,供大家参考。

十、数据结构面试之十——排序2(归并、快速、堆排序)

5. 归并排序

【算法思想】:采用分治法的算法思想,将原始数组分为A、B两个子数组,然后对A、B两个子数组继续划分为A1L,A1R,B1L,B1R四个子数组,继续划分直到数组中元素个数为1个时,即认为数组有序;然后再合并相邻的数组据可以。

核心分为3步骤:

第一,Divided,对应Divided()函数。

第二,Conquer,做相关处理。

第三,Merge,对应MergeArray()函数。

步骤示意图:

数组下标

a[0]

a[1]

a[2]

a[3]

a[4]

a[5]

a[6]

a[7]

a[8]

a[9]

元素值

9

8

7

6

5

4

3

2

1

0

Divided

1

first

 

 

 

mid

 

 

 

 

last

2

first

 

mid

 

last

 

 

 

 

 

3

first

mid

last

 

 

 

 

 

 

 

4

first&mid

last

 

 

 

 

 

 

 

 

 

Merge

5

first&mid

last

 

 

 

 

 

 

 

 

6

first

mid

last

 

 

 

 

 

 

 

 

Divided

7

 

 

 

first&mid

last

 

 

 

 

 

Merge

8

 

 

 

first&mid

last

 

 

 

 

 

Merge

9

first

 

mid

 

last

 

 

 

 

 

 

Divided

11

 

 

 

 

 

first

 

mid

 

last

12

 

 

 

 

 

first

mid

last

 

 

13

 

 

 

 

 

first&mid

last

 

 

 

 

Merge

14

 

 

 

 

 

first&mid

last

 

 

 

15

 

 

 

 

 

first

mid

last

 

 

 

Divided

16

 

 

 

 

 

 

 

 

first&mid

last

Merge

17

 

 

 

 

 

 

 

 

first&mid

last

Merge

18

 

 

 

 

 

first

 

mid

 

last

 

Merge

19

first

 

 

 

mid

 

 

 

 

last

【算法实现】:

枢轴

0

1

2

3

4

5

6

7

8

9

 

72

6

57

88

60

42

83

73

48

85

pivot=72

<--48

 

 

<--42

 

left=right

 

 

88-->

 

 

<--48

6

57

<--42

60

72

83

73

88-->

85

 

 

 

 

 

 

 

 

 

 

 

pivot=48

48

6

57

42

60

 

 

 

 

 

 

<--42

 

left=right

57-->

60

 

 

 

 

 

 

<--42

6

48

57-->

60

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

pivot=42

42

6

 

 

 

 

 

 

 

 

 

<--6

42

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

pivot=57

 

 

 

57

60

 

 

 

 

 

 

 

 

 

57

60

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

pivot=83

 

 

 

 

 

 

83

73

88-->

85

 

 

 

 

 

 

 

73

83

88-->

85

 

 

 

 

 

 

 

 

 

 

 

pivot=73

 

 

 

 

 

 

73

83

 

 

 

 

 

 

 

 

 

73

83

 

 

 

 

 

 

 

 

 

 

 

 

 

pivot=88

 

 

 

 

 

 

 

 

88

85

 

 

 

 

 

 

 

 

 

85

88

排序结果

6

42

48

57

60

72

73

83

85

88

【算法实现】:

template<typename T>void heapAdjust(T arr[], int i, int N){       intj;       inttemp = arr[i];    //临时存储需要节点信息.       j= i*2+1;         //左孩子节点        while(j< N)       {              if(j+1< N && arr[j+1] < arr[j])              {                     j++;                //取左右孩子中的小值.              }              if(arr[j]>= temp)              {                     break;             //小顶堆,如果出现孩子节点值大,则终止循环.              }              //找寻是否存在孩子节点的孩子节点.              arr[i]= arr[j];              i= j;              j= 2*i + 1;       }//endwhile       arr[i]= temp; //存储新的位置.} //堆排序.template<typename T>void heapSort(T arr[], int N){       //构建小顶堆,初始是凌乱的,调整后成一个小顶堆       for(int i = N-1; i >= 0; i--)       {              heapAdjust(arr,i/2,N-1);//比较的位置从中间开始.       }        for(int  i = N-1; i >= 0; i--)       {              swap(arr[i],arr[0]);              heapAdjust(arr,0,i);  //终止的大小为i,每次只调整根节点即可。       }}



1楼hxx00昨天 10:30
解释得很详细 顶一个

读书人网 >编程

热点推荐