c语言排序算法(所有的都是升序,冒泡排序、插入排序、快速排序、选择排序、希尔排序、堆排序 )

来源:互联网 发布:天津mac口红专柜 编辑:程序博客网 时间:2024/06/06 02:58
#include <stdio.h>
#include <stdlib.h>
#include <time.h>


/*
2017.7.25记录排序算法。所有的都是升序,冒泡排序、插入排序、快速排序、选择排序、希尔排序、堆排序 
(归并排序、基数排序没有实现)
还需要增加的优化代码增加升序还是降序操作。
*/
//产生随机数组
void gen_array(int arr[],int n)
{
    int i;
    unsigned sr = time(NULL);  //用当前时间做随机数种子
    srand(sr);          //初始化随机数
    for(i=0;i<n;i++)
        arr[i]=1+rand()%100;
}


void print(int a[],int n)
{
    int i;
    for(i=0;i<n;i++)
        printf("%6d",a[i]);
    printf("\n");
}
/*************************************************************************************************/ 
//传统冒泡排序  ,升序 
void BubleSort(int a[],int n)  
{  
int i,j;
    for(i=0;i<n-1;i++)  
        for(j=0;j<n-i-1;j++)  
            if(a[j]>a[j+1])  
            {  
                int t=a[j];  
                a[j]=a[j+1];  
                a[j+1]=t;  
            }  
}  
//冒泡排序改进1,添加标志位,如果某一次排序中出现没有交换位置,说明排序完成  
void maopao1(int a[],int n)  
{  
    int flag=0, i ,j;  
    for(i=0;i<n-1;i++)  
    {  
        flag=0;  
        for(j=0;j<n-i-1;j++)  
            if(a[j]>a[j+1])  
            {  
                int t=a[j];  
                a[j]=a[j+1];  
                a[j+1]=t;  
                flag=1;  
            }  
        if(flag==0)  
            break;  
    }  
}  
//冒泡排序改进2,添加标志位,记录最后一次交换位置的地方,证明最后一次交换位置之后的地方时排好序的,下一次只需要排最后一次之前的地方就好了  
void maopao2(int a[],int n)  
{  
    int flag=n-1;//刚开始,最后交换位置的地方设置为数组的最后一位  
    while(flag>0)//flag在逐渐减小,到最后肯定会变为0  
    {  
        int pos=0;//每一轮的最开始,标志位置在数组0 
int i; 
        for(i=0;i<flag;i++)  
            if(a[i]>a[i+1])  
            {  
                int t=a[i];  
                a[i]=a[i+1];  
                a[i+1]=t;  
                pos=i;  
            }  
        flag=pos;     
    }  
}  
/*************************************************************************************************/ 
//冒泡改进3,传统冒泡每趟排序遍历一次找到一个最大值或者最小值,如果每趟遍历两次就会找打一个最大值和一个最小值,减少了一半的排序趟数  
void maopao3( int r[], int n){    
    int low = 0;     
    int high= n -1; //设置变量的初始值    
    int tmp,j;    
    while (low < high) {    
        for (j= low; j< high; ++j) //正向冒泡,找到最大者    
            if (r[j]> r[j+1]) {    
                tmp = r[j]; r[j]=r[j+1];r[j+1]=tmp;    
            }     
        --high;                 //修改high值, 前移一位    
        for ( j=high; j>low; --j) //反向冒泡,找到最小者    
            if (r[j]<r[j-1]) {    
                tmp = r[j]; r[j]=r[j-1];r[j-1]=tmp;    
            }    
        ++low;                  //修改low值,后移一位    
    }     
}  
/*************************************************************************************************/ 
/*************************************************************************************************/  
//快速排序
void QuickSort(int a[], int left, int right)
{
    if (left < right)
    {
        int i = left, j = right, x = a[left];
        while (i < j)
        {
            while(i < j && a[j] >= x) // 从右向左找第一个小于x的数
                j--;  
            if(i < j) 
                a[i++] = a[j];


            while(i < j && a[i] < x) // 从左向右找第一个大于等于x的数
                i++;  
            if(i < j) 
                a[j--] = a[i];
        }
        a[i] = x;
        QuickSort(a, left, i - 1); // 递归调用 
        QuickSort(a, i + 1, right);
    }
}
//快速排序   
//第一个参数要排的数组,第二个参数第一个数,第三个参数数组成员个数  
void kuaipai(int array[],int low,int hight)  
{  
    int i,j,t,m;  
    if(low<hight)  
    {  
        i=low;  
        j=hight;  
        t=array[low];//第一个数为轴  
        while(i<j)  
        {  
            while(i<j && array[j]>t)//从右边找出小于轴的数  
                j--;  
            if(i<j)//将小于轴的数array[j]放到左边array[i]的位置  
            {  
                m=array[i];  
                array[i]=array[j];  
                array[j]=m;  
                i++;  
            }  
            while(i<j && array[i]<=t)//从左边找出大于轴的数  
                i++;  
            if(i<j)//将大于轴的数array[i]放在右边array[j]的位置  
            {  
                m=array[j];  
                array[j]=array[i];  
                array[i]=m;  
                j--;  
            }     
        }  
          
        array[i]=t;//轴放在中间,现在就有两个区域了分别是[0 i-1]和[i+1 hight],分别快排  
        kuaipai(array,0,i-1);  
        kuaipai(array,i+1,hight);  
    }  

/*************************************************************************************************/ 


/*************************************************************************************************/  
//直接插入排序:将第一个数据看做一个顺序表,将后面的数据一次插入表中  
void InsertSort(int a[], int n)    
{    
int i;
    for(i= 1; i<n; i++){    
        if(a[i] < a[i-1]){               //若第i个元素大于i-1元素,直接插入。小于的话,移动有序表后插入    
            int j= i-1;   //表中最后一个数据  
            int x = a[i];        //复制为哨兵,即存储待排序元素    
            a[i] = a[i-1];           //先后移一个元素 (因为a[i]就是X,所以不怕丢失)   
            while(j>=0 && x < a[j]){  //查找在有序表的插入位置  (遍历表)  
                a[j+1] = a[j];    
                j--;         //元素后移    
            }    
            a[j+1] = x;      //插入到正确位置    
        }    
    }    
        
}
/*************************************************************************************************/ 
/*************************************************************************************************/ 
//简单选择排序:遍历一次找到最小与第一个元素呼唤位置,再从第二个元素开始遍历找到最小与第二个元素呼唤位置...  
void SelectSort(int a[],int n)  
{  
int i;
    for(i=0;i<n-1;i++)  
    {  
        int k=i;//记录最小的那个下标的 
int j; 
        for(j=i+1;j<n;j++)  
            if(a[j]<a[k])  
                k=j;  
        if(k!=i)  
        {  
            int t=a[i];  
            a[i]=a[k];  
            a[k]=t;  
        }  
  
    }  
}  
/*************************************************************************************************/ 


/*************************************************************************************************/   
//希尔排序:去增量为d1的分为一组,共分成d1组分别进行插入排序,然后每组对应元素放在一起,然后取d2...知道d=1  
void ShellSort(int a[],int n)  
{  
    int dk;  
    int tmp;  
    for(dk=n/2;dk>0;dk/=2)  
    {
    int i;
        for(i=dk;i<n;i++)  
        {  
            tmp=a[i];  
            int j;
            for(j=i;j>=dk;j-=dk)  
                if(tmp<a[j-dk])  
                    a[j]=a[j-dk];  
                else break;  
            a[j]=tmp;  
        }
}
}  
/*************************************************************************************************/ 


/*************************************************************************************************/ 
//首先可以看到堆建好之后堆中第0个数据是堆中最小的数据。取出这个数据再执行下堆的删除操作。这样堆中第0个数据又是堆中最小的数据,
//重复上述步骤直至堆中只有一个数据时就直接取出这个数据。


//由于堆也是用数组模拟的,故堆化数组后,第一次将A[0]与A[n - 1]交换,再对A[0…n-2]重新恢复堆。第二次将A[0]与A[n – 2]交换,
//再对A[0…n - 3]重新恢复堆,重复这样的操作直到A[0]与A[1]交换。由于每次都是将最小的数据并入到后面的有序区间,故操作完成后整个数组就有序了。有点类似于直接选择排序。
//  从i节点开始调整,n为节点总数 从0开始计算 i节点的子节点为 2*i+1, 2*i+2  
void HeapAdjust(int array[], int parent, int length) {
    int temp = array[parent]; // temp保存当前父节点
    int child = 2 * parent + 1; // 先获得左孩子


    while (child < length) {
        // 如果有右孩子结点,并且右孩子结点的值大于左孩子结点,则选取右孩子结点
        if (child + 1 < length && array[child] < array[child + 1]) {
            child++;
        }


        // 如果父结点的值已经大于孩子结点的值,则直接结束
        if (temp >= array[child])
            break;


        // 把孩子结点的值赋给父结点
        array[parent] = array[child];


        // 选取孩子结点的左孩子结点,继续向下筛选
        parent = child;
        child = 2 * child + 1;
    }


    array[parent] = temp;
}
 
void HeapSort(int list[], int length) {
    // 循环建立初始堆
    int i;
    for (i = length / 2; i >= 0; i--) {
        HeapAdjust(list, i, length - 1);
    }


    // 进行n-1次循环,完成排序
    for (i = length - 1; i > 0; i--) {
        // 最后一个元素和第一元素进行交换
        int temp = list[i];
        list[i] = list[0];
        list[0] = temp;


        // 筛选 R[0] 结点,得到i-1个结点的堆
        HeapAdjust(list, 0, i);
    }
}
/*************************************************************************************************/ 


int main()
{
    int array[10];
    int len = sizeof(array)/sizeof(int);
    int ch;
    while(1)
    {
        gen_array(array,len);
        printf("Original array:\n");
        print(array,len);
        printf("Please select sort method:\n");//显示菜单
        printf("\t0 exit\n\t1 Buble sort\n\t2 Quick Sort\n\t3 Insertion Sort\n\t4 Selection Sort\n\t5 ShellSort\n\t6 HeapSort\nYour choice is>>");
        scanf("%d",&ch);
        switch(ch)
        {
        case 0:
            return 0;
        case 1:
            BubleSort(array,len);
            printf("Buble sorted array:\n");
            print(array,len);
            break;
        case 2:
            QuickSort(array,0,len-1);
            printf("Quick sorted array:\n");
            print(array,len);
            break;
        case 3:
            InsertSort(array,len);
            printf("Insertion sorted array:\n");
            print(array,len);
            break;
        case 4:
            SelectSort(array,len);
            printf("Selection sorted array:\n");
            print(array,len);
            break;
        case 5:
        /* cin>>n;  
   int *a=new int[n+1];  
   for(int j=1;j<n;j++)//注意:这里是从1开始的  
       cin>>a[j];  
   HeapSort(a,n);  
   for(int i=1;i<n;i++)  
       cout<<a[i]; */ 
            ShellSort(array,len); 
            printf("ShellSort sorted array:\n");
            print(array,len);
            break;
        case 6:
            HeapSort(array,len);
            printf("HeapSort sorted array:\n");
            print(array,len);
            break;
        case 7:
            SelectSort(array,len);
            printf("Selection sorted array:\n");
            print(array,len);
            break;
        default:
            break;
        }
        system("pause");
        system("cls");
    }
}
阅读全文
0 0
原创粉丝点击