数据结构——快速排序、插入排序、希尔排序

目录

1.快速排序(交换排序类)

(1).基本原理

(2).具体操作讲解

(3).代码展示

 2.插入排序(插入排序类)

(1).基本原理

(2).具体操作讲解

 (3).代码展示

3.希尔排序(插入排序类)

(1).基本原理

(2).具体操作讲解

 (3).代码展示


1.快速排序(交换排序类)

(1).基本原理

快速排序C.R.A.Hoare于1962年提出的,他的基本思路是:

首先从数列中取出一个元素作为基准数;然后扫描数列,将比基准数小的元素全部放到它的左边大于或等于基准数的元素全部放到它的右边,得到左右两个区间;接着再对左右区间重复第二步(即使用递归),直到各区间少于两个元素

(2).具体操作讲解

 1.选择一个元素作为基准数(一般情况下都选择第一个元素),并创建两个左右指向(指向数组下标)。

 2.扫描数组,先从右开始判断右指向所指的元素与基准数的大小关系,若大于基准数,则将右指向向左移,继续判断大小,若小于基准数,则将该元素“填”入左指向所指的位置,然后将左指向向右移,判断左指向所指元素与基准数的大小关系,若小于基准数,则将左指向右移,若大于基准数,则将该元素“填”入右指向所指位置。随着左右指向不断的移动,最后两个指向会指向同一个元素,这时要把基准数“填”入该位置。这样本轮基准数的位置就确定了,基准数左边都是小于它的,右边都是大于它的。

 3.分别对刚才形成的左右区间再继续进行刚才的操作,一直到各区间元素数量小于2时结束。

(3).代码展示

#include<stdio.h>
#include<stdlib.h>
void kuaisu(int *a,int n)
{
	int left,right,sign,move=2;		//left、right分别作为左右指向(指向数组下标),sign是所选取的中间轴(默认为数组最左边的数),move用来标记应该移动左、右指向所指的值(为1时代表左,为2时代表右)
	left=0;
	right=n-1;
	sign=a[0];
	
	while(left<right)	//循环条件为左指向小于右指向
	{
		if(move==2)		//移动右指向所指的值
		{
			if(a[right]>=sign){right--;continue;}	//如果右指向所指的指大于选取的中间轴,则不用移动,继续判断下一个
			a[left]=a[right];
			move=1;		//令move=1,下一次移动左指向所指的值
			left++;
			continue;
		}
		if(move==1)		//移动左指向所指的值
		{
			if(a[left]<=sign){left++;continue;}		//如果左指向所指的指小于选取的中间轴,则不用移动,继续判断下一个
			a[right]=a[left];
			move=2;		//令move=2,下一次移动右指向所指的值
			right--;
			continue;
		}
	}
	a[left]=sign;		//left=right时表示该次循环结束,将开始时选择的中间轴放到left和right所指的坑
	
	if(left>1){kuaisu(a,left);}		//递归,直到所分的数组元素个数为1
	if(n-left-1>1){kuaisu(a+left+1,n-left-1);}
}


int main()
{
	int a[15]={3,31,4,54,23,67,5,89,68,43,0,87,7,9,1};
	printf("该数组经过快速排序后结果为:\n");
	kuaisu(a,15);
	
	for(int j=0;j<15;j++)
	{
		printf("%d ",a[j]);
	}
	
	return 0;
}

 2.插入排序(插入排序类)

(1).基本原理

插入排序的原理是通过构建有序序列,对于未排序的数据,在已排序列中从后往前扫描找到相应的位置并插入即对于未排序元素a,从已排序序列中从后往前比较,如果小于所比元素,则交换两者的值,直到该元素a交换到第一个元素或者大于一个已排序元素为止)。

(2).具体操作讲解

 首先默认第一个元素为已排序,从第二个元素开始与已排序序列从后往前比较,大于该元素的往后移,找到合适位置即找到比该元素小的或者已经比较完了)后继续进行下一个元素的比较,直到所有元素都为有序。

 (3).代码展示

#include<stdio.h>

void insertSort(int array[],int length)
{
	int t;
	for(int i=1;i<length;i++)	//从第二个元素开始
	{
		for(int j=0;j<i;j++)	//每次都跟它前面的元素比较
		{
			if(array[i]<array[j])	//即找到合适位置
			{
				t=array[i];		//用变量t暂时存放该元素的值
				for(int k=i-1;k>=j;k--)
				{
					array[k+1]=array[k];	//在本轮的比较中,所有大于该元素的都往前移
				}
				array[j]=t;		//最后在把该元素的值填入正确的位置
			}
		}
	}
}

int main()
{
	int array[6]={4,3,5,1,9,6};
	insertSort(array,6);
	for(int i=0;i<6;i++)
	{
		printf("%d ",array[i]);
	}
	return 0;
}

3.希尔排序(插入排序类)

(1).基本原理

希尔排序是对上面的插入排序的一种改进,由D.L.Shell于1959年提出而得名。其基本思想是把待排序的数列分为多个组,然后再对每个组进行插入排序,先让数列整体大致有序,然后多次调整分组方式,使数列更加有序,最后再使用一次插入排序,整个数列将会全部有序。

(2).具体操作讲解

 先确定分组元素的间隔即每各多少个元素将元素进行分组)。对于元素个数为length的待排序数组,第一次分组的间隔应为length/2-1(注意length为int型,第二次为length/2/2-1直到间隔为0时结束分组操作,对已经大致有序的整体再进行一次插入排序。

 (3).代码展示

#include<stdio.h>

void printArray(int array[],int length){
	for(int i=0;i<length;i++)
	{
		printf("%d ",array[i]);
	}
	printf("\n");
}

void shellSort(int array[],int length,int step){
	for(int i=0;i<length;i++)
	{
		for(int j=i+step;j<length;j+=step)
		{
			for(int k=i;k<j;k+=step)
			{
				if(array[j]<array[k])
				{
					int temp=array[j];
					for(int l=j-step;l>=k;l-=step)
					{
						array[l+step]=array[l];
					}
					array[k]=temp;
				}
			}
		}
	}
}

int main()
{
	int array[10]={49,38,65,97,76,13,27,49,55,4};
	int steps[3]={5,3,1};
	for(int i=0;i<3;i++)
	{
		shellSort(array,10,steps[i]);
		printArray(array,10);
	}
	return 0;
}

学习是痛苦的,但也是快乐的

痛苦+坚持=成功!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值