算法与数据结构(四)--排序算法

一.冒泡排序

原理图:

算法与数据结构(四)--排序算法_第1张图片


实现代码:

/* 冒泡排序或者是沉底排序 */

/* int arr[]: 排序目标数组,这里元素类型以整型为例; int len: 元素个数 */
void bubbleSort (elemType arr[], int len) {
    //为什么外循环小于len-1次?
    //考虑临界情况,就是要循环到len-1个沉底/冒泡,则排序完毕
    for (int i=0; i arr[j+1]) { 
                int temp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = temp;
            }
        }
    }
}

二.插入排序


原理图:

 实现代码:

// 插入排序函数(n是数组的长度)
void insertionSort(int arr[], int n) {
    //先对第二个元素进行插入(索引比实际位置少一),直到对n个元素进行插入
    for (int i = 1; i < n; i++) {
        int key = arr[i]; // 当前要插入的元素
        j = i-1;

        // 将当前元素与前面的比较,将比当前元素大的元素往后移动,自己往前移动
        // 直到找到合适的位置或者遍历到数组的开头
        while (int j >= 0 && arr[j] > key) {
            arr[j+1] = arr[j]; // 当前元素比key大,向后移动一位
            j = j-1; // 继续向前比较
        }
        arr[j+1] = key; // 将当前元素插入到正确的位置
    }
}

三.选择排序

原理图:
算法与数据结构(四)--排序算法_第2张图片
实现代码:

void selectionSort(int arr[], int n) {
    // 遍历数组,从第一个元素到倒数第二个元素,要排序n-1次,n-1个排好才算全部排好
    for (int i = 0; i < n - 1; i++) {
        int minIndex = i;//假设当前循环开始时,第一个元素为最小值
        // 在未排序部分寻找最小值
        for (int j = i + 1; j < n; j++) {
            if (arr[j] < arr[minIndex]) {
                minIndex = j;
            }
        }
        // 如果最小值不是当前循环的第一个元素,则进行交换
        if (minIndex != i) {
            // 交换两个元素的位置
            int temp = arr[i];
            arr[i] = arr[minIndex];
            arr[minIndex] = temp;
        }
    }
}

上面三种简单排序算法在最坏情况及平均情况下都需要O(n^{2})计算时间。
下面讨论的排序算法,它在平均情况下需要O(nlogn)时间。下面这些是目前最快的排序。

四.快速排序--分治法+挖坑填数



原理:

去B站看其中快速排序的哪一节!!!

分治法:大问题分解成各个小问题,对小问题求解,使得大问题得以解决。


实现代码:

#include
using namespace std;
void PrintArray(int arr[],int len) {
	for(int i=0; i=temp) {
				j--;
			}
			//用j位置的数据给i的坑填数(将j的数据赋值给i),j变成坑
			if(i

五.归并排序/合并排序--分治法+合并两个有序序列

基本思想:分治法+将两个有序序列合并成一个有序序列
怎么合并呢?
就是开辟一块临时的存储空间。就比如有两个身高从低到高的队伍,要合并成一个也是身高从小到高的队伍,就先将每个队伍的第一个人比较身高,然后低的进去,然后第二个人再与另一个队的第一个人比较身高,低的进去。。。以此类推,差不多就是这样。

去B站看其中合并排序的哪一节!!!

#include
#include
#include
using namespace std;
#define MAX 10
//创建数组
int* CreatArray() {
	srand((unsigned int)time(NULL));
	int* arr=(int*)malloc(sizeof(int)*MAX);
	for(int i=0; i=end) {
		return;
	}
	int mid=(start+end)/2;
	//分组
	//左半边
	MergeSort(arr,start,mid,temp);
	//右半边
	MergeSort(arr,mid+1,end,temp);
	//合并
	Merge(arr,start,end,mid,temp);

}
int main() {
	int* myArr=CreatArray();
	PrintArray(myArr,MAX);
	//辅助空间,来存储合并后的有序序列。
	int * temp=(int*)malloc(sizeof(int)* MAX) ;
	MergeSort(myArr,0,MAX-1,temp);
	PrintArray(myArr,MAX);
	//释放空间
	free(temp);
	free(myArr);
}

六.希尔排序--分治法+插入排序(插入排序的提升版)

[算法]六分钟彻底弄懂希尔排序,简单易懂

20希尔排序

#include 
void shellSort(int arr[],int length) {
	int increasement=length;
	//确定分组的增量,你可以用你喜欢的增量,我这里取长度除以2 
	increasement=increasement/2;
	//增量小于1停止,也就是最后对一整组进行插入排序后停止 
	while(increasement>1) {
		
		//遍历每一组
		for(int i=0; i=0&&temp

为什么分组后的插入排序会快呢?
因为插入排序在元素序列基本有序和元素个数比较小的时候速度较快,而分组就创造了这种条件。

总结

可以发现,下面三种快的排序(平均情况下的时间复杂度都为O(nlogn))都使用了分治法,将一个大问题分为几个相同的小问题,分而治之。

你可能感兴趣的:(算法,数据结构,c++)