排序---排序算法2

上一篇总结了简单的排序算法,这一篇继续。。。

堆排序

思想

堆,堆顶元素(即第一个元素)必为最小项(小顶堆)(升序序列)或者最大项(大顶堆)(降序序列)。若以一维数组存储一个堆,则堆对应一棵完全二叉树,且所有非叶结点的值均不大于(或不小于)其子女的值,根结点(堆顶元素)的值是最小(或最大)的。虽然说是一棵完全二叉树,但不是说就得根据这些数据还需要重新建立数据结构,对于一维数组有这样的规定:
根节点i与左右孩子的下标的关系是:
左孩子:i*2+1
右孩子:i*2+2
每一个孩子节点对应的双亲节点的下标是:(i-1)/ 2
通过如上的关系,就可以将一维数组当做是一个二叉树来处理了。

实现
void adjustHeap(int*arr,int begin,int len);
//堆的初始化
void heap_init(int *arr,int len)
{
    for (int i=len-1;i >=0;i--)
    {
        adjustHeap(arr,i,len);
    }
}
//堆的调整
void adjustHeap(int*arr,int begin,int len)
{
    int tmp = arr[begin];
    int child = 2*begin+1;//左孩子的下标
    while (child < len)
    {
        if (child+1 < len && arr[child] < arr[child+1])
        //如果右孩子大于左孩子,就调整到右孩子的下标
        {
            ++child;
        }
        if (arr[begin] < arr[child])//如果较大的子节点大于父节点,
                                //那么子节点就替换它的父节点
        {
            arr[begin] = arr[child];
            begin = child;
            child = 2*begin+1;
        }
        else//如果当前节点大于它的左右孩子,就不需要调整,直接退出
        {
            break;
        }
        arr[begin] = tmp;//将待调整的节点的值放到比它还大的孩子节点的位置上
    }
}
void heap_sort(int *arr,int len)
{
    if (arr == NULL || len < 1)
    {
        return;
    }
    cout<<"heap_sort"<<endl;
    //堆的初始化
    heap_init(arr,len);
    //从最后一个元素开始对序列进行调整
    for (int i=len-1;i >=0;i--)
    {
        //交换堆顶元素
        int top = arr[i];
        arr[i] = arr[0];
        arr[0] = top;
        adjustHeap(arr,0,i);
    }
}
效率

堆排序也是属于选择排序的一种,但是它的效率是很高的,和快速排序不相伯仲,时间复杂度都是O(nlogn)。

快速排序

思想

1.在待排序的元素任取一个元素作为基准(通常是选取第一个元素,但最好的选择方法是从待排序的元素中随机选取一个作为基准),称为基准元素
2.将待排序的元素进行分区,比基准元素大的元素放在它的右边,比它小的放在它的左边;
3.对左右两个分区重复以上的步骤直到所有的元素都是有序的。

递归实现
int patition(int *arr,int l,int r)
{
    int tmp = arr[l];
    while (l < r)
    {
        while (arr[r] >= tmp && l < r)
        {
            r--;
        }
        arr[l] = arr[r];
        while (arr[l] <=tmp && l < r)
        {
            l++;
        }
        arr[r] = arr[l];
    }
    arr[l] = tmp;
    return l;
}

void quick(int *array,int start,int end)
{
    if (start < end)
    {
        int pos = patition(array,start,end);
        quick(array,0,pos-1);
        quick(array,pos+1,end);
    }
}


void quick_sort(int*array,int num)
{
    if (array == NULL || num < 1)
    {
        return;
    }
    cout<<"quick sort"<<endl;
    quick(array,0,num-1);
}
非递归实现
void quick_sortRecursion(int*arr,int len)
{
    if (arr == NULL || len < 1)
    {
        return;
    }
    stack<int>st;
    int left = 0;
    int right = len-1;
    st.push(left);
    st.push(right);
    while (!st.empty())
    {
        right = st.top();
        st.pop();
        left = st.top();
        st.pop();
        if (left < right)
        {
            int pos = patition(arr,left,right);
            st.push(left);
            st.push(pos);

            st.push(pos+1);
            st.push(right);
        }
    }
}
效率

和堆排序一样的,都是属于选择排序,而且效率都是O(nlogn)。

现在就理解这么多,还有个效率更高的归并排序,后面再说吧,关于排序算法中的其他几个,见
http://blog.csdn.net/adminlpx/article/details/79279750这也是我的总结。继续加油!^_^

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值