常见的排序算法的实现

      今天用c++把常见的排序算法实现了一遍。

class Sort
{
    void swap(int& a, int& b)
    {
        if (a == b)
            return;
        a ^= b;
        b ^= a;
        a ^= b;
    }
     //调整堆,根节点的左右两个子树都是调整好的大根堆,只需要把根节点与左右子树的根节点比较
     //找出最大值,把最大值往上提,小值往下沉,就可以调整好堆
    void MaxHeapify(int a[], int maxIndex, int n)
    {
        int largest = maxIndex;
        int left = maxIndex * 2 + 1;
        int right = maxIndex * 2 + 2;
        if (left < n && a[left] > a[maxIndex])
        {
            largest = left;
        }
        if (right < n && a[right] > a[largest])
        {
            largest = right;
        }
        if (largest != maxIndex)
        {
            swap(a[largest], a[maxIndex]);
            MaxHeapify(a, largest, n);
        }
    }
     //创建初始堆
    void BuildMaxHeap(int a[], int n)
    {
      //完全二叉树最后一个非叶子节点下标为n/2-1
        for (int i = n / 2 - 1; i >= 0; i--)
        {
            MaxHeapify(a, i, n);
        }
    }
    
    void merge(int a[], int low, int mid, int hight)
    {
        if (low == hight)
            return;
            
        merge(a, low, (mid - low) / 2 + low, mid);
        merge(a, mid + 1, (hight - mid - 1) / 2 + mid + 1, hight);

        int* tmp = new int[hight - low + 1];
        int* p = tmp;
        int i = low;
        int j = mid + 1;
        while (i <= mid && j <= hight)
        {
            if (a[i] <= a[j])
            {
                *p++ = a[i++];
            }
            else
            {
                *p++ = a[j++];
            }
        }
        while (i <= mid)
        {
            *p++ = a[i++];
        }
        while (j <= hight)
        {
            *p++ = a[j++];
        }
        for (int i = 0; i < hight - low + 1; i++)
        {
            a[low + i] = *(tmp + i);
        }
        delete[] tmp;
    }
public:
    //直接插入排序
    void insert_sort(int* a, int n)
    {
        for (int i = 0; i < n; i++)
        {
            int j = i;
            while (j > 0)
            {
                if (a[j] >= a[j - 1])
                    break;
                swap(a[j], a[j - 1]);
                j--;
            }
        }
    }
    //希尔排序,插入排序的变种
    void shell_sort(int* a, int n)
    {
        int m = n;
        while (m /= 2)
        {
            for (int i = m; i < n; i++)
            {
                int j = i;
                while (j > 0)
                {
                    if (a[j] >= a[j - m])
                        break;
                    swap(a[j], a[j - m]);
                    j -= m;
                }
            }
        }
    }
    //冒泡排序
    void bubble_sort(int a[], int n)
    {
        bool isSort = true;
        for (int i = 0; i < n; i++)
        {
            isSort = true;
            for (int j = n - 1; j > i; j--)
            {
                if (a[j] >= a[j - 1])
                    continue;
                swap(a[j], a[j - 1]);
                isSort = false;     //如果发生交换则表明还没有排好序,如果没有发生交换说明已经排好序了
            }
            if (isSort)
                return;
        }
    }
    //快速排序
    void quick_sort(int a[], int n)
    {
        int* low = a;
        int* hight = a + n - 1;
        int* bp = low;  //默认使用第一个数做基准数据
        int* tp = hight;
        if (low == hight)
            return;
        //快排的主要思路就是,对每一次递归的子数组进行遍历,比较每个数与基准数的大小
        //小于基准数的放在基准数的左边,大于基准数的放在右边
        //所以关键是每次遍历数组的方法,这里每次递归选择数组的第一个数为基准数,从数组末尾往回遍历数组
        //tp为遍历数组的指针,bp为基准数指针
        while (tp != low)
        {
   	    if (tp > bp)
   	    {
    	        if (*tp >= *bp)
    		{
     		    tp--;
    		}
    		else
   		{
     		    swap(*bp, *tp);
     		    bp = tp;
     		    tp--;
   	 	}
   	    }
  	    else
   	    {
    	    	if (*tp <= *bp)
    	        {
    		    tp--;
    		}
    		else
    		{
     		    swap(*bp, *tp);
     		    bp = tp;
     		    tp--;
    		}
   	    }
        }
        if(low + 1 < bp)
            quick_sort(low, bp - low + 1);
        if(bp + 1 < hight)
            quick_sort(bp + 1, hight - bp);
    }
    //直接选择排序
    void select_sort(int a[], int n)
    {
        for (int i = 0; i < n; i++)
  	{
   	    int* min = a + i;
  	    for (int j = i + 1; j < n; j++)
   	    {
    		if (a[j] < *min)
   		{
     		    min = a + j;
    		}
   	    }
   	    swap(a[i], *min);
  	}
    }
    //堆排序有三步,1、从最后一个非叶子节点开始往回调整堆,创建初始堆;2、将堆顶的最大数与未排序区末尾的数互换;3、重新调整未排序区
    void heap_sort(int a[], int n)
    {
        BuildMaxHeap(a, n);
        for (int i = 1; i < n; i++)
  	{
   	    swap(a[0], a[n - i]);
   	    MaxHeapify(a, 0, n - i);
  	}
    }
    //归并排序
    void merge_sort(int a[], int n)
    {
       merge(a, 0, n / 2 - 1, n-1);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值