1. 程式人生 > >常用排序:氣泡排序,選擇排序,插入排序,希爾排序,歸併排序,快速排序等

常用排序:氣泡排序,選擇排序,插入排序,希爾排序,歸併排序,快速排序等

#include <stdio.h>
#define MAX 10

typedef int  ElementType;

typedef ElementType ARR[MAX];

void swap(ARR arr,int i,int j)
{
    ElementType temp = arr[i];
    arr[i] = arr[j];
    arr[j] = temp;
}

void print(ARR arr)
{
    int i;
    for(i = 0;i < MAX;i++)
        printf("%d ",arr[i]);
    printf("\n");
}

void bubble1(ARR arr);
void bubble2(ARR arr);
void select(ARR arr);
void insert(ARR arr);
void shell(ARR arr);
void heap(ARR arr);
void merge(ARR arr,int left,int mid,int right);
void mergesort1(ARR arr);
void mergesort2(ARR arr,int left,int right);
int pivotkey1(ARR arr,int low,int high);
int pivotkey2(ARR arr,int low,int high);
void quicksort1(ARR arr,int low,int high);
void quicksort2(ARR arr,int low,int high);
ElementType getpivot(ARR arr,int low,int high);


int main()
{
    ARR arr1 = {8,7,5,6,4,10,9,1,2,3};
    ARR arr2 = {8,7,5,6,4,10,9,1,2,3};
    ARR arr3 = {8,7,5,6,4,10,9,1,2,3};
    ARR arr4 = {6,3,9,8,4,2,7,5,1,10};
    ARR arr5 = {6,4,2,5,10,7,1,8,3,9};
    ARR arr6 = {6,4,2,5,10,7,1,8,3,9};
    ARR arr7 = {6,4,2,5,10,7,1,8,3,9};
    ARR arr7 = {10,9,8,7,6,5,4,3,2,1};

    bubble1(arr1);
    bubble2(arr1);
    select(arr2);
    insert(arr3);
    shell(arr4);
    heap(arr5);
    mergesort1(arr6);
    mergesort2(arr6,0,MAX-1);
    quicksort1(arr7,0,9);
    quicksort2(arr7,0,9);

    return 0;
}

void bubble1(ARR arr)//氣泡排序
{
    int i,j;
    for(i = 0;i < MAX - 1;i++)
    {
        for(j = 0;j < MAX - 1 - i;j++)
        {
            if(arr[j] > arr[j+1])
                swap(arr,j,j+1);
        }
        print(arr);
    }
}

void bubble2(ARR arr)//氣泡排序改進
{
    int i,j;
    int flag = 0;
    for(i = 0;i < MAX - 1;i++)
    {
        flag = 0;
        for(j = 0;j < MAX - 1 - i;j++)
        {
            if(arr[j] > arr[j+1])
            {
                flag = 1;
                swap(arr,j,j+1);
            }
        }
        if(flag == 0)
            break;
        print(arr);
    }
}

void select(ARR arr)
{
    int i,j;
    int min;
    for(i = 0;i < MAX - 1;i++)
    {
        min = i;
        for(j = i+1;j < MAX;j++)
            if(arr[min] > arr[j])
                min = j;
        if(min != i)
            swap(arr,i,min);
        print(arr);
    }
}

void insert(ARR arr)//插入排序
{
    int i,j;
    for(i = 1;i < MAX;i++)
    {
        if(arr[i-1] > arr[i])
        {
            ElementType temp = arr[i];
            for(j = i-1;j >= 0;j--)
            {
                if(arr[j] > temp)
                    arr[j+1] = arr[j];
                else
                    break;
            }
            arr[j+1] = temp;
            print(arr);
        }
    }
}
//希爾排序
void shell(ARR arr)
{
    int a[] = {1,3,5};//增量
    int k = 2;
    int step = a[k];
    int i,j;
    while(k >= 0)
    {
        for(i = step;i < MAX;i++)
        {
            if(arr[i-step] > arr[i])
            {
                ElementType temp = arr[i];
                for(j = i-step;j >= 0;j -= step)
                    if(arr[j] > temp)
                        arr[j+step] = arr[j];
                    else
                        break;
                arr[j+step] = temp;
            }
        }
        step = a[--k];
        print(arr);
    }
}

//堆調整
void heapadjust(ARR arr,int n,int m)
{
    ElementType temp = arr[n];
    int i;
    for(i = 2*n+1;i <= m;i = 2*i+1)
    {
        if(i < m && arr[i] < arr[i+1])
            i++;
        if(arr[i] < temp)
            break;
        arr[n] = arr[i];
        n = i;
    }
    arr[n] = temp;
}
//堆排序
void heap(ARR arr)
{
    int i;
    for(i = (MAX-2)/2;i >= 0;i--)//初始化堆
        heapadjust(arr,i,MAX-1);//進行堆調整
    for(i = MAX - 1;i > 0;i--)
    {
        swap(arr,0,i);
        heapadjust(arr,0,i-1);
        print(arr);
    }
}
//進行歸併
void merge(ARR arr,int left,int mid,int right)
{
    int len = right-left+1;
    ElementType temp[len];
    int k = 0;
    int i = left;
    int j = mid+1;
    while(i<=mid && j<=right)
    {
        if(arr[i] < arr[j])
            temp[k++] = arr[i++];
        else
            temp[k++] = arr[j++];
    }
    while(i<=mid)
        temp[k++] = arr[i++];
    while(j<=right)
        temp[k++] = arr[j++];
    for(i = 0;i < len;i++)
        arr[left+i] = temp[i];
}

//歸併排序1
void mergesort1(ARR arr)//非遞迴的歸併排序
{
    int left,right,mid;
    int i;
    for(i = 1;i < MAX;i *= 2)//i為步長
    {
        left = 0;
        while(left+i < MAX)
        {
            mid = left+i-1;
            right = (mid+i)<(MAX-1)?(mid+i):(MAX-1);
            merge(arr,left,mid,right);
            left = right+1;
        }
        print(arr);
    }
}
//歸併排序2
void mergesort2(ARR arr,int left,int right)//遞迴的歸併排序
{
    if(left == right)
        return;
    int mid = (left+right)/2;
    mergesort2(arr,left,mid);
    mergesort2(arr,mid+1,right);
    merge(arr,left,mid,right);
    print(arr);
}

//方法一:獲得樞軸的位置
int pivotkey1(ARR arr,int low,int high)
{
    //int pivot = arr[low];//選取樞軸的初始化位置
    int pivot = getpivot(arr,low,high);
    while(low < high)
    {                                                    //3 4 2 5 7 1 6 8 10 9
        while(low<high && arr[high] > pivot)            //3 4 2 5 1 6 7 8 10 9
            high--;                                        //3 4 2 5 7 1 6 8 10 9 
        arr[low] = arr[high];
        while(low<high && arr[low] < pivot)
            low++;
        arr[high] = arr[low];
    }
    arr[low] = pivot;
    print(arr);
    return low;
}
//方法二:獲得樞軸的位置
int pivotkey2(ARR arr,int low,int high)
{
    //int pivot = arr[low];//選取樞軸的初始化位置
    int pivot = getpivot(arr,low,high);
    int tail = low+1;
    int i;
    for(i = low+1;i <= high;i++)
    {
        if(arr[i] <= pivot)
        {
            if(i != tail)
                swap(arr,i,tail);
            tail++;
        }
    }
    swap(arr,low,--tail);
    print(arr);
    return tail;
}

//快速排序
void quicksort1(ARR arr,int low,int high)
{
    if(low < high)
    {
        int pivot = pivotkey2(arr,low,high);
        quicksort1(arr,low,pivot-1);
        quicksort1(arr,pivot+1,high);
    }
}
//獲得樞軸的改進
ElementType getpivot(ARR arr,int low,int high)
{
    int mid = (low + high) / 2;
    if(arr[high] < arr[low])
        swap(arr,low,high);
    if(arr[high] < arr[mid])
        swap(arr,high,mid);
    if(arr[mid] > arr[low])
        swap(arr,mid,low);
    return arr[low];
}
//快速排序改進
void quicksort2(ARR arr,int low,int high)
{
    while(low < high)
    {
        int pivot = pivotkey2(arr,low,high);
        quicksort2(arr,low,pivot-1);
        low = pivot+1;//尾遞迴
    }
}