堆排序和归并排序笔记

堆排序

堆排序是对选择排序的改进 时间复杂度是 O(nlogn),大概思路是:

  1. 将待排序的数列构造成大顶堆或者小顶堆 大顶堆就是每个结点的值大于左右孩子的值
  2. 此时,整个数列的最大值就是堆顶的根节点(将其与末尾交换)
  3. 然后将剩余的n-1个序列重新构造成一个堆
  4. 反复进行
    上代码:
/*
 ============================================================================
 Name        : HeapSort.c
 Author      : liuxin
 Version     :
 Copyright   : Your copyright notice
 Description : Hello World in C, Ansi-style
 ============================================================================
 */

#include<stdio.h>

void swap(int a[],int i,int j)
{
	int temp;
	temp = a[i];
	a[i] = a[j];
	a[j] = temp;
}

void HeapAdjust(int a[],int s,int n)
{
	int i,temp;
	temp = a[s];  //temp存放双亲结点
	for(i=2*s;i<=n;i=i*2)    //2*s代表左结点
	{
		if(i<n && a[i]<a[i+1])   //i+1代表右结点
		{
			i++;
		}
		if(temp>a[i])
		{
			break;
		}
		a[s] = a[i];
		s = i;

	}
	a[s] = temp;
}

void HeapSort(int a[],int n)
{
	int i;

	for(i=n/2;i>0;i--)
	{
		HeapAdjust(a,i,n);  //构建大顶堆,其中i是双亲结点,n是总个数
	}


	for(i=1;i<9;i++)              //把第一次构建出来的大顶堆打印出来了
	{
		printf("%d ",a[i]);
	}
	printf("\n");

	for(i=n;i>1;i--)
	{
		swap(a,1,i);    //构建完大顶堆之后,第一个元素是最大的了,把他和最后的互换,然后在重新把剩下的构建大顶堆
		HeapAdjust(a,1,i-1);  //重新从第一个顶点开始构建
	}
}

int main()
{
	int i;
	int a[]={-1,1,3,2,6,5,4,8,7};         //从第一个元素开始排,因为这样正好2*i是左结点,2*i+1是右结点
	HeapSort(a,8);
	for(i=1;i<9;i++)
	{
		printf("%d ",a[i]);
	}
	return 0;
}

归并排序

归并排序(Merge Sort)就是利用归并思想实现的排序算法,他的原理是假设初始序列有n个元素,可以看成有n个有序的子序列,每个子序列的长度是1,然后归并,得到n/2个长度为2或者1的子序列,然后再两辆归并,反复如此,直到得到一个长度为n的有序序列位置。上图:
在这里插入图片描述
递归实现代码:

#include<stdio.h>
#define MAXSIZE 8

void merging(int *list1,int list1_size,int *list2,int list2_size)    //给两个数组排序然后放一起放在list1中
{
	int i,j,k,m;
	i=j=k=0;
	int temp[MAXSIZE];

	while(i < list1_size && j < list2_size)
	{
		if(list1[i]<list2[j])
		{
			temp[k++] = list1[i++];
		}
		else
		{
			temp[k++] = list2[j++];
		}
	}
	while(i < list1_size)
	{
		temp[k++] = list1[i++];
	}
	while(j < list2_size)
	{
		temp[k++] = list2[j++];
	}
	for(m = 0;m < (list1_size+list2_size);m++)    
	{
		list1[m]=temp[m];
	}

}

void MergeSort(int a[],int n)    //递归实现
{
	if(n>1)
	{
		int *list1 = a;
		int list1_size = n/2;
		int *list2 = a+n/2;
		int list2_size = n - list1_size;

		MergeSort(list1,list1_size);
		MergeSort(list2,list2_size);

		merging(list1,list1_size,list2,list2_size);

	}	

}

int main()
{
	int a[]={5,2,9,1,4,7,8,3};
	int i;
	MergeSort(a,8);

	for(i=0;i<8;i++)
	{
		printf("%d ",a[i]);
	}
	return 0;
}

把这两个排序算法放在一起写是因为这两个排序算法无论是在最坏情况,最好情况,平均情况下时间复杂度都是O(nlogn),都是十分好的排序算法,则两个相比而言,归并排序稳定,堆排序不稳定。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值