11-12-23排序

#include <iostream>

using namespace std;
extern int swap_count;
int swap_count = 0;
struct node
{
    int i;
    char c;
    int operator > (node &a)
    {
        return (i > a.i);
    }
    int operator < (node &a)
    {
        return (i < a.i);
    }
    void operator = (node &a)
    {
        i = a.i;
        c = a.c;
    }
    friend ostream &operator << (ostream &output, node &n)
    //输入输出操作符只能重载为友元函数,其中operator前的 & 也是必不可少的, 
    {
        output << n.i;
        output << n.c;
        return output;
    }
};
template <typename T1>
void swap(T1 *a, T1 *b)
{
    T1 c;
    c = *a;
    *a = *b;
    *b = c;
    swap_count += 1;
}
/**********************************
* 冒泡排序(BubbleSort),稳定排序,时间复杂度 N2 ,
* 逆序时性能最差,顺序时线性性能 
* 
***********************************/
template <typename T1>
void Bubble(T1 *pn, int len)
{
    for(int i = len; i > 0; i--)                  //*******************
    {
        for(int m = 0; m < i; m++)               //***************
        {
            if(*(pn + m) > *(pn + m + 1))
                swap((pn+m), (pn+m+1));
        }
    }
}
/************************************
* 插入排序(InsertionSort),时间复杂度 N2 , 
* 稳定排序,逆序时性能最差,顺序时线性性能。 
* 
*************************************/
template <typename T1>
void Insertion(T1 *pn, int len)
{
    T1 tmp;
    for(int i = 0; i < len; i++)
    {
        tmp = *(pn+i);
        for(int m = i +1; m < len; m++)
        {
            if(*(pn+m) < tmp)
                swap(&tmp, (pn+m));
        }
        *(pn+i) = tmp;
    }    
}
/****************************************
* 希尔排序(ShellSort),时间复杂度 N1.25 ,
* 非稳定排序,对初始记录不敏感。 
* 实质上是一种改进的插入排序:先将元素分成小组,插排,再合并,
* 再插排,最后合并成一组,而此时元素已经基本有序, 
****************************************/
/* 程序员实用算法 里推荐的一种确定 h 值序列的方法:
*  h1 = 1,n = 总元素个数, 
*  h(i+1) = 3h(i) + 1;当 h(x) > n/9 时停止,这种序列步进适合元素较多的时候, 
***************************************/
//靠 
template <typename T1>
void Shell(T1 *pn, int len)
{
    for(int increment = len/2; increment > 0; increment /= 2)
    {
        for(int i = 0; i < len; i++)  //虽然可行,但是会越界 
        {
            T1 tmp;
            tmp = *(pn+i);
            for(int m = i + increment; m < len; m += increment)
            {
                if( *(pn+m) < tmp)
                    swap(&tmp, (pn+m));
            }
            *(pn+i) = tmp;
        }
    }
}
/******************************************
* 快速排序(QuickSort),使用很广泛的一种排序,性能比较好,实现略复杂点, 
* 时间复杂度 N*logN 。选择一个基准,将数据集分成两个区:大于基准和小于基准的, 
*  等于基准的随便放,然后对这两个区递归 , 不稳定排序 
* 快排的缺点就是对于基本有序序列,效率反而很低,类似插排了, 
******************************************/
template <typename T1>
void Quick(T1 *pn, int left, int right)
{
    if(left < right)
    {
        int i = left;
        int j = right; 
        while(1)
        {
            while(*(pn+(++i)) < *(pn+left));
            while(*(pn+(--j)) > *(pn+left));
            if(i>=j)
                break;
            swap(pn+i, pn+j);
        }
        //当这个循环结束时,i = j+1 必然成立 ??貌似 
        swap(pn+left, pn+j);
        
        Quick(pn, left, j);
        Quick(pn, i, right);
    }
}
/***********************************************
* 堆排序(HeapSort),时间复杂度 N*logN ,比快速排序略慢, 
* 但是不存在最坏情况,也是不稳定的排序 
***********************************************/
//Heap_adjust:堆调整,大根堆 
//这个差不多了, 
//开始的错误是在于:调整成了一个近似于堆的东西,虽然最大值在最上面,但是后续的调整反而更麻烦
//不如开始时调整成标准的堆,这样后面的调整就可以局限在一定范围内 
template <typename T1>
void Heap_adjust(T1 *pn, int i, int len)
{
    int lc, rc, largest;
    lc = 2*i + 1;
    rc = 2*i +2;
    largest = (lc < len && pn[lc] > pn[i]) ? lc : i;
    largest = (rc < len && pn[rc] > pn[largest]) ? rc : largest;
    if(largest != i)
    {
        swap(pn +i, pn +largest);
        Heap_adjust(pn, largest, len);
    }
}
template <typename T1>
void Heap(T1 *pn, int len)
{
    for(int i = (len - 1)/2; i >= 0; --i)
        Heap_adjust(pn, i, len);
    //建立一个标准的大根堆,这样以后调整的时候方便,
    //如果是近似大根堆,想以前的版本那样,以后调整反而得不偿失 
    
    int tmp = len;
    for(int i = 0; i < len - 1; i++) //最后只剩一个节点时,没必要再调用函数调整了, 
    {
        tmp -= 1;
        swap(pn, pn + tmp);
        Heap_adjust(pn, 0, tmp);
    }
}
记录一下
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值