排序算法及分析

排序算法小合集:冒泡排序、快速排序、堆排序、合并排序、插入排序

 

相关知识:

假设:含n个记录的序列为:{R1,R2,…,Rn}

         相应的关键字序列为:{K1,K2,…,Kn}

需确定1,2,…,n的一种排列p1,p2,…,pn,使其相应的关键字满足如下的非递减(或非递增)关系:                                     Kp1 <=Kp2<= … <=Kpn

使得记录的序列成为一个按关键字有序的序列:

                                            {Rp1,Rp2,…,Rpn}

这样的一种操作称为排序。

假设Ki=Kj(1<=i<=n,1<=j<=n,i!=j),且在排序前序列中Ri领先于Rj(及i<j)。若在排序后的序列中Ri仍领先于 Rj,则称所用的排序方法是稳定的;反之,排序方法是不稳定的。

 

冒泡排序:Time(O(n2))

 1 /************************************************************************/
 2 /* 函 数 名: BubbleSort()
 3 /* 输入参数: int iArr[], int n //n为数组长度
 4 /* 输出参数: 无
 5 /* 返 回 值: int*
 6 /* 功能描述: 输入一个数组,使用冒泡排序,将其排序(从小到大),返回数组指针
 7 /* 日    期: 2012-10-2
 8 /***********************************************************************/
 9 
10 int* BubbleSort(int iArr[], int n)
11 {
12     for (int i=0; i<n; i++)
13     {
14         for (int j=i+1; j<n; j++)
15         {
16             if (iArr[i]>iArr[j])
17             {
18                 int temp = iArr[i];
19                 iArr[i] = iArr[j];
20                 iArr[j] = temp;
21             }
22         }
23     }
24     return iArr;
25 }

 

快速排序:(Time(O(nlogn)))

/************************************************************************/
/* 函 数 名: Partition()
/* 输入参数: int iArr[], int low, int higt 
/* 输出参数: 无
/* 返 回 值: int
/* 功能描述: 完成一次快排
/* 日    期: 2012-10-5
/***********************************************************************/

int Partition(int iArr[], int low, int high)
{
    int pivotkey = iArr[low];  //存储枢轴值
    
    while(low < high)          //从表两端交替地向中间扫描
    {
        //把比枢轴值小的值移到前面
        while(low<high && iArr[high]>=pivotkey)
        {
            --high;
        }

        iArr[low] = iArr[high];
        //把比枢轴值大的值移到前面
        while(low<high && iArr[low]<=pivotkey)
        {
            ++low;
        }

        iArr[high] = iArr[low];
    }

    iArr[low] = pivotkey;  

    return low;               //返回枢轴位置
}

/************************************************************************/
/* 函 数 名: QSort()
/* 输入参数: int iArr[], int low, int higt //low为第一个数的位置,
             high为最后一个数的位置(数组长度减1)
/* 输出参数: 无
/* 返 回 值: int*
/* 功能描述: 输入一个数组,使用快速排序,将其排序(从小到大),返回数组指针
/* 日    期: 2012-10-5
/***********************************************************************/

int* QSort(int iArr[], int low, int high)
{
    if (low<high)
    {
        int pivotloc = Partition(iArr, low, high); //将数组一分为二
        QSort(iArr, low, pivotloc-1);
        QSort(iArr, pivotloc+1, high);
    }
    return iArr;
}

 

堆排序:(Time(O(nlogn)))

/************************************************************************/
/* 函 数 名: HeapAdjust()
/* 输入参数: int iArr[], int s, int m //
/* 输出参数: 无
/* 返 回 值: void
/* 功能描述: 已知iArr[s...m]中记录的关键字除iArr[s]外均满足堆的定义,
             本函数调整iArr[s...m]的关键字,使得其成为一个大顶堆
             (对其中记录的关键字而言)
/* 日    期: 2012-10-5
/***********************************************************************/

void HeapAdjust(int iArr[], int s, int m)
{//已知iArr[s...m]中记录的关键字除iArr[s]外均满足堆的定义,本函数调整
 //iArr[s...m]的关键字,使得其成为一个大顶堆(对其中记录的关键字而言)

    int rc = iArr[s];
    //沿较大孩子结点向下筛选
    for (int j=2*s; j<=m; j*=2)
    {
        //j为值较大的下标
        if (j<m && iArr[j]<iArr[j+1])
        {
            j++;
        }
        //rc应插入在s处
        if (rc>=iArr[j])
        {
            break;
        }

        iArr[s] = iArr[j];
        s = j;
    }

    iArr[s] = rc;
}

/************************************************************************/
/* 函 数 名: HeapSort()
/* 输入参数: int iArr[], int n //n为数组长度减1(参与排序元素的个数)
/* 输出参数: 无
/* 返 回 值: int*
/* 功能描述: 大顶堆排序,返回升序  !!注意:iArr中的iArr[0]不存值,或是说这个值不参与排序。
/* 日    期: 2012-10-5
/***********************************************************************/

int* HeapSort(int iArr[], int n)
{//注意:iArr中的iArr[0]不存值,或是说这个值不参与排序。
    for (int i=n/2; i>0; i--)
    {
        HeapAdjust(iArr, i, n);
    }

    for (int i = n; i>1; i--)
    {
        int temp = iArr[1];
        iArr[1] = iArr[i];
        iArr[i] = temp;

        HeapAdjust(iArr, 1, i-1);
    }
    return iArr;
}

 

合并排序:

/************************************************************************/
/* 函 数 名: MergeSort()
/* 输入参数: int iArr[], int begin, int end //end为数组下标最大值
/* 输出参数: 无
/* 返 回 值: int*
/* 功能描述: 输入一个数组,使用合并排序,将其排序(从小到大),返回数组指针
/* 日    期: 2012-9-18
/***********************************************************************/

void Merge(int* iArr, int begin, int mid, int end);

int * MergeSort(int iArr[], int begin, int end)
{
    if (begin < end)
    {
        int mid = (begin + end)/2;

        MergeSort(iArr, begin, mid);
        MergeSort(iArr, mid+1, end);
        Merge(iArr, begin, mid, end);
    }

    return iArr;
}

void Merge(int* iArr, int begin, int mid, int end)
{
    int n1 = mid - begin + 1;
    int n2 = end - mid;

    int* LArr = new int[n1+1];
    int* RArr = new int[n2+1];

    int i=0;
    int j=0;
    for (; i<n1; i++)
    {
        LArr[i] = iArr[begin+i];
    }
    for (; j<n2; j++)
    {
        RArr[j] = iArr[mid+j+1];
    }

    LArr[n1] = 1000;
    RArr[n2] = 1000;

    i = 0;
    j = 0;

    for (int k=begin; k<=end; k++)
    {
        if (LArr[i] <= RArr[j])
        {
            iArr[k] = LArr[i++];
        } 
        else
        {
            iArr[k] = RArr[j++];
        }
    }

    delete[] LArr;
    delete[] RArr;
}

 

插入排序:

 1 /************************************************************************/
 2 /*内容:本源代码主要为排序函数
 3 /*
 4 /************************************************************************/
 5 
 6 /************************************************************************/
 7 /* 函 数 名: InsertionSort()
 8 /* 输入参数: int[], int
 9 /* 输出参数: 无
10 /* 返 回 值: int*
11 /* 功能描述: 输入一个数组,使用插入排序,将其排序(从小到大),返回数组指针
12 /* 日    期: 2012-9-18
13 /***********************************************************************/
14 
15 int* InsertionSort(int iArr[], int n)
16 {
17     for (int j=1; j<n; j++)
18     {
19         int key = iArr[j];
20         int i = j-1;
21         while(i>=0 && iArr[i]>key)
22         {
23             iArr[i+1] = iArr[i];
24             i--;
25         }
26         iArr[i+1] = key;
27     }
28 
29     return iArr;
30 }

转载于:https://www.cnblogs.com/Longlycsu/archive/2012/10/05/2707720.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值