内部排序算法总结

内部排序算法总结

1、常见的几种排序算法

内 部 排 序 { 插 入 排 序 : 直 接 插 入 排 序 , 希 尔 排 序 交 换 排 序 : 冒 泡 排 序 , 快 速 排 序 选 择 排 序 : 简 单 选 择 排 序 , 堆 排 序 合 并 排 序 分 配 排 序 : 桶 排 序 , 基 数 排 序 内部排序 \begin{cases} 插入排序: 直接插入排序,希尔排序\\ 交换排序 : 冒泡排序,快速排序\\ 选择排序: 简单选择排序,堆排序\\ 合并排序 \\ 分配排序:桶排序,基数排序 \end{cases} ::::

2 、算法性能比较
算法最好时间复杂度最坏时间复杂度平均时间复杂度空间复杂度稳定性
插入排序 O ( n ) O(n) O(n) O ( n 2 ) O(n^2) O(n2) O ( n 2 ) O(n^2) O(n2) O ( 1 ) O(1) O(1)稳定
希尔排序-- O ( n 1.3 ) O(n^{1.3}) O(n1.3) O ( 1 ) O(1) O(1)不稳定
冒泡排序 O ( n ) O(n) O(n) O ( n 2 ) O(n^2) O(n2) O ( n 2 ) O(n^2) O(n2) O ( 1 ) O(1) O(1)稳定
快速排序 O ( n l o g n ) O(nlogn) O(nlogn) O ( n 2 ) O(n^2) O(n2) O ( n l o g n ) O(nlogn) O(nlogn) O ( l o g n ) O(logn) O(logn)不稳定
选择排序 O ( n 2 ) O(n^2) O(n2) O ( n 2 ) O(n^2) O(n2) O ( n 2 ) O(n^2) O(n2) O ( 1 ) O(1) O(1)不稳定
堆排序 O ( n l o g n ) O(nlogn) O(nlogn) O ( n l o g n ) O(nlogn) O(nlogn) O ( n l o g n ) O(nlogn) O(nlogn) O ( 1 ) O(1) O(1)不稳定
归并排序 O ( n l o g n ) O(nlogn) O(nlogn) O ( n l o g n ) O(nlogn) O(nlogn) O ( n l o g n ) O(nlogn) O(nlogn) O ( n ) O(n) O(n)稳定
桶排序 O ( n ) O(n) O(n) O ( n 2 ) O(n^2) O(n2) O ( n 2 ) O(n^2) O(n2) O ( m + n ) O(m+n) O(m+n)稳定
基数排序 − - − - − - − - 稳定
3 、算法实现
插入排序:
(1)直接插入排序:

算法内容:
1)待排序数列存储在数组arr[n] 中,把数组的首元素看作一个有序数列。
2)依次将arr[i](i = 1....n-1) 插入已经排好序的序列r[0…i-1] 中,并保持有序性。
代码:

#include <iostream>
#include <fstream>

using namespace std;
//直接插入排序
void StraightSort(int *arr,int n)   //升序
{
	int temp = arr[0];
	for(int i = 1;i<n;i++)
	{
		int j = 0;
		if(arr[i] < arr[i-1])     //小于才有故事发生
		{
			temp = arr[i];
			arr[i] = arr[i-1];    //向后挪动 
			for(j = i-2; temp<arr[j] && j>=0 ;j--)
			{
				arr[j+1] = arr[j];
			}
			arr[j+1] = temp;
		}
	}

}
int main()
{
	//从txt中读取测试数据
	int array[20] = {0};
    int num_count = 0;
    string path = "D:\\code\\cpp\\cpp_proj\\algorithms\\Sort\\num.txt";
    fstream test_file;
    test_file.open(path,ios::in);
    if(!test_file)
    {
        cout<<"open failed!"<<endl;
    }
    cout<<"input num_count : ";
    test_file>>num_count;
    cout<< num_count<<endl;
    cout<<"input num:"<<endl;
    for(int i = 0;i<num_count;i++)
    {
        test_file>>array[i];
        cout<<array[i]<<"\t";
    }
    cout<<endl;

    //排序
    StraightSort(array,10);
    //显示
    for(int i = 0;i<num_count;i++)
    {
        cout<<array[i]<<"\t";
    }
    cout<<endl;
	return 0;
}		

测试数据

10
12 2 16 30 28 10 16 20 6 18

在这里插入图片描述

(2)希尔排序:

希尔排序是直接插入排序的改进,从减少排序元素个数使序列基本有序,进行改进。
算法内容:
1)待排序数列存储在数组arr[n] 中,增量序列为( d 1 , d 2 , . . . , d t d_1,d_2,...,d_t d1,d2,...,dt), n > d 1 > d 2 > . . . > d t = 1 n>d_1> d_2>...>d_t=1 n>d1>d2>...>dt=1
2)依次以 d i d_i di 为间隔,进行直接插入排序。
3)最后一次取 d t = 1 d_t = 1 dt=1 进行直接插入排序。
代码:

void ShellInsert(int *arr,int n,int dk)
{
	int temp = arr[0];
	for(int i = dk;i<n;i++)
	{
		int j = 0;
		if(arr[i]<arr[i-dk])
		{
			temp = arr[i];
			arr[i] = arr[i-dk];
			for(j = i-dk;temp<arr[j] && j>=0;j-=dk)
			{
				arr[j+dk] = arr[j];
			}
			arr[j+dk] = temp;
		}
	}
}
void ShellSort(int *arr,int n,int *dt,int t)
{
	for(int i = 0;i<t;i++)
	{
		ShellInsert(arr,n,dt[i]);
	}
}
交换排序:
(1)冒泡排序:

算法内容:
1)n个数据比较n-1趟,每趟比较n-i次,i 为趟数。
代码:

void BubbleSort(int *arr,int n)
{
	for(int i = 0;i<n-1;i++)  //趟数
	{
		for(int j = 0;j<n-i-1;j++)  //次数
		{
			if(arr[j]>arr[j+1])
			{
				arr[j] = arr[j] +arr[j+1];
				arr[j+1] = arr[j] - arr[j+1];
				arr[j] = arr[j] - arr[j+1];
			}
		}
	}
}
(2)快速排序:

j算法内容:
1)取出数组中的首元素作为基准,定义两个索引 i = low,j = high
2)从右向左扫描,找到小于基准的数,然后交换 arr[i],arr[j],i++ 其实arr[i]就是基准
3)从左向右扫描,找到大于基准的数,然后交换 arr[i],arr[j],j-- 其实arr[j]就是基准
4) 重复 2,3 直到 i == j,返回mid = i.
5) 在以mid为界对左右两个子序列重复以上步骤排序。
代码:

int Partition(int *arr,int low,int high)
{
	int temp = arr[low];
	int i = low;
	int j = high;
	while(i<j)
	{
		while(i<j && arr[j] > temp)
			j--;
		if(i<j)
		{`
			int t = arr[j];
			arr[j] = arr[i];
			arr[i] = t;
			i++;		
		}
		while(i<j && arr[i] <= temp)
			i++;
		if(i<j)
		{
			int t = arr[j];
			arr[j] = arr[i];
			arr[i] = t;
			j--;

		}
	}
	return i;
}
void QuickSort(int *arr,int low,int high)
{
	int mid = 0;
	if(low < high)
	{
		mid = Partition(arr,low,high);
		QuickSort(arr,low,mid-1);
		QuickSort(arr,mid+1,high);		
	}
}
选择排序:
(1)简单选择排序:

算法内容:
1)设待排序的元素存储在数组arr[n]中,首先选择数组中的最小元素记录为arr[min] 然后与arr[1]交换
2) 然后从arr[2] - arr[n-1]中选择最小,与arr[2]交换 ,
3)重复以上过程,n-1趟排序。
代码:

//直接选择排序
void SelectSort(int *arr,int n)
{
	for(int i = 0;i<n-1;i++)
	{
		int min = i;	
		for(int j = i+1;j<n;j++)
		{
			if(arr[j]<arr[min])
			{
				min = j;
			}
		}
		if(min != i)
		{
			int temp = arr[i];
			arr[i] = arr[min];
			arr[min] = temp;
		}
	}
}
合并排序:

算法内容:
1)分解,将待排序的序列分成规模大致相等的两个序列
2)对两个子序列进行合并排序
3)将排序好的有序子序列进行合并,得到最终序列。
代码:

void Merge(int *arr,int low,int mid,int high)
{
	int *B = new int [high-low+1];
	int i = low,j = mid+1,k = 0;
	while(i <= mid && j <= high)
	{
		if(arr[i] <= arr[j])
			B[k++] = arr[i++];
		else
			B[k++] = arr[j++];		
	}
	while(i<=mid)
		B[k++] = arr[i++];
	while(j<=high)
		B[k++] = arr[j++];
	for(i = low,k = 0;i<=high;i++)
	{
		arr[i] = B[k++];
	}
	delete []B;
}
void MergeSort(int *arr,int low,int high)
{
	if(low < high)
	{
		int mid = (low + high) / 2;
		MergeSort(arr,low,mid);
		MergeSort(arr,mid+1,high);
		Merge(arr,low,mid,high);
	}
}
分配排序:
(1)桶排序
(2)基数排序:
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FlyDremever

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值