排序算法问题(二)

排序算法问题(一)直接选择排序,冒泡排序,插入排序,快速排序,归并排序

堆排序

核心思想

堆:

1.完全二叉树。
2.父节点大于子节点。
用一维数组表示完全二叉树,因此数列如果不满足父节点大于子节点就需要调整,从倒数第二行开始往前整理。

排序:

将堆中的根节点与最后一个节点位置交换,再砍断最后一个节点,得到的数即为最大值,再将剩下的数重新整理为堆,再重复操作。

For instance:

上源码:

#include<stdio.h>
#define N 5
void swap(int arr[],int i,int j)
{
	int temp;
	temp=arr[i];
	arr[i]=arr[j];
	arr[j]=temp;
}
//调整父节点大于子节点
void heapify(int tree[],int n,int i)
{   
	int c1,c2,max;
	c1 = 2*i+1;//左孩子节点
	c2 =2*i+2;//右孩子节点
	max =i;//根节点
	if(i>=n)//递归出口
		return;
	if(c1<n&&tree[c1]>tree[i])
		max =c1;
	if(c2<n&&tree[c2]>tree[max])
		max = c2;
	if(max!=i)//如果根节点不是最大
		{
			swap(tree,max,i);//交换根节点与子节点的值
		    heapify(tree,n,max);//子节点作为父节点再与他的字节点比较
	    }
}
//当数较乱时,建立堆使根节点大于子节点
void build_heap(int tree[],int n)
{
	int last_node = n-1;//从后往前
	int parent = (last_node-1)/2;//父亲节点
	int i;
	for(i = parent;i>=0;i--)
	{
		heapify(tree,n,i);
	}
}
void heep_sort(int tree[],int n)
{
	int i;
	build_heap(tree,n);//保证为堆
	for(i=n-1;i>=0;i--)
	{
		swap(tree,i,0);//将根节点和最后一个节点交换
		heapify(tree,i,0);//舍弃最后一个节点,因为它已经是最大
	}

}
int main(){
	int tree[N];
	int n=N,i;
	printf("请输入%d个整数:\n",n);
	for(i=0;i<N;i++)
		scanf("%d",&tree[i]);
	heep_sort(tree,n);
	for(i=0;i<N;i++)
		printf("%d ",tree[i]);
	putchar('\n');
	return 0;
}

希尔排序

核心思想:

1.希尔排序是对插入排序的改进。
2.插入排序在数据元素比较少,或者数据元素基本有序时,算法效率高。
3.因此在数据元素比较大,元素又无序时,可以先将数据整理成基本有序,再最后用一次插入排序。
将待排数据分成若干子序列(将间隔一定距离的数据组成一个序列,然后不断缩小距离组成数列(比如刚开始的子序列的位置为1,5,9…&&2,6,10…&&…下次分组为1,3,5…&&2,4,6&&…)),分别进行插入排序,待整体数据基本有序时,再对整体数据进行一次插入排序。
在这里插入图片描述
在这里插入图片描述
上源码:

#include <stdio.h>
#define N 10
void shell_sort(int array[], int length){
	int i,j,k;
	int gap;	//gap是分组的步长
	int temp;	//暂存数据
	for(gap=length/2; gap>0; gap=gap/2)
	{//逐渐减小间距
		for(i=0; i<gap; i++)
		{//将数据分组
			for(j=i+gap; j<length; j=j+gap)//每组数据进行插入排序
			{	//单独一次的插入排序
				temp=array[j];
				for(k=j;k>=0&&temp<array[k-gap];k=k-gap)
				{
					array[k]=array[k-gap];
				}
				array[k]=temp;
			}
				//下面注释代码为while循环实现内层for循环效果
				/*if(array[j] < array[j - gap])
				{
					temp = array[j];	//将位置j的数据取出
					k = j - gap;//记录j元素之前的元素位置
					while(k>=0 && array[k]>temp)//改组中将前面比j位置大的数据往后移
					{
						array[k + gap] = array[k];
						k = k - gap;
					}
					array[k + gap] = temp;//将j位置插到合适的位置
					
				}
				*/
			
		}
	}
}
int main()
{
    int arr[N],i,x;
	x=N;
    printf("请输入 %d 个数据:\n",x);
    for(i=0;i<N;i++)
    scanf("%d",&arr[i]);    
    shell_sort(arr, N);   
    printf("排序后的顺序是:\n");
    for(i=0;i<N;i++)
    printf("%5d",arr[i]);
    printf("\n");
    return 0;
}

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值