排序算法一------插入排序,使用二分查找法对插入排序进行优化,希尔排序

外部排序:指数据不能一次性加载到内存里去
内部排序:指数据能一次性加载到内存里去
非比较排序:不用比较就能进行的排序
比较排序:进行比较才能进行的排序
稳定性:如两个学生按照学号排:a在b的前面,按照成绩排a还是在b的前面,则这种排序算法是稳定的;若是如两个学生按照学号排:a在b的前面,按照成绩排b在a的前面,则是不稳定的(成绩是有序的)
排序算法分类:
    1、插入排序:
插入排序

.h

# pragma once
# include<stdio.h>
# include<string.h>
# include<stdlib.h>
# include<assert.h>
//插入排序
void PrintArray(int *array, int size);
void InsertSort(int *array, int size);
 

.c

# include"paixu1.h"
void PrintArray(int *array, int size)
{
	int i = 0;
	for (; i < size; ++i)
	{
		printf("%d", array[i]);
	}
	printf("\n");
}
void InsertSort(int *array, int size)
{
	int i = 1;
	for (; i < size; ++i)
	{
		int key = array[i];
		int end = i - 1;
		//查找待插入元素的位置
		while (end >= 0 && key < array[end])
		{
			array[end + 1] = array[end];
			--end;
		}
		//key大于end+1处的元素
		array[end + 1] = key;
	}
}
void TestChaRuSort()
{
	int array[] = { 2, 5, 4, 9, 3, 6, 8, 7, 1, 0 };
	PrintArray(array, sizeof(array) / sizeof(array[0]));
	InsertSort(array, sizeof(array) / sizeof(array[0]));
	PrintArray(array, sizeof(array) / sizeof(array[0]));
}
 
test.c
# include"paixu1.h"
void PrintArray(int *array, int size)
{
	int i = 0;
	for (; i < size; ++i)
	{
		printf("%d", array[i]);
	}
	printf("\n");
}
void InsertSort(int *array, int size)
{
	int i = 1;
	for (; i < size; ++i)
	{
		int key = array[i];
		int end = i - 1;
		//查找待插入元素的位置
		while (end >= 0 && key < array[end])
		{
			array[end + 1] = array[end];
			--end;
		}
		//key大于end+1处的元素
		array[end + 1] = key;
	}
}
void TestChaRuSort()
{
	int array[] = { 2, 5, 4, 9, 3, 6, 8, 7, 1, 0 };
	PrintArray(array, sizeof(array) / sizeof(array[0]));
	InsertSort(array, sizeof(array) / sizeof(array[0]));
	PrintArray(array, sizeof(array) / sizeof(array[0]));
}
 
结果:

(1)插入排序用二分法优化
begin标记起始地址,end标记最后一个元素的位置;key与中间元素进行比较

搬移元素的次数没改变,但是比较的次数相对于未优化的场景减少了;插入排序适用于(1、数据接近于有序的情况时间复杂度为O(n),不用搬移数据;2、适用于数据量较小的、元素个数较少的)
头文件及测试代码同上

.c

# include"paixu1.h"
void PrintArray(int *array, int size)
{
	int i = 0;
	for (; i < size; ++i)
	{
		printf("%d", array[i]);
	}
	printf("\n");
}
void InsertSort(int *array, int size)
{
	int i = 1;
	for (; i < size; ++i)
	{
		int key = array[i];
		int begin = 0;
		int end = i - 1;
 		int mid =-1;
		//通过二分查找查找待插入元素的位置
		while (begin<=end)
		{
			mid = begin + ((end - begin) >> 1);
			if (key>=array[mid])
				begin = mid + 1;
			else
				end = mid - 1;
		}
		//搬移元素
		end = i - 1;
		while (end >= begin)
		{
			array[end + 1] = array[end];
			--end;
		}
		array[begin] = key;
	}
}
void TestChaRuSort()
{
	int array[] = { 2, 5, 4, 9, 3, 6, 8, 7, 1, 0 };
	PrintArray(array, sizeof(array) / sizeof(array[0]));
	InsertSort(array, sizeof(array) / sizeof(array[0]));
	PrintArray(array, sizeof(array) / sizeof(array[0]));
}
 

2、希尔排序

void ShellSort(int *arr,int sz)
{
    int i=1;
    int gap=3;
    while(gap>0)
    {
        for(i=gap;i<sz;i++){                                                                           
            int key=arr[i];
            int end=i-gap;
           while(end>=0&&key<arr[end]){
                arr[end+gap]=arr[end];
                end-=gap;
           }
            arr[end+gap]=key;
        }
        gap--;                                                                                         
    }
}




关于gap取值的多种方式:
1、首先将gap直接给为size,每次给gap直接除二
2、每次都给gap取一些素数,直至取到1为止
3、每次让gap取gap除三加1的方式,gap从size的位置开始,效率很高。代码如下:
void shellSort(int *array, int size)
{
	int i = 1;
	int gap = size; 
	while (gap>1)//因为按照这种方式,gap最后一次的取值一定是1而不是0
	{
		gap = gap / 3 + 1;
		for (i = gap; i < size; ++i)//第一个分组的排序
		{
			int key = array[i];
			int end = i - gap;
			//查找待插入元素的位置
			while (end >= 0 && key < array[end])
			{
				array[end + gap] = array[end];
				end -= gap;
			}
			//插入元素
			array[end + gap] = key;
		}
 	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

xuruhua

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

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

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

打赏作者

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

抵扣说明:

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

余额充值