码迷,mamicode.com
首页 > 编程语言 > 详细

快速排序(QuickSort),归并排序(MergeSort),堆排序(HeapSort)典型C++代码实现总结

时间:2018-10-12 13:59:20      阅读:141      评论:0      收藏:0      [点我收藏+]

标签:哨兵   排序   元素   直接   有序   数组   写法   swap   比较   

最近在面试的时候经常能碰到让手写代码的,其中这三种经典排序算法更是出现频繁,在这里用C++总结一下,也算是备忘。

快速排序(QuickSort)

快速排序最经典的就是挖坑法,在第一个数字(把该数字作为temp,即枢轴量pivot)处挖坑用来存放右侧第一个比temp值小的数,然后坑的位置就变成了右侧这一位置,再从左侧找到第一个比pivot大的数放到坑里去,以此类推。

具体C++代码如下:

void QuickSort_vector_index(vector<int> &nums,int start ,int end){
    if(start>=end) return;
    int temp = nums[start];
    int L = start;          //L,R左右哨兵
    int R = end;

    while(L<R){
        while(L<R && nums[R]>=temp)             //找到右侧第一个比temp小的数 放到左侧挖的坑里面去
            R--;
        if(L<R)                                 //注意一定要增加L<R这个判断语句
            nums[L++] = nums[R];
        while(L<R && nums[L]<=temp)
            L++;
        if(L<R)
            nums[R--] = nums[L];
    }

    nums[L] = temp;                             //中间的坑填上中间量
    QuickSort_vector_index(nums,start,L-1);
    QuickSort_vector_index(nums,L+1,end);
}

以上代码的接口为vector<int>,用数组同样原理。

归并排序(MergeSort)

归并排序考察的明显就是分治的思想,主要的函数也就merge。

C++实现代码如下:

//merge两个有序数列为一个有序数列
void MergeArr(int a[], int first, int mid, int last, int temp[])
{
    int i = first, j = mid+1;
    int m = mid, n = last;
    int k=0;
    //通过比较,归并数列a和b
    while(i<=m && j<=n)           //逻辑要能够这么清晰
    {
        if(a[i]<a[j])
            temp[k++] = a[i++];             //temp[k++]这种简洁的写法值得学习
        else
            temp[k++] = a[j++];
    }
    //将数列a或者b剩余的元素直接插入到新数列后边
    while(i<=m)
        temp[k++] = a[i++];
    while(j<=n)
        temp[k++] = a[j++];

    for(i=0; i<k; i++)
        a[first+i] = temp[i];
}

//归并排序
void MergeSort(int a[], int first, int last, int temp[])
{
    if(first<last)             //这里这个first<last把只有一个元素进行MergeSort的迭代出口确定了。此时first==last
    {
        int mid = (first+last)/2;
        MergeSort(a, first, mid, temp);
        MergeSort(a, mid+1, last, temp);
        MergeArr(a, first, mid, last, temp);
    }
}

堆排序(HeapSort)

堆排序有两个主要过程,建堆以及之后的堆结构维护,主要函数则是下滤函数(downPerlocate)

C++实现代码如下:

void downPercolate(vector<int>& nums ,int index, int end){
    int index_temp = index;
    while(1){
        int hole = 2*index_temp + 1;
        if(hole > end) break;
        if(hole+1 <= end && nums[hole] > nums[hole+1])
            ++hole;
        if(nums[index_temp] < nums[hole]) break;//下滤的几个跳出判断挺有用的
        swap(nums[index_temp],nums[hole]);
        index_temp = hole;
    }
}


void HeapSort(vector<int>& nums, int size){
    for(int i = size/2; i>=0; --i){
        downPercolate(nums,i,size-1);
    }
    for(int i = 0; i<size; ++i){//注意这几行代码,每次把第一个值放到最后然后把最后的值进行下滤,实现堆排序。
        swap(nums[0],nums[size-1-i]);
        downPercolate(nums,0,size-2-i);
    }
    reverse(nums.begin(),nums.end());//这里是为了从小到大排序,以上代码默认完成的时候是从大到小的
}

 最近学了些Go语言,在这里贴一下Go语言版的HeapSort:

package main

import (
	"awesomeProject/HeapSort/tool"
	"fmt"
)

func main(){
	nums:= [10]int{3,7,1,5,0,9,2,12,6,8}
	tool.Hp(nums[:])
	for i,d:= range nums{
		fmt.Printf("%d -> %d\n",i,d)
	}
}

============================================
package tool

func Hp(nums []int) {
	for i:= len(nums)/2;i>=0;i--{
		DownPerlocate(nums[i:])
	}
	for j:= 0; j<len(nums); j++{
		nums[0] ,nums[len(nums)-j-1] = nums[len(nums)-j-1],nums[0]
		DownPerlocate(nums[:len(nums)-j-1])
	}
}

============================================
package tool

func DownPerlocate(nums []int){
	s:= len(nums)
	index := 0
	for {
		hole := 2*index+1
		if hole >= s{
			break
		}
		if hole+1 < s && nums[hole+1] > nums[hole] {
			hole++
		}
		if nums[index]>=nums[hole]{
			break
		}
		nums[hole],nums[index] = nums[index],nums[hole]
		index = hole
	}
}

  

快速排序(QuickSort),归并排序(MergeSort),堆排序(HeapSort)典型C++代码实现总结

标签:哨兵   排序   元素   直接   有序   数组   写法   swap   比较   

原文地址:https://www.cnblogs.com/J1ac/p/9777129.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!