数据结构基础排序算法

来源:互联网 发布:在手机淘宝怎么开店 编辑:程序博客网 时间:2024/06/05 05:00

从小到大排序
1、冒泡
每次从第一个元素开始与右边相邻元素两两比较,将较大元素右移。
需要移动n-1次。

void bubble(int a[], int n){    int i;    int tmp;    int j;    for(j=n-1; j>0; j--) // 需要n-1轮冒泡    {        for(i=0; i<j; i++) // 每轮冒泡将最大的移动到右侧        {            if(a[i] > a[i+1])            {                tmp = a[i];                a[i] = a[i+1];                a[i+1] = tmp;            }        }    }}

2、选择
每次选择0到i-1位置最大元素放到i位置。i从n-1到0变化。

void select(int a[], int n){    int i;    int j;    int max, u;    int tmp;    for(i=n-1; i>0; i--) // 需要选择n-1次    {        max = a[0];        u = 0;        for(j=1; j<=i; j++) // 每次选择一个最大的放到右侧        {            if(max < a[j])            {                u = j;                max = a[j];            }        }        tmp = a[i];        a[i] = a[u];        a[u] = tmp;    }}

3、插入
每次把i位置元素插入到0到i-1合适位置。i从1到n-1。

void inserts(int a[], int n){    int i;    int j;    int tmp;    for(i=1; i<n; i++) // 需要插入n-1次    {        tmp = a[i];        for(j=i-1; j>=0; j--) // 每次选择数插入到前面排好序的数组        {            if(tmp < a[j]) // 插入时找到合适位置,其它元素向后顺延            {                a[j+1] = a[j];                if(j == 0) // 需要插在第一位时特殊判断                    a[j] = tmp;            }            else            {                a[j+1] = tmp;                break;            }        }    }}

4、快速
选取第一个为基准。将基准调整在中间位置,左边全是比基准小的。右边全是比基准大的。然后对左右分别递归快排。
调整方法:i指向基准,j指向数组最后一个元素。首先从右向左找到第一个比基准小的数,放到i位置,i++。然后从左往右找第一个比基准大的元素,放到j位置,j–。重复该过程,直到i>=j。将基准放到i位置。

void quick(int a[], int l, int r){    if(l >= r) // 至少有两个元素        return;    int base = a[l]; // 选取第一个为基准    int i = l;    int j = r;    while(i < j) // 至少有两个元素才需要快排    {        while(i < j &&a[j] >= base) // 从右向左找第一个比base小的            j--;        if(i < j) // 如果找到了        {            a[i] = a[j];            i++;        }        while(i < j && a[i] <= base) // 从左向右找第一个比base大的            i++;        if(i < j) // 如果找到了        {            a[j] = a[i];            j--;        }    }    a[i] = base;    quick(a, l, i-1);    quick(a, i+1, r);}

5、归并
将数组切分成均等的两份(允许前面数组比后面数组多一个元素),分别递归这两部分,然后将这两部分合并成一部分。
合并方法:
对两部分的每个元素两两比较,较小者优先放到合并后的数组中。两部分长度不一致时,较长数组剩下元素依次放入合并后数组即可。

void merges(int a[], int l, int r){    if(l >= r)        return; // 至少有两个元素    int mid = (l + r) / 2; // 拆分进行归并排序两个子数组    merges(a, l, mid);    merges(a, mid+1, r);    // 合并两个子数组为新数组,再将新数组复制回去    int t[r-l+1];    int k = 0;    int i = l;    int j = mid+1;    while(i <= mid && j <= r)    {        if(a[i] <= a[j])        {            t[k] = a[i];            i++;        }        else        {            t[k] = a[j];            j++;        }        k++;    }    while(i <= mid)    {        t[k] = a[i];        i++;        k++;    }    while(j <= r)    {        t[k] = a[j];        j++;        k++;    }    for(i=0; i<k; i++)    {        a[i+l] = t[i];    }}

测试

#include <stdio.h>void outputa(int a[], int l, int r){    int i;    for(i=l; i<r; i++)    {        printf("%d ", a[i]);    }    printf("%d\n", a[i]);}int main(){    int a1[7] = {23, 14, 37, 48, 5, 1, 11};    bubble(a1);    printf("bubble sort...\n");    outputa(a1, 0, 6);    int a2[7] = {23, 14, 37, 48, 5, 1, 11};    select(a2);    printf("select sort...\n");    outputa(a2, 0, 6);    int a3[7] = {23, 14, 37, 48, 5, 1, 11};    inserts(a3);    printf("insert sort...\n");    outputa(a3, 0, 6);    int a4[7] = {23, 14, 37, 48, 5, 1, 11};    quick(a4, 0, 6);    printf("quick sort...\n");    outputa(a4, 0, 6);    int a5[7] = {23, 14, 37, 48, 5, 1, 11};    merges(a5, 0 ,6);    printf("merge sort...\n");    outputa(a5, 0, 6);    return 0;}
0 0
原创粉丝点击