选择排序

//SelectionSort.h

#ifndef _SELECTIONSORT_H_
#define _SELECTIONSORT_H_

#include <stdlib.h>
#include <stdio.h>
#include <time.h>

#define SIZE	15

typedef int Element;
typedef Element ListType[SIZE];

void CreateRandom(ListType List, int n);
void print(ListType List, int n);

//简单选择排序
void SimpleSort(ListType List, int n);

//堆排序
void HeapSort(ListType List, int n);

#endif //_SELECTIONSORT_H_

//SelectionSort.c

#include "SelectionSort.h"

void CreateRandom(ListType List, int n)
{
	int i = 0;
	srand((unsigned)time(NULL));

	for(i = 0; i < n; ++i)
	{
		List[i] = rand() % 0x7F;
	}
}

void print(ListType List, int n)
{
	int i = 0;
	for(i = 0; i < n; ++i)
	{
		printf("%d\t", List[i]);
	}
	printf("\n");
}

static void Swap(Element *a, Element *b)
{
	Element Temp = *b;
	*b = *a;
	*a = Temp;
}

/*********************************************************
首先选定一个位置作为最小元素的下标位置,从此位置以外寻找比此位置
存在更小元素的位置,一趟下来最小的元素的位置就位于了数组的最左端,
第二趟下来,第二小的就在了数组的左端第二个位置.............
全部n-1趟下来排序完成
*********************************************************/
void SimpleSort(ListType List, int n)
{
	int i = 0, j = 0, MiniPos = 0;
	for(i = 0; i < n-1; ++i)
	{
		MiniPos = i;							//选定i为最小值
		for(j = i+1; j < n; ++j)				//寻找最小元素所在的位置
		{
			if (List[MiniPos] > List[j])
			{
				MiniPos = j;
			}
		}
		if( i != MiniPos )						//找到了更小元素所在位置
			Swap(&List[i], &List[MiniPos]);		
	}
}


/***************************************************************
堆排序是利用堆的特点:堆顶元素一定是极值(极大值或是极小值)的特点,
每次取堆顶元素,然后再将剩下的元素再一次组成一个堆,再次取堆顶元
素,如此循环直到堆顶无元素则排序完成。

堆的定义:将堆看作一颗完全二叉树,并且用一个一位数组存储这个完全
二叉树,则有完全二叉树上任意一个非叶子节点的值均不大于(或不小于)
其左、右孩子的值

大项堆:完全二叉树上任意一个非叶子节点的值不小于其左、右孩子的值
小项堆:完全二叉树上任意一个非叶子节点的值不大于其左、右孩子的值

升序排序:使用大项堆(因为每次取得的极值是数组中最末一个元素,且
		 最末元素是由堆顶的极值交换而来)
降序排序:使用小项堆

***************************************************************/

static void Adjust(ListType List, int pos, int n)					//调整为大项堆
{
	int Child = 0, Parent = 0;										
	Element Temp = List[pos];										//保存待调整节点值,以备交换
	Parent = pos;
	Child = 2 * Parent + 1;											//使Child指向Parent的左孩子 
	 												

	while (Child < n)												//存在左孩子则循环向下调整,值大的节点向上移动,值小的节点下沉,以满足堆定义
	{
		if( Child + 1 < n && List[Child + 1] > List[Child] )		//存在右孩子且右孩子的值更大
			Child++;												//使Child指向右孩子
	
		if( Temp >= List[Child] )									//父节点已经大于存在的孩子节点(注意不能是List[Parent] > List[Child],除非使用的是方式是直接交换父子节点)
			break;

		//能到此处说明父节点必然小于存在的孩子节点 
		List[Parent] = List[Child];									//用孩子节点替换父节点,使这个非叶子节点不小于其存在的孩子
		Parent = Child;												//继续向下调整
		Child = 2 * Parent + 1;
	}
	List[Parent] = Temp;											//在叶子节点上恢复
}

void HeapSort(ListType List, int n)
{
	int pos = 0, i = 0;
	Element Temp;

	if( n <= 1 )													
		return ;
	
	pos = (n - 1) / 2;												//从最后一个非叶子节点开始向上调整
	while (pos >= 0)												//创建堆
	{
		Adjust(List, pos, n);
		pos--;
	}

	for(i = 0; i < n; ++i)											//循环取堆顶元素到数组无序部分末位置,以对数组进行排序	
	{
		Temp = List[0];												//保存堆顶元素
		List[0] = List[n - i -1];									//使用当前次的末尾元素覆盖堆顶元素
		List[n - i - 1] = Temp;										//将堆顶元素放在末尾
		Adjust(List, 0, n - i - 1);									//使用剩下的元素再次组成堆
	}
}
main.c

#include "SelectionSort.h"

int main(int argc, char **argv)
{
	ListType List ={ 0 };
	int n = sizeof(List) / sizeof(Element);

	CreateRandom(List, n);
	printf("排序前\n");
	print(List, n);

	//SimpleSort(List, n);
	HeapSort(List, n);

	printf("排序后\n");
	print(List, n);

	system("pause");
	return 0;
}







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值