各种排序算法的实现(更新中)

  这里我只贴出各种排序算法的代码,或者简单的说明,以备日后复习。

  今晚又把归并排序和快速排序实现了一遍,不要担心做重复的工作,只有把简答的工作做得很好,那么你才有能力去承担更好的工作。虽然说已经写了好多次了,但是每次都能发现自己的问题。 首先是归并排序,实现过程很简单,但是在最后竟然忘记把malloc的空间给free掉。。这是很危险的事情啊!  还有就是快速排序,快速排序的思想是任意选一个数,然后以它为基准,把这个数组划分成左右两部分,右边部分是小的,左边部分是大的。但是当选出一个数后应该怎么对整个数组进行划分呢?这个绞尽脑汁也没想出来。。╮(╯▽╰)╭。。。原来是把标准与最后一个数交换,然后设置两个指针,从头开始比较每个数组的值与最后这个值的大小,然后再变换指针,这样最后就能够得到这个标准所要插入的位置!!

  关于归并排序和快速排序的代码我就不贴出来了。具体可以看看以前是现代的归并排序快速排序

  今晚最后还把插入排序(insert_sort)实现了,这也是个非常简单的排序算法,每次用后面一个与前面的所以数字比较然后再移位就能够得到最终的结果。但是这个算法的时间复杂度是O(n^2),不推荐使用。

  2013/10/09

  这是昨天写的插入排序的代码:

  

#include <stdio.h>

void insert_sort(int arr[],int left,int right);

int main()
{
    int arr[] = {5,2,7,3,8,9};
    int i;
    
    insert_sort(arr,0,5);
    for (i = 0; i <= 5; i++)
    {
        printf("%d ",arr[i]);
    }
    printf("
");
    
    return 0;
}

void insert_sort(int arr[],int left,int right)
{
    int i,j,p_value;
    
    for (i = 1; i <= right; i++)
    {
        p_value = arr[i];
        j = i - 1;
        while((j >= 0) && (arr[j] > p_value))
        {
            arr[j+1] = arr[j];
            j--;
        }
        arr[j+1] = p_value;
    }
}

//    2013/10/08 

  希尔排序(shell_sort)

    希尔排序就是插入的改进版本,它就多了个步长,这个步长就是把数组划分为几个区域,通过将比较的全部元素分为几个区域来提升插入排序的性能。这样可以让一个元素可以一次性地朝最终位置前进一大步,然后算法再取越来越小的步长进行排序,最后到步长为1时,就是插入排序了。最终就得到了我们想要的结果。具体的实现可以去维基百科里关于希尔排序的描述。  下面是我的代码,这代码是参考维基里面的优化过的,我自己写的考虑的角度不一样,所以多了一层循环。其实用下面这种方法来遍历并进行插入排序是最好的。

#include <stdio.h>

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

int main()
{
    int arr[] = {5,9,4,10,11,2,13,6};
    int i;

    shell_sort(arr,8);
    for (i = 0; i < 8; i++)
    {
        printf("%d ",arr[i]);
    }
    printf("
");

    return 0;
}

void shell_sort(int arr[],int n)
{
    int step_size = n / 2;
    int i,j,p_value;
    
    while (step_size > 0)
    {
        for (i = step_size; i < n; i++)
        {
            j = i - step_size;
            p_value = arr[i];
            while ((j >= 0) && (arr[j] > p_value))
            {
                arr[j+step_size] = arr[j];
                j -= step_size;
            }
            arr[j+step_size] = p_value;
        }
        step_size /= 2;
    }
}

//   2013/10/09  22:16

堆排序(heap_sort)

  堆排序(Heapsort)是指利用这种数据结构所设计的一种排序算法。堆是类似于完全二叉树的结构,堆分为大顶堆和小顶堆大顶堆就是根节点是最大值,其余的每个节点都大于其子节点,小顶堆则相反。但是我们在写堆排序的时候,一般都是用数组来存储二叉树的结构,那么节点i的左右子节点分别问2*i+1和2*i+2。

  堆排序主要涉及的操作有:堆调整,建立堆,堆排序。这三个操作在具体的代码实现中可以看出来,对调整就是对堆的某个非叶子节点进行调整,也就是把它和它的叶子节点进行比较,保证i是最大的(相对叶子节点)。建立堆就是对每个非叶子节点调用堆调整函数,完成堆的建立。在堆建立完成后,这是的根节点肯定是最大(小)节点,就可以对堆进行排序了,把第一个节点与最后一个节点交换,然后输出最后一个节点,此时堆的大小减一,对第一个节点进行调整,然后再递归调用堆排序即可。

比较好的两个对堆排序的认识的网站:维基百科倒计时的博客

代码实现:

#include <stdio.h>

#define LCHILD(i) (((i)*2)+1)
#define RCHILD(i) (((i)*2)+2)
#define PARENT(i) ((i-1)/2)

//int start = (heap_size - 2) / 2;

void adjust_heap(int arr[], int heap_size, int i)
{
    int l = LCHILD(i);
    int r = RCHILD(i);
    int largest,tmp;

    if ((l <= heap_size) && (arr[l] > arr[i]))
        largest = l;
    else
        largest = i;

    if ((r <= heap_size) && (arr[r] > arr[largest]))
        largest = r;

    if (largest != i)
    {
        //交换
        tmp = arr[i];
        arr[i] = arr[largest];
        arr[largest] = tmp;

        //对刚刚被交换过的值,还要进行调整
        adjust_heap(arr,heap_size,largest);
    }
} 

void build_heap(int arr[], int heap_size)
{
    int i = (heap_size - 1) / 2;
    while (i >= 0)
    {
        adjust_heap(arr,heap_size,i);
        i--;
    }
}

void heap_sort(int arr[], int heap_size)
{
    int tmp;

    if (heap_size == 0)
    {
        printf("%d
",arr[heap_size]);
        return;
    }
    
    //第一个与最后一个交换
    tmp = arr[0];
    arr[0] = arr[heap_size];
    arr[heap_size] = tmp;

    printf("%d ",arr[heap_size]);
    adjust_heap(arr,heap_size-1,0);
    heap_sort(arr, heap_size-1);

}

int main()
{
    int arr[] = {9,2,3,1,5,4,7,6,8};
    int len = 9;

    build_heap(arr,len-1);
    heap_sort(arr,len-1);
    return 0;
}

2013/10/22 20:39
原文地址:https://www.cnblogs.com/Jason-Damon/p/3358289.html