数据结构 排序算法 笔记


/*
折半插入排序是对插入排序的一种改进,主要思想是在查找插入位置的过程中
引入折半查找算法思想,利用折半查找在有序集中确定待排序元素的插入位置
与直接插入排序的区别:
    直接插入排序是从右到左按顺序查找插入位置。
    折半插入排序是在有序集中查找插入位置。
*/

# include <stdio.h>
# define LEN 6

void Half_Insert_Sort(int arr[], int n);

int main(void)
{
    int arry[LEN] = {6, 2, 4, 1, 5, 9};
    int i;
    for (i = 0; i < LEN; ++i)
        printf("%-5d", arry[i]);
    printf("\n");
    Half_Insert_Sort(arry, LEN);
    for (i = 0; i < LEN; ++i)
        printf("%-5d", arry[i]);
    printf("\n");
    
    return 0;
}

void Half_Insert_Sort(int * arr, int n)
{
    int i, j, temp;
    int low, mid, high;
    for (i = 1; i < n; ++i)
    {
        temp = arr[i];
        for (low = 0, high = i - 1; high >= low; )
        {
            mid = (low + high) / 2;
            if (temp < arr[mid])
                high = mid - 1;
            else
                low = mid + 1;
        }
        for (j = i-1; j >= low; --j)
            arr[j + 1] = arr[j];
        arr[low] = temp;
    }

    return;
}/*
折半插入排序是对插入排序的一种改进,主要思想是在查找插入位置的过程中
引入折半查找算法思想,利用折半查找在有序集中确定待排序元素的插入位置
与直接插入排序的区别:
    直接插入排序是从右到左按顺序查找插入位置。
    折半插入排序是在有序集中查找插入位置。
*/

# include <stdio.h>
# define LEN 6

void Half_Insert_Sort(int arr[], int n);

int main(void)
{
    int arry[LEN] = {6, 2, 4, 1, 5, 9};
    int i;
    for (i = 0; i < LEN; ++i)
        printf("%-5d", arry[i]);
    printf("\n");
    Half_Insert_Sort(arry, LEN);
    for (i = 0; i < LEN; ++i)
        printf("%-5d", arry[i]);
    printf("\n");
    
    return 0;
}

void Half_Insert_Sort(int * arr, int n)
{
    int i, j, temp;
    int low, mid, high;
    for (i = 1; i < n; ++i)
    {
        temp = arr[i];
        for (low = 0, high = i - 1; high >= low; )
        {
            mid = (low + high) / 2;
            if (temp < arr[mid])
                high = mid - 1;
            else
                low = mid + 1;
        }
        for (j = i-1; j >= low; --j)
            arr[j + 1] = arr[j];
        arr[low] = temp;
    }

    return;
}

 

/* 
    冒泡排序
    原理是临近的数字两两进行比较,按照从小到大或者从大到小的顺序进行交换,
    这样一趟过去后,最大或最小的数字被交换到了最后一位,
    然后再从头开始进行两两比较交换,直到倒数第二位时结束,其余类似看例子
    例子为从小到大排序
*/ 

# include <stdio.h>
# define LEN 6

void bubble_sort(int *, int);

int main(void)
{
    int arry[LEN] = {6, 2, 4, 1, 5, 9};
    int i;
    for (i = 0; i < LEN; ++i)
        printf("%-5d", arry[i]);
    printf("\n");
    bubble_sort(arry, LEN);
    for (i = 0; i < LEN; ++i)
        printf("%-5d", arry[i]);
    printf("\n");
    
    return 0;
}

void bubble_sort(int * arr, int len)
{
    int i, j;
    for (i = 0; i < len-1; ++i)
    {
        for (j = 0; j < len-1-i; ++j)
        {
            if (arr[j] > arr[j+1])
            {
                int temp;
                temp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = temp;
            }
        }
    }
    
    return;
}

/*
    Dve-C++
    - 输出大小: 128.6396484375 KiB
    - 编译时间: 1.75s
*/
/*
    快速排序
    快速排序是对冒泡排序的一种改进。基本思想是:通过一趟排序后将
    需要排序的数据分割成独立的两部分,其中一部分的所有数据都比另
    外一部分的所有数据都要小,然后再按照此方法对这两部分数据进行
    快速排序,整个排序过程可以递归进行,以此使整个数据都变成有序
    数据。 
*/

# include <stdio.h>
# define LEN 6

int quick(int *, int, int);
void sort(int *, int, int);

int main(void)
{
    int arry[LEN] = {6, 2, 4, 1, 5, 9};
    int i;
    for (i = 0; i < LEN; ++i)
        printf("%-5d", arry[i]);
    printf("\n");
    sort(arry, 0, LEN-1);
    for (i = 0; i < LEN; ++i)
        printf("%-5d", arry[i]);
    printf("\n");
    
    return 0;
}

int quick(int * arr, int low, int high)
{
    int key = 0;
    key = arr[low];
    while (low < high)
    {
        while (low < high && arr[high] >= key)
            --high;
        arr[low] = arr[high];
        while (low < high && arr[low] <= key)
            ++low;
        arr[high] = arr[low];
    }
    arr[low] = key;
    
    return low;
}

void sort(int * arr, int low, int high)
{
    if (low >= high)
        return;
    int aim = 0;
    aim = quick(arr, low, high);
    sort(arr, low, aim-1);
    sort(arr, aim+1, high);
    
    return;
}

/*
    Dve-C++
    - 输出大小: 129.1630859375 KiB
    - 编译时间: 0.34s
*/ 
/*
    选择排序
        简单选择排序的基本思想非常简单,即:第一趟,从n个元素中找出关键字
        最小的元素与第一个元素交换;第二趟,在从第二个元素开始的n-1个元素
        中再选出关键字最小的元素与第二个元素交换;如此,第k趟,则从第k个元
        素开始的n-k+1个元素中选出关键字最小的元素与第k 个元素交换,直到整
        个序列按关键字有序?选择排序是不稳定的排序方法
        在简单选择排序的基础上,对其进行改进的算法有树型选择排序和堆排序
*/ 

# include <stdio.h>
# define LEN 6

void select_sort(int *, int);

int main(void)
{
    int arry[LEN] = {3, 7, 5, 9, 1, 4};
    int i;
    for (i = 0; i < LEN; ++i)
        printf("%-5d", arry[i]);
    printf("\n");
    select_sort(arry, LEN);
    for (i = 0; i < LEN; ++i)
        printf("%-5d", arry[i]);
    printf("\n");
    
    return 0;
}

void select_sort(int * arr, int len)
{
    int i, j;
    int min;          // 记录最小数的下标 
    for (i = 0; i < len-1; ++i)
    {
        min = i;      //  假设此时下标为 i 的数最小 
        // 找出 a[i+1] 到 a[n] 之间的最小数,并将其下标用 min 记录
        for (j = i+1; j < len; ++j)
        {
            if (arr[j] < arr[min])
                min = j;
        } 
        if (min != i)
        {
            int temp;
            temp = arr[i];
            arr[i] = arr[min];
            arr[min] = temp;
        }
    }
    
    return;
}

/*
    Dve-C++
    - 输出大小: 128.6396484375 KiB
    - 编译时间: 0.38s
*/
/*
    插入排序 
        有一组数据,先取出第一个数,把它作为一个有序的数组。然后
        接着再取一个数,将它放到那个有序数组里的一个合适位置,使
        得这个数组仍然有序。如此循环下去,每次从原数组中取出一个
        数,放到有序的数组里 
*/

# include <stdio.h>
# define LEN 6

void insert_sort(int *, int);

int main(void)
{
    int arry[LEN] = {6, 2, 4, 1, 5, 9};
    int i;
    for (i = 0; i < LEN; ++i)
        printf("%-5d", arry[i]);
    printf("\n");
    insert_sort(arry, LEN);
    for (i = 0; i < LEN; ++i)
        printf("%-5d", arry[i]);
    printf("\n");
    
    return 0;
}

void insert_sort(int * arr, int len)
{
    int i, j, k, target;
    for (i = 0; i < len-1; ++i)
    {
        target = arr[i+1];
        for (j = i; j >= 0; --j)
        {
            if (target > arr[j])
                break;
        } 
        for (k = i+1; k > j+1; --k)
            arr[k] = arr[k-1];
        arr[j+1] = target;    
    }
    
    return;
}

/*
    Dve-C++
    - 输出大小: 128.6396484375 KiB
    - 编译时间: 0.41s 
*/ 
/*
    shell排序
        从第一个元素开始,对间距为 h 的元素进行排序,排好后再从第
        二个元素与间隔为 h 的元素开始往后排,直到排到第 h 个元素,
        这样就能保证所有元素都按间隔为 h 排了一遍,保证元素与间隔
        h 的元素之间是有序的。然后再按 h = (h-1)/3 不断缩小 h 在
        排一遍,一点点缩小间隔到保证间隔为 1 的元素之间都是有序的。
        这样较直接插入排序而言,减少了数组元素移动的次数。 
*/ 

# include <stdio.h>
# define LEN 6

// shell排序一遍
void shell_pass(int *, int, int);
void shell_sort(int *, int);

int main(void)
{
    int arry[LEN] = {6, 2, 4, 1, 5, 9};
    int i;
    for (i = 0; i < LEN; ++i)
        printf("%-5d", arry[i]);
    printf("\n");
    shell_sort(arry, LEN);
    for (i = 0; i < LEN; ++i)
        printf("%-5d", arry[i]);
    printf("\n");
    
    return 0;
}

// shell排序一遍,h 为当前增量
void shell_pass(int * arr, int h, int len)
{
    int i, j, key;
    for (i = h; i < len; ++i)  // 增量之后的所有记录在自己所在的组进行插入排序 
    {
        key = arr[i];  // 当前记录
        for (j = i-h; j >= 0 && arr[j] > key; j -= h)
            arr[j+h] = arr[j];
        arr[j+h] = key; 
    }
    
    return;
} 

void shell_sort(int * arr, int len)
{
    int h = len;
    do
    {
        h = h/3 + 1;  // 下一趟增量 
        shell_pass(arr, h, len);
    }while(h > 1); 
    
    return;
}

 

posted @ 2017-04-12 20:44  荒唐了年少  阅读(315)  评论(0编辑  收藏  举报