排序算法(C++)

来源:互联网 发布:lofter绑定独立域名 编辑:程序博客网 时间:2024/06/02 05:51

一、插入排序

工作原理:通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。设立第一个元素为哨兵,从第二个元素开始,插入到前面大于它的数的前面。直到第n个元素结束。
时间复杂度:O(n^2)

void insert_sort(int *num,int len){    for (int i = 1;i < len;i++)    {        int tmp = num[i];        int j = i;        while(j>0 && num[j-1]>tmp)        {            num[j] = num[j-1];            j--;        }        num[j] = tmp;    }}

二、选择排序

工作原理:找出数组中最小元素和第一个元素交换,然后找出数组中次最小元素,与第二个元素进行交换。对数组中前n-1个元素按该方式继续。
时间复杂度:O(n^2)

void selection_sort(int num[], int len){    for (int i = 0; i < len - 1; i ++)    {        int j = i;        for (int k = i + 1; k < len; k++)        {            if (num[k] < num[j])            {                j = k;            }        }        if (j != i)        {            int temp = num[j];            num[j] = num[i];            num[i] = temp;        }    }}

三、冒泡排序

工作原理:每次比较相邻的元素,如果顺序错误就把它们交换过来。冒泡排序每一次循环确定一个数归位,n个数排序,要进行n-1次循环。每一次循环需要从第一位进行相邻两个数的比较,将较大的数放到后面。
时间复杂度:O(n^2)

void Bubble_sort(int num[], int len){    for (i=0;i<n;i++)     //开始冒泡排序    {        for(j=i;j<n;j++)        {            if (a[i]>a[j])            {                t = a[i];                a[i]=a[j];                a[j]=t;            }        }    }}

四、快速排序

工作原理:每次排序设置一个基准点,将小于等于基准点的数全部放在基准点的左边,大于等于基准点的数放在基准点的右边,每一次循环就是将这个基准点进行归位。快速排序是基于一种二分思想。
快速排序过程
这里写图片描述
时间复杂度:最差:O(n^2) 平均:O(nlgn)

void Quick_sort(int left,int right){    int i,j,k,tmp;    if(left>right)        return;    tmp = a[left];    i = left;    j = right;    while (i!=j)    {        while(a[j]>=tmp && i<j)            j--;        while(a[i]<=tmp && i<j)            i++;        if (i<j)        {            k = a[i];            a[i]  = a[j];            a[j] = k;        }    }a[left] = a[i];a[i] = tmp;Quick_sort(left,i-1);Quick_sort(i+1,n);}

五、归并排序

工作原理:归并排序(Merge sort)是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)。
分解待排序的n个元素的序列成各具n/2个元素的两个子序列,使用归并并排序递归地排序两个子序列,合并两个已排序好的子序列。
时间复杂度: 最佳:O(n) 最差:O(nlgn) 平均:O(nlgn)
这里写图片描述

void Merge_sort(int num[],int first,int end){    if (first < end)    {        int mid = (first + end) / 2;        Merge_sort(num, first, mid);        Merge_sort(num, mid+1, end);        Merge(num, first, mid, end);    }}void Merge(int num[],int first,int mid,int end){    int n1= mid-first+1;    int n2 = end-mid;    int *L = new int[n1];    int *R = new int[n2];    for (int i=0;i<n1;i++)    {        L[i]=num[first+i];    }    for (int j=0;j<n2;j++)    {        R[j]=num[mid+j+1];    }    int i = 0;    int j = 0;    int k = first;    while(i < n1 && j < n2)    {        if (L[i] < R[j])        {            num[k++] = L[i++];        }        else        {            num[k++] = R[j++];        }    }    while (i < n1)    {        num[k++] = L[i++];    }    while (j < n2)    {        num[k++] = R[j++];    }    delete [] L;    delete [] R;}

六、堆排序

堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。
在Max-heapify程序的每一步中,从num[i]和它的左边和右边值中选出最大的,并将其下标存储到largest中,用自底向上的方法利用过程Max-heapify把一个大小为n的数组转换成最大堆。因为数组中的最大元素总在根节点num[0]中,通过把它和num[n-1]进行互换,让元素放到正确的位置。这时候,去掉最大的节点(即len–),剩余的节点可能会违背最大堆的性质,将剩余的节点再次调用Max-heapify(num,1)构造新的最大堆,找到第二大的元素,从而实现堆排序。
这里写图片描述
时间复杂度:O(nlgn)

void Max_heapify(int num[], int i, int len){    int left = i * 2 + 1;    if (left < len)    {        int largest = left;        int right = left + 1;        if (right < len)        {            if (num[right] > num[largest])            {                largest = right;            }        }        if (num[i] < num[largest])        {            swap(num[i], num[largest]);            Max_heapify(num, largest, len);        }    }}void Heap_sort(int num[], int len){    for (int i = len / 2; i >= 0; i--)    {        Max_heapify(num, i, len);    }    for (int j = len - 1; j >= 1; j--)    {        swap(num[0], num[j]);        Max_heapify(num, 0, --len);    }}

七、桶排序、计数排序

基数排序的基本思想:对每一个输入元素x,确定小于x的元素的个数,利用这一信息,可以直接把x放到输入数组中的位置。
桶排序假设输入数据服从均匀分布,平均情况下它的时间代价为O(n),具体地说,计数排序假设输入数据都属于一个区间内的整数,而桶排序则假设输入是由一个随机过程产生,该过程将元素均匀、独立地分布在[0 ,1)区间上。桶排序将[0,1)区间划分为n个相同大小的子区间,称为桶。先对每个桶中的数进行排序,然后遍历每一个桶,按照次序把各个桶中的元素列出来即可。

void Count_Sort(int ArrIn[],int ArrOut[],int len,int limit){    int* count = new int[limit+1];    for(int i=0;i<=limit;i++)//初始化count[]        count[i] = 0;    for(int i=0;i<len;i++)//count[i]记录ArrIn[]中等于i的元素个数        count[ArrIn[i]] += 1;    for(int i=1;i<=limit;i++)//count[i]记录ArrIn[]中小于等于i的元素个数        count[i] += count[i-1];    for(int i=len-1;i>=0;i--)    {        ArrOut[count[ArrIn[i]]-1] = ArrIn[i];        count[ArrIn[i]] -= 1;    }    delete []count;}

八、基数排序

 基数排序(Radix sort)是一种非比较型整数排序算法,其原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。由于整数也可以表达字符串(比如名字或日期)和特定格式的浮点数,所以基数排序也不是只能使用于整数。
  将所有待比较数值(正整数)统一为同样的数位长度,数位较短的数前面补零。然后,从最低位开始,依次进行一次排序。这样从最低位排序一直到最高位排序完成以后,数列就变成一个有序序列。
时间复杂度:平均:O(n) 最坏:O(nlgn)

int maxbit(int data[], int n) //辅助函数,求数据的最大位数{    int d = 1; //保存最大的位数    int p = 10;    for(int i = 0; i < n; ++i)    {        while(data[i] >= p)        {            p *= 10;            ++d;        }    }    return d;}void radixsort(int data[], int n) //基数排序{    int d = maxbit(data, n);    int *tmp = newint[n];    int *count = newint[10]; //计数器    int i, j, k;    int radix = 1;    for(i = 1; i <= d; i++) //进行d次排序    {        for(j = 0; j < 10; j++)            count[j] = 0; //每次分配前清空计数器        for(j = 0; j < n; j++)        {            k = (data[j] / radix) % 10; //统计每个桶中的记录数            count[k]++;        }        for(j = 1; j < 10; j++)            count[j] = count[j - 1] + count[j]; //将tmp中的位置依次分配给每个桶        for(j = n - 1; j >= 0; j--) //将所有桶中记录依次收集到tmp中        {            k = (data[j] / radix) % 10;            tmp[count[k] - 1] = data[j];            count[k]--;        }        for(j = 0; j < n; j++) //将临时数组的内容复制到data中            data[j] = tmp[j];        radix = radix * 10;    }    delete[]tmp;    delete[]count;}

九、希尔排序

希尔排序属于插入排序的一种。希尔排序的基本思想就是把数进行分组,按照一定的规律分组,最先可以按照d1这个增量分组,d1=n/2(n为数组中数的长度)来分成d1个分组,然后对分组内部的数进行直接插入排序再设置第二个增量d2来分组,如d2 = d1/2这样来分组直到增量为1停止。希尔排序方法是一个不稳定的排序方法。
时间复杂度:最佳:O(n^s)(1

void shell_sort(int *num,int len){    int d = 0;    for (d=len/2;d>0;d=d/2)    {        for (int i = d;i < len;i++)        {            int tmp = num[i];            int j = i;            while(j>=d && num[j-d]>tmp)            {                num[j] = num[j-d];                j= j-d;            }            num[j] = tmp;        }    }}
原创粉丝点击