数据结构学习第10篇 - 排序算法的比较冒泡排序、直接插入排序、选择排序、希尔排序、快速排序、归并排序和堆排序

排序算法的比较   

内排序的方法有许多,教材上面提到的有:冒泡排序、直接插入排序、选择排序、希尔排序、快速排序、归并排序和堆排序。请编写一简单应用程序,实现上述提到的各种排序算法。

注意:1.需要输出每一趟排序的中间结果;

2.为方便排序算法的比较,不同排序算法请使用相同数据。


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAXSIZE 100
#define LEN 10

typedef struct
{
    int data[MAXSIZE]; //存在范围0~MAXSIZE-1
    int len;  //长度
}SqList;

void init(SqList *L,int n)
{
    L->len=n;
    for(int i=0;i<L->len;i++)
    {
        L->data[i]=rand()%(L->len*10);
    }
}

void print(SqList *L)
{
       for(int i=0;i<L->len;i++)
    {
        printf("%4d ",L->data[i]);
    }
    printf("\n");
}

//test
void TestSort(SqList L)
{
    printf("Sort Data:\n");
    print(&L);
    for(int i=0;i<L.len-1;i++)
    {
        //Sort
        print(&L);
    }
    printf("\n");
}

//1.Insertion Sort
void InsertSort(SqList L)
{
      int i,j,k,memo;
      printf("\nInsertSort:\n");
      for(i = 1; i < L.len; i++)
      {
          memo = L.data[i];
          for(j = i-1; j >= 0; j--)
          {
              
              if(memo <= L.data[j])
            {
                L.data[j+1] = L.data[j];
                if(j == 0)
                {
                    L.data[j] = memo;
                    break;
                }
            }
            else
            {
                L.data[j+1] = memo;
                break;
            }    
        }
        print(&L);
    }
}

//2.Bubble Sort
void BubbleSort(SqList L)
{
    int i,j,t;
    printf("\nBubbleSort:\n");
    for(j = 0; j < L.len; j++)
    {
        for(i = 0; i < L.len - j - 1; i++)
        {
            if(L.data[i] > L.data[i+1])
            {
                t = L.data[i];
                L.data[i] = L.data[i+1];
                L.data[i+1] = t;
            }
        }
        print(&L);
    }    
}


//3.Selection Sort
void SelectSort(SqList L)
{
    int i,j,k,min,memo;
    printf("\nSelectSort:\n");
    for(i = 0; i < L.len - 1; i++)
    {
        min = L.data[i];
        for(j = i; j < L.len; j++)
        {
            
            if(min >= L.data[j])
            {
                min = L.data[j];
                memo = j;
            }
        }
        L.data[memo] = L.data[i];
        L.data[i] = min;
        print(&L);
    }
}

//4.Shell Sort
void ShellSort(SqList L)
{
    int i,j,k,l,dk,memo,dlta[MAXSIZE];
    printf("\nShellSort:\n");
    dk = L.len / 2;                        //增量
    for(i = dk; i > 0; i = dk)
    {
        for(k = 0; k < dk; k++)
        {
        
            //直接插入算法
            for(j = k + i; j < L.len; j = j + i)
            {
                memo = L.data[j];
                for(l = j; l - i >= 0; l = l - i)
                {
                    if(L.data[l] <= L.data[l - i])
                    {
                        L.data[l] = L.data[l - i];
                        if(l - i == k)
                        {
                            L.data[l - i] = memo;
                            break;
                        }
                    }
                    else
                    {
                        L.data[l] = memo;
                        break;
                    }
                }
            }
            
        }
        dk = dk / 2;
        print(&L);
    }
}

//5.Quick Sort
struct low_high
{
    int low;
    int high;
}st[MAXSIZE];

//从左向右搜索
int split(SqList * L, int low, int high)
{
    
    int i,j,k,memo;
    memo = L->data[low];
    while(low < high)
    {
        
        while(memo <= L->data[high] && low < high)
        {
            high--;
        }
        if(low < high && memo > L->data[high])
        {
            L->data[low] = L->data[high];
        }
        while(memo >= L->data[low] && low < high)
        {
            low++;
        }
        if(low < high && memo < L->data[low])
        {
            L->data[high] = L->data[low];
        }
    }
    L->data[low] = memo;
    return low;
}

void QuickSort(SqList L)
{
    int top,w,low,high,t,i,j,k;
    printf("\nQuickSort:\n");
    top = 0;
    st[top].high = L.len - 1;
    st[top].low = 0;
    while(top > -1)
    {
        low = st[top].low;
        high = st[top].high;
        top--;
        if(low < high)
        {
            w = split(&L, low, high);
            st[++top].low = low;
            st[top].high = w - 1;
            st[++top].low = w + 1;
            st[top].high = high;
        }
        print(&L);
    }

}

//6.Merge Sort
//把两个数组归并成个一个数组
void Merge(SqList * L, int a1, int a2, int b1, int b2)
{
    int i, j, k, l, c[MAXSIZE];
    j = 0;
    k = 0;
    for(i = 0; i < a2 - a1 + b2 - b1 + 2 && j <= a2 - a1&& k <= b2 - b1; i++)
    {
        if(L->data[a1 + j] < L->data[b1 + k])
        {
            c[i] = L->data[a1 + j];
            j++;
        }
        else
        {
            c[i] = L->data[b1 + k];
            k++;
        }
    }
    if(j - 1 == a2 - a1 && k <= b2 - b1)
    {
        for(l = b1 + k; l <= b1 + b2; l++)
        {
            c[i] = L->data[l];
            i++;
        }
    }
    else
        if(k - 1 == b2 - b1 && j <= a2 - a1)
        {
            for(l = a1 + j; l <= a1 + a2; l++)
            {
                c[i] = L->data[l];
                i++;
            }
         }
     j = 0;
     for(i = a1; i <= b2; i++)
     {
         L->data[i] = c[j];
         j++;    
    }
}


void MergeSort(SqList L)
{
    int i, j, k, t;
    printf("\nMergeSort:\n");
    for(t = 1; t < L.len; t = t * 2)                            //每个子序列的长度
    {
        for(i = -1; L.len - 1 - i > 0; i = i + t * 2)            //每两个子序列遍历一次
        {
            if(L.len - 1 - i >= 2 * t)                            //当相邻子序列等长时
            {
                Merge(&L, i + 1, i + t, i + t + 1, i + t * 2);
            }
            else                                                //当相邻两个子序列不等长时
            {
                if(L.len - 1 - i > t)                
                {
                    Merge(&L, i + 1, i + t, i + t + 1, L.len - 1);
                }
            }
        }
        print(&L);     
    }
}

//7.HeapSort

void HeapAdjust(SqList * L, int s, int m)                        //对以第s个结点为根的子树进行堆排序
{
    int i, j, k, rc = L->data[s];
    for(i = s * 2 + 1; i <= m; i = i * 2 + 1)
    {
        if(i < m && L->data[i] < L->data[i + 1])
        {
            i++;
        }
        if(rc >= L->data[i])
        {
            break;
        }
        L->data[s] = L->data[i];
        s = i;
    }
    L->data[s] = rc;

}

void HeapSort(SqList L)
{
    int i, t;
    printf("\nHeapSort:\n");
    for(i = (L.len - 1) / 2; i >= 0; i--)
    {
        HeapAdjust(&L, i, L.len);
    }
    for(i = L.len - 1; i > 0; i--)
    {
        t = L.data[0];
        L.data[0] = L.data[i];
        L.data[i] = t;
        HeapAdjust(&L, 0, i - 1);
        print(&L);
    }

        
}

int main()
{
    SqList L;
    init(&L,LEN);
    TestSort(L);
    InsertSort(L);
    BubbleSort(L);
    SelectSort(L);
    ShellSort(L);
    QuickSort(L);
    MergeSort(L);
    HeapSort(L);
}

想想前端时间电面(阿里)和笔试(东方海外),都有问到快排,之前大一的时候有自己把它理解并实现,也知道它们的时间复杂度,后来真的太久没看过数据结构与算法了,春招也完全没准备就去面试了,问到快排都答不出,深感惭愧。

猜你喜欢

转载自blog.csdn.net/guanshanyue96/article/details/89011729