【数据结构】排序算法代码汇总

各种排序算法性能比较

代码实现(堆排序没有写)

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

#define MAXSIZE 100

typedef int ElemType;

//线性表结构
typedef struct{
    ElemType data[MAXSIZE];
    int length;
}sqList;

//线性表的遍历
void traverse(sqList L){
    for(int i=1; i<=L.length; i++){
        printf("%d ", L.data[i]);
    }
    printf("\n");
}


/////////插入排序///////////////
//我们都是从小到大排序
//直接插入排序,时间复杂度n^2
void InsertSort(sqList &L){
    //从第二个元素开始插入
    for(int i=2; i<=L.length; i++){
        if(L.data[i] < L.data[i-1]){    //需要交换次序
            L.data[0] = L.data[i];      //设置哨兵
            L.data[i] = L.data[i-1];    
            //后移元素
            int j;
            for(j=i-2; L.data[i]>L.data[j]; j--){
                L.data[j+1] = L.data[j];    //后移元素
            }
            L.data[j+1] = L.data[0];
        }
    }
}

//折半查找版的直接插入排序
//在查找插入位置的时候时间复杂度为logn,查找n个就是nlogn
//但是关键字的移动次数还是不变
void BInsertSort(sqList &L){
    for(int i=2; i<=L.length; i++){
        if(L.data[i] < L.data[i-1]){
            L.data[0] = L.data[i];
            int high = i-1;
            int low = 1;
            int mid;
            while(low <= high){
                mid = (high + low)/2;
                if(L.data[mid] > L.data[0]){    //应该插入低半区
                    high = mid-1;
                } else {    //应该插入高半区
                    low = mid+1;
                }
            }//while
            //移动元素
            for(int j=i-1; j>=high+1; j--){
                L.data[j+1] = L.data[j];
            }
            L.data[high+1] = L.data[0];
        }
    }
}

//希尔排序
void ShellInsert(sqList &L, int dk){
    for(int i = dk+1; i<=L.length; i++){
        if(L.data[i] < L.data[i-dk]){
            L.data[0] = L.data[i];
            int j;
            for(j = i-dk; j>0 && L.data[0]<L.data[j]; j-=dk){
                L.data[j+dk] = L.data[j];
            }
            L.data[j+dk] = L.data[0];
        }
    }
}
//dlta[]是增量序列
int dlta[3] = {5, 3, 1};
void ShellSort(sqList &L, int dlta[], int t){
    for(int k=0; k<t; k++){
        ShellInsert(L, dlta[k]);
    }
}

////////交换排序/////////////
//冒泡排序
void bubble(sqList &L){
    for(int i=L.length; i>=2; i--){
        int flag = 1;
        for(int j=1; j<=i; j++){
            if(L.data[j] > L.data[j+1]){
                flag = 0;
                ElemType temp = L.data[j];
                L.data[j] = L.data[j+1];
                L.data[j+1] = temp;
            }
        }
        if(flag == 1){
            return;
        }
    }
}

//快速排序(真的挺快的)
//要让关键字左边的元素都比关键字小,右边的元素都比关键字大
int Partition(sqList &L, int low, int high){
    L.data[0] = L.data[low];    //暂存关键字
    while(low < high){
        while(low < high && L.data[high] >= L.data[0]) high--;
        L.data[low] = L.data[high];     //找到右边一个比关键字小的换到low位置
        while(low < high && L.data[low] <= L.data[0]) low++;
        L.data[high] = L.data[low];     //找到左边一个比关键字大的换到high位置
    }
    L.data[high] = L.data[0];   //此时low=high了
    return high;
}

void QSort(sqList &L ,int low, int high){
    if(low < high){
        int pivotloc = Partition(L, low, high);
        QSort(L, low, pivotloc-1);
        QSort(L, pivotloc+1, high);
    }
}

///////////选择排序///////////////
//简单选择排序(真的很简单)
void EasySelect(sqList &L){
    for(int i=1; i<L.length; i++){
        int j = i+1;
        int min = i;
        while(j<=L.length){
            if(L.data[j] < L.data[min]){
                min = j;        //找到最小元素的下标
            }
            j++;
        }
        if(min != i){   //交换
            ElemType temp = L.data[i];
            L.data[i] = L.data[min];
            L.data[min] = temp;
        }
    }
}

//堆排序(很快,但是不好想)
//从小到大排序要使用小根堆
void HeapAdjust(sqList &L, int s, int m){
    //本函数进入条件为,除了结点s之外都满足堆的定义
    //调整s使整棵树变成大根堆
    L.data[0] = L.data[s];
    for(int i=s*2; i<=m; i*=2){ //直接指向s的孩子结点
        if(i<m && L.data[i] < L.data[i+1]) i++; //选择最大的那个孩子结点
        if(L.data[0] > L.data[i]) break;    //s就应该在这里了
        L.data[s] = L.data[i];  //小的结点上去
        s = i;  //下一个待插入的结点是i,用s来指向
    }
    L.data[s] = L.data[0];
}

void HeapSort(sqList &L){
    //建大顶堆
    for(int i=L.length/2; i>=1; i--){   //从第一个有孩子结点的结点开始调整
        HeapAdjust(L, i, L.length);
    }
    for(int i=L.length; i>1; i--){
        ElemType temp = L.data[1];
        L.data[1] = L.data[i];
        L.data[i] = temp;
        HeapAdjust(L, 1, i-1);
    }
}

///////归并排序//////////
//需要两个数组
void Merge(sqList SR, sqList &TR, int i, int m, int n){
    int j, k;
    //k是TR指针,i是SR左半边指针,j是SR右半边指针
    for(j=m+1, k=i; i<=m && j<=n; k++){
        if(SR.data[i] < SR.data[j]) TR.data[k] = SR.data[i++];
        else TR.data[k] = SR.data[j++];
    }
    while(i<=m) TR.data[k++] = SR.data[i++];
    while(j<=n) TR.data[k++] = SR.data[j++];
}

void MSort(sqList SR, sqList &TR, int s, int t){
    sqList TR2; //注意这里需要在每一层递归写一个变量,用于记录归并的中间结果
    if(s == t) TR.data[s] = SR.data[s]; 
    else {
        int m = (s+t)/2;
        MSort(SR, TR2, s, m);
        MSort(SR, TR2, m+1, t);
        Merge(TR2, TR, s, m, t);
    }
}

//////////堆排序////////////
//好麻烦,不写了
发布了130 篇原创文章 · 获赞 151 · 访问量 19万+

猜你喜欢

转载自blog.csdn.net/haohulala/article/details/96570589