常用排序算法 思想和实现()

#include <stdio.h>
#include <stdlib.h>
/*排序算法,从小到大排序*/

void swap(int *a, int *b);
int max(int a[], int n);
void array_print(int a[], int n);
int array_insert(int a[], int n, const int data);

void sort_select(int a[], int n);
void sort_bubble(int a[], int n);
void sort_insert(int a[], int n);


/*
*名称:选择排序 
*思想:每次选一个最大的放到数组的最后面。 
*/
void sort_select(int a[], int n)
{
    int size = 0, index = 0;
    for(size = n; size > 1; size--)
    {
        index = max(a, size);
        swap(&a[size - 1], &a[index]);
    }
}

//找数组中最大的元素,返回下标
int max(int a[], int n)
{
    int i = 0, index = 0;
    for(i = 0; i < n; i++)
    {
        index = ((a[index] >= a[i]) ? index : i);
    }
    
    return index;
}

//交换两个元素
void swap(int *a, int *b)
{
    int tmp = *a;
    *a = *b;
    *b = tmp;
}

/*
*名称:冒泡排序,及时终止的排序 
*思想:每次通过逐个比较选出最大的放在最后面。
*区别:比较的过程会改变经过比较的元素的顺序,
*      对比选择排序,可能不需要比较n个循环。 
*/
void sort_bubble(int a[], int n)
{
    int size = 0, j = 0, flag = 0;
    for(size = n; size > 1; size--)
    {
        flag = 0;
        for(j = 0; j < size-1; j++)
        {
            if(a[j] > a[j+1])
            {
                swap(&a[j], &a[j+1]);
                flag = 1;
            }
        }
        if(flag == 0)
        {
            printf("%d\n", size);//输出比较循环的次数 
            break;
        }
    }
}

/*
*名称:插入排序 
*思想:保护一个元素的数组是有序的,加入一个元素时也按顺序插入,结果还是有序的。
*/
void sort_insert(int a[], int n)
{
    int size = 0, i = 0;
    for(size = 1; size < n; size++)
    {
        array_insert(a, size+1, a[size]); //把a[size-1]插入有序数组a中;        
    }
}

int array_insert(int a[], int n, int data)
{
    int i = 0;
    for(i = n-2; i >= 0 && data < a[i]; i--)
    {
        a[i+1] = a[i];
    }
    a[i+1] = data;
    
    return 0;
}

/*
*名称:归并排序 
*思想:分治的策略,若n为1,算法终止;否则,将这个集合分解为2个子集合,分别排序
*    然后将排序好的子集合归并为一个集合。 
*分析:归并排序最好最坏的时间复杂度是一样的,都等于nlogn。 
*/
void sort_merge(int a[], int left, int right)
{
    int b[];
    
    if(left < right)
    {
        int i = (left + right)/2;
        sort_merge(a, left, i);
        sort_merge(a, i+1, right);
        merge(a, b, left, i, right);//合并到b
        copy(b, a, left, right);//复制到a 
    }
}

/*
*名称:自然归并排序 
*思想:在普通归并排序的基础上,首先对输入序列中已经存在的有序子序列进行归并,
*    然后再按上面的归并算法归并。 
*分析:自然归并排序最好的时间复杂度等于N,只扫描一次即可。 
*/

/*
*名称:快速排序 
*思想:选取一个支点,把数组分成两个部分,左边元素都小于支点,右边元素都大于支点,
*    然后对左右两边的分组进行快速排序。 
*快速排序最坏情况下复杂度等于n2(n的平方),最好等于nlogn,平均为nlogn。 
*/

//算法总是选取第一个元素作为支点
void sort_quick(int a[], int l, int r)
{
    if(l >= r) return;
    int i = l; //从左边开始的游标 
    int j = r+1; //从右边开始的游标 
    int pivot = a[l]; //支点 
    
    while(true)
    {
        do{ // 在左边找大于支点的元素 
            i = i+1;
        }while(a[i] < pivot);
        
        do{ // 在右边找小于支点的元素 
            j = j-1;
        }while(a[j] > pivot);
        
        if(i >= j) break;
        swap(a[i], a[j]);
    }
    
    //把支点放到左边和右边的中间位置 
    a[l] = a[j];
    a[j] = pivot;
    
    sort_quick(a, l, j-1); //对左边排序 
    sort_quick(a, j+1, r); //对右边排序 
} 

/*
*名称:堆排序 
*思想:把数组组织成堆,然后从堆中一次删除元素
*堆的初始化等于N,删除元素O(logN) ,总的复杂度为O(nlogn). 
*/

//输出数组元素
void array_print(int a[], int n)
{
    int i = 0;
    for(i = 0; i < n; i++)
    {
        printf("%d ", a[i]);
    }
    printf("\n");
} 


int main()
{
    printf("hello.\n");
    /*tst*/
    int a[10] = {3, 6, 2, 1, 87, 35, 96, 8, 12, 100};
    array_print(a, 10);
    //sort_select(a, 10);
    //sort_bubble(a, 10);
    sort_insert(a, 10);
    array_print(a, 10);
    
    system("pause");
    return 0;
}


你可能感兴趣的:(算法,System,insert,include,PIVOT,merge)