数据结构笔记——第八章 排序

排序算法

直接排序法

基本思想

在要排序的一组数中,假设前面(n-1)[n>=2] 个数已经是排好顺序的,现在要把第n个数插到前面的有序数中,使得这n个数也是排好顺序的。如此反复循环,直到全部排好顺序。

#include<stdio.h>


int main()

{

    int a[]={49,38,65,97,76,13,27,49,78,34,12,64,5,4,62,99,98,54,56,17,18,23,34,15,35,25,53,51};

    int n = 28;

    int temp,i,j;


    for(i=0;i<n;i++)

    {

        printf("%d\t",a[i]);

    }

    printf("\n");

    for(i=1;i<n;i++)

    {

        temp = a[i];

        for(j = i-1;j>=0 && temp<a[j];j--)

        {

            a[j+1] = a[j];

        }

        a[j+1] = temp;

    }

    for(i=0;i<n;i++)

    {

        printf("%d\t",a[i]);

    }

    printf("\n");

    return 0;

}

 

 

希尔排序

 

基本思想

 

算法先将要排序的一组数按某个增量d(n/2,n为要排序数的个数)分成若干组,每组中记录的下标相差d.对每组中全部元素进行直接插入排序,然后再用一个较小的增量(d/2)对它进行分组,在每组中再进行直接插入排序。当增量减到1时,进行直接插入排序后,排序完成。

 

#include<stdio.h>


#include<math.h>

#include<windows.h>

int main()

{

    int a[] = {1,54,6,3,78,34,12,45,56,100};

    int n= 10,d1=10;

    int temp,i,j,x,d;

    for(i=0;i<n;i++)

    {

        printf("%d\t",a[i]);

    }

    printf("\n");

    while(true)

    {

        d1 = ceil(d1/2);

        d = (int)d1;

        for(x=0;x<d;x++)

        {

            for(i=x+d;i<n;i=i+d)

            {

                temp = a[i];

                for(j=i-d;j>=x && temp<a[j];j=j-d)

                {

                    a[j+d] = a[j];

                }

                a[j+d] = temp;

            }

        }

        if(d == 1)

            break;

    }

    for(i=0;i<n;i++)

    {

        printf("%d\t",a[i]);

    }

    printf("\n");

    system("pause");

    return 0;

}

 

快速排序

 基本思想

 

选择一个基准元素,通常选择第一个元素或者最后一个元素,通过一趟扫描,将待排序列分成两部分,一部分比基准元素小,一部分大于等于基准元素,此时基准元素在其排好序后的正确位置,然后再用同样的方法递归地排序划分的两部分。

#include<stdio.h>


#include<math.h>

int main()

{

    int a[] = {49,38,65,97,76,13,27,49,78,34,12,64,5,4,62,99,98,54,56,17,18,23,34,15,35,25,53,51};

    int n= 28;

    int i;

    for(i=0;i<n;i++)

    {

        printf("%d\t",a[i]);

    }

    printf("\n");

    void quick_sort(int *nums,int low,int high);

    quick_sort(a,0,n-1);

    for(i=0;i<n;i++)

    {

        printf("%d\t",a[i]);

    }

    printf("\n");

    return 0;

}

int getPosition(int *nums,int low,int high)

{

    int k,pos;

    k = nums[low];

    while(low<high)

    {

        while(low<high && nums[high]>=k)

            high--;

        if(low<high)

            nums[low++] = nums[high];

        while(low<high && nums[low]<=k)

            low++;

        if(low<high)

            nums[high--] = nums[low];

    }

    nums[low] = k;

    pos = low;

    return pos;

}

void quick_sort(int *nums,int low,int high)

{

    int pos;

    if(low<high)

    {

        pos = getPosition(nums,low,high);

        quick_sort(nums,low,pos-1);

        quick_sort(nums,pos+1,high);

    }

}

 

 

归并排序

 基本思想

归并(Merge)排序法是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的。然后再把有序子序列合并为整体有序序列。

 

#include<stdio.h>


void merge_array(int *arr,int low,int mid,int high)

{

    int k,i;

    int *temp = (int *)malloc((high-low+1)*sizeof(int));

    int left_low = low;

    int left_high = mid;

    int right_low = mid + 1;

    int right_high = high;

    for(k=0;left_low<=left_high && right_low<=right_high;k++)

    {

        if(arr[left_low]<=arr[right_low])

        {

            temp[k] = arr[left_low++];

        }else

        {

            temp[k] = arr[right_low++];

        }

    }

    if(left_low<=left_high)

    {

        for(i=left_low;i<=left_high;i++)

        {

            temp[k++] = arr[i];

        }

    }

    if(right_low<=right_high)

    {

        for(i=right_low;i<=right_high;i++)

        {

            temp[k++] = arr[i];

        }

    }

    for(i=0;i<high-low+1;i++)

    {

        arr[low+i] = temp[i];

    }

    free(temp);

    return;

}

void merge_sort(int *arr,int first,int last)

{

    int mid = 0;

    if(first<last)

    {

        mid = (first+last)/2;

        merge_sort(arr,first,mid);

        merge_sort(arr,mid+1,last);

        merge_array(arr,first,mid,last);

    }

    return;

}

int main()

{

    int a[] = {49,38,65,97,76,13,27,49,78,34,12,64,5,4,62,99,98,54,56,17,18,23,34,15,35,25,53,51};

    int n= 28;

    int i;

    for(i=0;i<n;i++)

    {

        printf("%d\t",a[i]);

    }

    printf("\n\n");

    merge_sort(a,0,n-1);

    for(i=0;i<n;i++)

    {

        printf("%d\t",a[i]);

    }

    printf("\n");

    return 0;

}

 

 

简单选择排序

No.1  基本思想

在要排序的一组数中,选出最小的一个数与第一个位置的数交换;然后在剩下的数当中再找最小的与第二个位置的数交换,如此循环到倒数第二个数和最后一个数比较为止。

 

#include<stdio.h>


#include<windows.h>

int main()

{

    int a[] = {1,54,6,3,78,34,12,45};

    int n= 8;

    int i,j;

    for(i=0;i<n;i++)

    {

        printf("%d\t",a[i]);

    }

    printf("\n");

    int position,temp;

    for(i=0;i<n;i++)

    {

        position = i;

        temp = a[i];

        for(j=i+1;j<n;j++)

        {

            if(a[j]<temp)

            {

                temp = a[j];

                position = j;

            }

        }

        a[position] = a[i];

        a[i] = temp;

    }

    for(i=0;i<n;i++)

    {

        printf("%d\t",a[i]);

    }

    printf("\n");

    system("pause");

    return 0;

}

 

 

冒泡排序

基本思想

 

在要排序的一组数中,对当前还未排好序的范围内的全部数,自上而下对相邻的两个数依次进行比较和调整,让较大的数往下沉,较小的往上冒。即:每当两相邻的数比较后发现它们的排序与排序要求相反时,就将它们互换。

#include<stdio.h>


#include<math.h>

int main()

{

    int a[] = {49,38,65,97,76,13,27,49,78,34,12,64,5,4,62,99,98,54,56,17,18,23,34,15,35,25,53,51};

    int n= 28;

    int i,j;

    for(i=0;i<n;i++)

    {

        printf("%d\t",a[i]);

    }

    printf("\n");

    int temp;

    for(i=0;i<n;i++)

    {

        for(j=0;j<n-1-i;j++)

        {

            if(a[j]>a[j+1])

            {

                temp = a[j];

                a[j] = a[j+1];

                a[j+1] = temp;

            }

        }

    }

    for(i=0;i<n;i++)

    {

        printf("%d\t",a[i]);

    }

    printf("\n");

    return 0;

}

 

 

 

 

猜你喜欢

转载自blog.csdn.net/qq_40270579/article/details/81100104