八大基本排序

一、时间复杂度与空间复杂度

 

 二、原理与代码

1、直接插入排序

1)原理:从序列第二个数开始,将一个数插入到前面已经排序好的序列,记录数加一,以此类推。

2)代码:

//直接插入
void insertSort(int a[],int n) {
    int temp;
    for (int i = 1; i < n; i++) {
        for (int j = i; j > 0; j--) {
            if (a[j] < a[j - 1]) {
                temp = a[j];
                a[j] = a[j - 1];
                a[j - 1] = temp;
            }
        }
    }
}

 

2、冒泡排序

1)原理:

(1)比较第一个数和第二个数的大小,若前一个大于后一个,则交换;

(2)接着比较第二个和第三个,以此类推,一轮比较完,得到最大的数放在最后面;

(3)接着下一轮比较,重复(1)(2)操作,直到最后全部排序完

2)代码:

//冒泡排序
void bubbleSort(int a[], int n) {
    int temp;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j <n-1; j++) {
            if (a[j] > a[j + 1]) {
                temp = a[j];
                a[j] = a[j + 1];
                a[j + 1] = temp;
            }
        }
    }
}

3、直接选择排序

1)原理:找到最小的数放到序列的最前面,与冒泡排序相比,大大减少了交换次序

2)代码:

//直接选择排序
void sort8(int a[], int n) {
    for (int i = n-1; i > 0; i--) {for (int j = 0; j <= i; j++) {
            if (a[j] > a[0]) {
          swap(a[j],a[0]);
} }
     swap(a[0],a[i]);
} }

 

4、堆排序

1)原理:将序列转换为一颗完全二叉树,通过结点与孩子结点的大小比较,最后转换为小顶堆(或者大顶堆)

假设序列为n的序列组,具体步骤如下:

(1)取中间数mid=n/2,从序号为mid的数开始,比较该结点与孩子结点的大小,若孩子结点比父结点大,则交换;

(2)记录数减一,重复(1)(2)操作,直到得到大顶堆;

(3)交换第一个数和最后一个数,序列组长度减一,重复(1)(2)操作,直到全部排序完成。

2)代码:

//堆排序
void heapSort(int a[],int n) {
    int temp;
    for (int i = n; i > 0; i--) {
        pileSort(a,i);
        temp = a[0];
        a[0] = a[i-1];
        a[i-1] = temp;
    }
}
void pileSort(int a[],int n) {
    int mid = n / 2;
    int temp;
    for (int i = mid; i >= 0; i--) {
        if (a[i] < a[2 * i + 1] && 2 * i + 1 < n) {
            temp = a[i];
            a[i] = a[2 * i + 1];
            a[2 * i + 1] = temp;
        }
        if (a[i] < a[2 * i + 2] && 2 * i + 2 < n) {
            temp = a[i];
            a[i] = a[2 * i + 2];
            a[2 * i + 2] = temp;
        }
    }
}

 

5、希尔排序

1)原理:希尔排序又名缩小增量排序,直接插入排序在序列大部分有序的情况下,效率会非常高,希尔排序则是为了实现这一点,该排序是先把序列划分为若干个子序列,使用直接排序进行排序,最后序列基本有序后再对整个序列进行一次直接插入排序。

2)代码:

//希尔
void shellSort(int a[], int n) {
    int length = n;
    while (length > 1) {
        length = length / 2;
        for (int i = 0; i < length; i++) {
            for (int j = i + length; j < n; j = j + length) {
                int temp = a[j];
                int k;
                for (k = j - length; k >= 0 && a[k] > temp; k = k - length) {
                    a[k + length] = a[k];
                }
                a[k + length] = temp;
            }
        }
    }
}

6、快速排序

1)原理:每次操作都找出数据索引位置,形成左边的数都比这个数小,右边的数都比这个数大,再把左边的序列重复该操作,右边的序列也重复该操作。

2)代码:

void quickSort(int a[], int left,int right) {
    int mid;
    if (left < right) {
        mid = partition(a,left,right);
        quickSort(a, left, mid-1);
        quickSort(a, mid+1, right);
    }
}
int partition(int a[],int left,int right) {
    int data = a[left];
    while (left < right) {
        while (a[right] >= data && left < right) {
            right--;
        }
        a[left] = a[right];
        while (a[left] <= data && left < right) {
            left++;
        }
        a[right] = a[left];
    }
    a[left] = data;
    return left;
}

 

7、基数排序

1)原理:桶排序的拓展,将整数按位数切分为不同的数字,按每个数的位数比较。

2)代码:

//基排
void baseSort(int a[], int n,int bit) {
    int c[10][50];
    int num = 1;
    for (int i = 1; i <= bit; i++) {
        int b[10] = { 0,0,0,0,0,0,0,0,0,0 };
        if(i!=1)
            num = num * 10;
        for (int j = 0; j < n; j++) {
            int temp = (a[j] / num) %10;
            c[temp][b[temp]] = a[j];
            b[temp]++;
        }
        int m = 0;
        for (int k = 0; k < 10; k++) {
            if (b[k] > 0) {
                int end = b[k];
                for (int t = 0; t < end; t++) {
                    a[m] = c[k][t];
                    m++;
                }
            }
        }
    }
}

 

8、归并排序

1)原理:该算法是采用分治法的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。

2)代码:

//归并排序
void mergeSort(int a[], int left, int right,int b[]) {
    int mid = ((right - left) >> 1) + left;
    if (right <= left) {
        return;
    }
    mergeSort(a, left, mid, b);
    mergeSort(a, mid + 1, right, b);
    merge(a,left,right,b);
    
}
void merge(int a[],int left,int right,int b[]) {
    int mid = ((right - left) >> 1) + left;
    int i = left, j = mid+1,k = left;
    while (i <= mid && j <= right)
        b[k++] = a[i] < a[j] ? a[i++] : a[j++];
    while (i <= mid)
        b[k++] = a[i++];
    while (j <= right)
        b[k++] = a[j++];
    for (int m = left; m <= right; m++) {
        a[m] = b[m];
    }
}

 

posted @ 2020-09-16 16:31  鲤鱼程序员  阅读(124)  评论(0编辑  收藏  举报