算法排序————插入排序,希尔排序,选择排序,冒泡排序

1.插入排序:以第二个数据开始,插入到数据前已排序好的数据序列中,并使其依旧有序。

实现过程:

算法的代码实现:

//函数功能:直接插入排序,把数据从小到大排序
//arr 表示数组   len 表示长度
时间复杂度O(n^2)  空间复杂度O(1)   稳定     如果待排序列本就有序,时间复杂度为O(n)
#include<stdio.h>
int insertsort(int *arr, int len)
{
	int i = 0; int j = 0;
	int tmp;
	for (i = 0; i < len -1; i++)
	{
		for (j = i+1; j > 0; j--)
		{
			if (arr[j]>arr[j-1])
			{
				break;
			}
			else
			{
				tmp = arr[j-1];
				arr[j-1] = arr[j];
				arr[j] = tmp;
			}
		}			
	}
	return 0;	
}
int main()
{
	int arr[] = { 2, 5, 6, 8, 12, 7, 16, 11 };
	int len = sizeof(arr) / sizeof(int);
	insertsort(arr, len);
	for (int i = 0; i < len; i++)
	{
		printf("%d ", arr[i]);
	}
	printf("\n");
	return 0;
}



2.希尔排序(一个改进的插入排序):先把大数据集合划分成若干个小组,然后对每一个小组分别进行插入排序。此时,插入排序所作用的数据量比较小(每一个小组)插入的效率比较高。

第一趟:增量为4                                                                    第二趟:增量为2

第三趟:增量为1

复杂度分析:

排序方法 时间复杂度  空间复杂度  稳定性   复杂性
        平均情况  最坏情况 最好情况
希尔排序 O(n^1.3~n^1.5)  O(n^2)

  O(n)

    O(1)  不稳定

  较复杂

算法代码实现:

//希尔排序
//时间复杂度O(n^1.3  -  n^1.5)  空间复杂度O(1)  不稳定
#include<stdio.h>
void shellsort(int a[], int n)
{
	int i, j, d;
	for (d = n / 2; d>0; d /= 2)
	{
		for (i = d; i<n; ++i)
		{
			int tmp = a[i];
			for (j = i; j >= d&&a[j - d]>tmp; j -= d)
				a[j] = a[j - d];
			a[j] = tmp;
		}
	}
}

int main()
{
	int arr[] = { 2, 5, 6, 8, 12, 7, 16, 11 };
	int len = sizeof(arr) / sizeof(int);
	shellsort(arr, len);
	for (int i = 0; i < len; i++)
	{
		printf("%d ", arr[i]);
	}
	printf("\n");
	return 0;
}

3.选择排序:从头至尾扫描序列,找出最小的一个元素,和第一个元素进行交换,接着从剩下的元素中继续这种选择和交换的方式,最终得到一个有序序列。

原始序列:{2,5,6,8,12,7,16,11}

1)进行选择排序时分成有序和无序两个序列,最开始都是无序序列           {2,5,6,8,12,7,16,11}

2)从无序序列中找出最小的元素2,将2同无序序列第一个元素交换,此时产生仅含一个元素的有序序列,无序序列减一(此时可以看到,无序序列中2本来就在第一个元素中,所以无需进行交换)

{2}      {5,6,8,12,7,16,11}

3)从无序序列中取出最小的元素5,将5同无序序列第一个元素交换,此时产生仅两个元素的有序序列,无序序列减一(同上)

{2,5}   {6,8,12,7,16,11}

4)从无序序列中取出最小的元素6,将6同无序序列第一个元素交换,此时产生含三个元素的有序序列,无序序列减一

{2,5,6}   {8,12,7,16,11}

5)同上   {2,5,6,7}   {12,8,16,11}

6)从无序序列中取出最小的元素6,将6同无序序列第一个元素交换,此时产生含三个元素的有序序列,无序序列减一

{2,5,6,7,8}    {12,11,16}

{2,5,6,7,8,11}    {12,16}

7)最后一个元素肯定是最大元素,无序排序直接生产一个有序的序列

结果:{2,5,6,7,8,11,12,16}

算法代码实现:

//时间复杂度O(n^2)   空间复杂度O(1)    不稳定
#include<stdio.h>
void selectsort(int *arr, int len)
{
	int tmp, index;
	for (int i = 0; i < len-1; i++)//每次循环数组,找出最小的元素,放在前面,前面的即为排序好的
	{
		index = i;//假设最小元素的下标
		for (int j = i + 1; j < len; j++)
		{
			if (arr[j] < arr[index])//将上面假设的最小元素与数组比较,交换出最小的元素的下标
			{
				//index = j;//进行交换
				tmp = arr[index];
				arr[index] = arr[j];
				arr[j] = tmp;
			}
			if (i != index)////若数组中真的有比假设的元素还小,就交换
			{
				tmp = arr[i];
				arr[i] = arr[index];
				arr[index] = tmp;
			}
		}
	}
}
int main()
{
	int arr[] = { 2, 5, 6, 8, 12, 7, 16, 11 };
	int len = sizeof(arr) / sizeof(int);
	selectsort(arr, len);
	for (int i = 0; i < len; i++)
	{
		printf("%d ", arr[i]);
	}
	printf("\n");
	return 0;
}

4.冒泡排序:
算法实现:第一次首先将第0和第1位进行比较,并且将结果大的数字向后移动,也就是进行交换,然后将第二位和第三位进行比较,依次两两进行往后推移,最后得到排序,最后一位就是最大的数字。如下图:

算法代码实现:

//时间复杂度 O(n^2)  空间复杂度O(1)   稳定
#include<stdio.h>
void bubblesort(int *arr, int len)
{
	int tmp;
	for (int i = 0; i < len-1; i++)
	{
		for (int j = i+1; j < len; j++)
		{
			if (arr[i] > arr[j])
			{
				tmp = arr[i];
				arr[i] = arr[j];
				arr[j] = tmp;
			}
		}
	}
}
int main()
{
	int arr[] = { 2, 5, 6, 8, 12, 7, 16, 11 };
	int len = sizeof(arr) / sizeof(int);
	bubblesort(arr, len);
	for (int i = 0; i < len; i++)
	{
		printf("%d ", arr[i]);
	}
	printf("\n");
	return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章