内部排序算法总结

内部排序算法总结

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 
#include 

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

内部排序算法总结_第1张图片

(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)基数排序:

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