数据结构--排序算法

数据结构排序算法


一,排序基本概念

算法的稳定性

算法的稳定性与算法的性能无关

内部排序

元素存放在在内存中的排序

外部排序

元素不断在内外存之间移动的排序

二,插入排序

  1. 直接插入排序

适用于顺序存储和链式存储

1.1 源代码:

void InsertSort(Elemtype A[],int n){
    int i,j;
    for(i=2,i<n;i++)
    {
        if(A[i].key<A[i-1].key)//由循环条件知,该算法是稳定的
        {
            A[0]=A[i];	//A[0]起哨兵作用,防止数组越界,提高效率
            for(j=i-1;A[0].key<A[j].key;--j)//后往前查找插入的位置
            {
                A[j+1]=A[j];//向后挪位
            }
            A[j+1]=A[0];//复制到插入位置
        }//if
    }//for
}//InserSort

1.2 性能分析

空间效率:O(1)

时间效率:

  • 最好情况(已经有序) O(n)
  • 最坏情况 (逆序)O(n^2)
  • 平均情况 O(n^2)

2 折半插入排序

适用于顺序存储

2.1 源代码:

void InsertSort(ElemType A[],int n)
{
    int i,j,low,high,mid;
    for(i=2;i<n;i++)
    {
        A[0]=A[i];
        low=1;high=i-1;//问:为什么不是high=i?答:折半查找的是该点前适合插入的
        //位置,当然不能包括自己
        while(low<=high)//算法稳定
        {
            mid=(low+high)/2;
            if(A[0].key<A[mid].key)
                high = mid-1;//查找左边
            else
                low = mid + 1//查找右边
        }//while
        for(j=i-1;j>=high+1;--j)
            A[j+1]=A[j];//元素后移,最后选择的元素的位置在high+1位置上
        A[high+1]=A[0];//插入操作,问:为什么是A[high+1]=A[0];
    }
}

2.2 性能分析

比较次数为O(nlog2^n)

时间复杂度O(n^2)

3 希尔排序

不稳定且仅适用于顺序存储

3.1 源代码:

void ShellSort(ElemType A[],int n){
    //主要修改部分,前后记录位置的增量是 dk ,不是 1
    //r[0]只是暂存单元不是哨兵,当j<=0时,插入位置已到
    for(dk = n / 2;dk>=1;dk = dk / 2)//步长最后要为1
        for(i=dk+1;i<=n;i++)//i从dk+1开始有利于判断数组范围
        {
            if(A[i].key<A[i-1].key)//跟直接插入,折半插入处理方式一样
            {
                A[0]=A[i];
                for(j=i-dk;i>0&&A[0].key<A[j].key;j-=dk)//相应步长的元素比较
                {
                    A[j+dk]=A[j];//元素处理和其他插入排序类似
                }//for
                A[j+dk]=A[0];
            }//if
        }//for
}

3.2 性能分析

空间复杂度 O(1)

时间复杂度 O(n^2)

三,交换排序

1 冒泡排序

1.1 源代码

void BubbleSort(ElemType A[],int n)
{
    fir(i=0;i<n-1;i++)
    {
        flag=false;//冒泡是否交换的标志
        for(j=n-1;j>i;j--)//一趟冒泡标志,从后面往前冒泡
        {
			if(A[j-1].key>A[j].key)
            {
                swap(A[j-1],A[j]);
                flag=true;//冒泡标记
            }
        }
        if(flag==false)
            return ;
    }

1.2性能分析

空间效率 O(1)

时间复杂度 O(n^2)

  1. 快速排序

2.1 源代码

//快速排序,不稳定,
void QuickSort(ElemType A[],int low,int high){
    if(low<high)
    {
        //Partition()是划分操作
        int pivotpos = Partition(A,low,high);
        QuickSort(A,low,pivotpos-1);
        QuickSort(A,pivotpos+1,high);
    }
}

//一趟排序过程
int Partition(ELemType A[],int low,int high)
{
    ElemType pivot = A[low];
    while(low<high){
        while(low<high&&A[high]>=pivot)	--high;
        A[low]=A[high];
        while(low<high&&A[low]<=pivot)	++low;
        A[high]=A[low];
    }
    A[low]=pivot;
    return low;
}

2.2性能分析

快速排序算法是内部排序算法中平均性能最优的

空间效率

  • 最坏情况O(n)
  • 最好情况O(nlog2^n)

时间效率

  • 最好情况O(nlog2^n)
  • 最坏情况O(n^2)

四,选择排序

1 简单选择排序

1.1 源代码

void SelectSort(ElemType A[],int n){
    	for(i=0;i<n-1;i++)
        {
            min = i;
            for(j=i+1;j<n;j++)
            	if(A[j]<A[min])	min=j;
            if(min!=i)	swap(A[i],A[min]);
        }
}

1.2 性能分析

空间效率 O(1)

时间效率O(n^2)

2.堆排序

1.1 源代码

//大根堆
void BuildMaxHeap(ELemType A[],int len){
    for(int i=len/2;i>0;i--)
        AdjustDown(A,i,len);
}

void AdjustDown(ElemType A[],int k,int len){
    A[0]=A[k];
    for(i=2*k;i<=len;i*=2)
    {
        if(i<len&&a[i]<A[i+1])
            i++;
        if(A[0]>=A[i])	break;
        else{
            A[k]=A[i];
            k=i;
        }
    }//for
    A[k]=A[0];
}

//堆排序
void HeapSort(ElemType A[],int len){
    BuildMaxHeap(A,len);
    for(i=len;i>1;i--)
        swap(A[i],A[1]);
    	AdjustDown(A,1,i-1);
	}//for
}

//向上调整堆
void AdjustUp(ElemType A[],int k)
{
    A[0]=A[k];
    int i=k/2;
    while(i>0&&A[i]<A[0]){
        A[k]=A[i];
        k=i;
        i=k/2;
	}//while
    A[k]=A[0];
}

1.2 性能分析

空间效率 O(1)

时间效率 O(nlog2^n)

五,归并排序

1.1 源代码

稳定

ElemType *B=(ElemType *) malloc((n+1)*sizeof(ElemType));
void Merge(ElemType A[],int low,int mid,int high){
    for(int k=low;k<=high;;k++)
    	B[k]=A[k];
    for(i=low,j=mid+1,k=i;i<=mid&&j<=high;k++){
        if(B[i]<=B[j])
            A[k]=B[i++];
        else
            A[k]=B[j++];
    }//for
    while(j<=mid)	A[k++]=B[j++];
    while(j<=high)	A[k++]=B[j++];
}

//合并
void MergeSort(ElemType A[],int low,int high){
    if(low<high){
        int mid=(low+high)/2;
        MergeSort(A,low,mid);
        MergeSort(A,mid+1,high);
        Merge(A,low,mid,high);
    }//if
}

1.2 性能分析

空间效率 O(n)

时间效率 O(nlog2^n)

六,基数排序

性能分析

稳定

空间效率 O® r个队列

时间效率 O(d(n+r))

七,归纳总结

IMG_20190511_085055.jpg

发布了71 篇原创文章 · 获赞 7 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/CANGYE0504/article/details/90105564