C++——插入排序

 排序基本概念:

(1)排序码:结点中的字段,用于排序运算中的依据(关键字或其他)、数据类型不限

(2)记录 :排序中结点数,

(3)文件:结点构成的线性表

(4)排序算法稳定:对于任意具有相同排序码的多个记录排序后,相对次序不变(反之称为                   不稳定 

1、直接插入排序

 直接插入排序

#include 
using namespace std;

template 


void DirecInsSort(T *a, int n)
{
	int i,p;//p指向空位置
	for(int i = 0; i < n; i++)
	{
		T temp = a[i];
		p = i;
		for(int j = i - 1; j >= 0; j--)
		{
			if(temp < a[p - 1])
			{
				a[p] = a[j]; 
				p = j;
			}
			else
			{
				break;
			}
		}
		a[p] = temp;
	}
}

int main()
{
	int a[5] = {1 , 6, 7 ,4 ,3};
	DirecInsSort(a,5);
	for(int i = 0; i < 5; i++)
	{
		cout << a[i];
	}
}

算法时间复杂度为O(n * n),稳定排序。

2、为优化直接插入排序,可以进行折半插入排序。

插入折半排序的思想参考

while(L <= R)//L ,R分别表示前面已排序的最小和最大段
{
	m = (L + R) / 2;
	if(A[m] > A[i])
	{
		R = m - 1;
	}
	else
	{
		L = m + 1;
	}
	ans = L // l是插入点
}

插入折半排序实现

void BinInsSort(int* a, int n)
{
	int i,L,R;
	for(i = 1; i < n; i++)//将a[i]插入a[0,..i-1]
	{
		int temp = a[i];
		L = 0;
		R = i - 1;
		while(L <= R)
		{
			int m = (L + R) / 2;//二分法
			if(temp < a[m])
				R = m - 1;
			else
				L = m + 1;
		}
		//求出插入的位置L;
		for(R = i; R > L;R--)
		{
			a[R] = a[R - 1];
		}
		a[R] = temp; // 完成插入
	}
}

int main()
{
	int a[5] = {1 , 6, 7 ,4 ,3};
	BinInsSort(a,5);
	for(int i = 0; i < 5; i++)
	{
		cout << a[i];
	}
	return 0;
}

时间复杂度为O(n \log_2n

 3、Shell排序基本思想是进行分组

C++——插入排序_第1张图片

分的组数为数据的一半,组数依次除于2递减至零。最后得到排序的结果为 6 13 20 28 39 41 72 85

shell排序是不稳定的平均移动次数为O(n ^ \frac{2}{3})

Shell排序

template 
void ShellSort(T A[], int n, int s)//s表示分组的数量就是n / 2
{
	T temp;
	int j;
	for(int k = s; k > 0; k >>= 1)//k >>= 1 表示左移一位意思就是除以2 这里表示最外层循环即进行几次分组
	{
		for(int i = k; i < n; i++)//这里从A[i]所在组前面部分进行插入排序
		{
			temp = A[i];
			j = i - k;	
			while(j >= 0 && temp < A[j])
			{
				//前面元素的条件有序,第二个条件避免无法比较
				A[j + k] = A[j];
				j = j - k;
				A[j + k] = temp;
			}		
		}
	}
}

for(int i = n/2; i>= 1; i = i/2)
{
	for(int j = 0; j < i; j++)
	{
		tmp = a[j + i];//这个思路则是取分组的前几个数即从每一组的第零位开始
	}
}

 两种方式同样要从分组后的第2个数字开始看采用插入排序。

你可能感兴趣的:(c++,算法,c语言)