再谈数据结构(四):排序与查找

1 - 引言

虽然C++中的STL库中提供了许多排序和查找的方法。但是我们还是需要了解一下排序和查找内部的原理,下面让我们学习一下各类排序与查找算法

2 - 归并排序

第一种高效的排序算法是归并排序,按照分治三步法,对归并排序算法介绍如下:

  • 划分问题:把序列分成元素个数尽量相等的两半。
  • 递归求解:把两半元素分别排序
  • 合并问题:把两个有序表合并成一个

前两部分是很容易完成的,关键在于如何把两个有序表合成一个。如图所示,每次只需把两个序列的最小元素加以比较,删除其中较小元素并加入合并后的新表即可。由于需要一个新表来存放结果,所以附加空间为N
在这里插入图片描述

#include<cstdio>
const int maxn = 1000;
int A[maxn];
int T[maxn]={0};
void merge_sort(int* A,int x,int y,int* T){

    if(y-x>1){

        int m = x+(y-x)/2;  //划分
        int p=x, q=m,i=x;
        merge_sort(A,x,m,T);
        merge_sort(A,m,y,T);
        while(p<m||q<y){

            if(q>=y||(p<m&&A[p]<=A[q])) T[i++] = A[p++];//从左半数组赋值到临时空间

            else T[i++] = A[q++];   //右半数组复制到临时空间
        }
        for(i=x;i<y;i++) A[i] = T[i];   //从辅助空间复制回A数组
    }

}
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=0;i<n;i++)
        scanf("%d",&A[i]);
    merge_sort(A,0,n,T);
    for(int i=0;i<n;i++)
        printf("%d",A[i]);
    return 0;
}

在这里插入图片描述

3 - 快速排序

快速排序是最快的通用内部排序算法,且速度比归并排序块且不需要辅助空间。分成三步骤来实现。

  • 划分问题:把数组的各个元素重排后分成左右两部分,使得左边的任意元素都小于或等右边的任意元素
  • 递归求解:把左右两部分分别排序
  • 合并问题:不用合并,因为此时数组已经完全有序
//快速排序实现
#include<stdio.h>
#include<stdlib.h>
const int maxn = 1000;
int A[maxn];
void quick_sort(int s[],int l,int r)
{
    if(l < r)
    {
        int i=l,j=r,x=s[l];
        while(i<j)
        {
            while(i<j && s[j]>=x)//从右到左找到第一个小于x的数
                j--;
            if(i<j)
                s[i++]=s[j];

            while(i<j && s[i]<=x)//从左往右找到第一个大于x的数
                i++;
            if(i<j)
                s[j--]=s[i];

        }

        s[i]=x;//i = j的时候,将x填入中间位置
        quick_sort(s,l,i-1);//递归调用
        quick_sort(s,i+1,r);
    }
}


int main()
{

    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d",&A[i]);
    quick_sort(A,1,n);
    for(int i=1;i<=n;i++)
        printf("%d",A[i]);
    return 0;





}

在这里插入图片描述

4 - 二分查找

//快速排序实现
#include<stdio.h>
#include<stdlib.h>
const int maxn = 1000;
int A[maxn];
/**
 * 二分查找,找到该值在数组中的下标,否则为-1
 */
int bsearch(int*A, int x, int y, int v){
int m;
while(x < y) {
m = x+(y-x)/2;
if(A[m] == v) return m;
else if(A[m] > v) y = m;
else x = m+1;
}
return -1;
}


int main()
{

    int n,key,m;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d",&A[i]);
    scanf("%d",&key);
    m=bsearch(A,1,n+1,key);
    printf("%d ",m);

    return 0;





}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/HHH_ANS/article/details/84966310