【排序】内部排序算法实现

1.归并排序

分析:

归并排序使用分治思想,原理是

①将一个无序数列分成两个序列后,对序列进行排序后,再将两个有序序列合并成一个有序序列;

②分开的两个序列又可以进行再分排序然后合并从而形成问题的子问题。

 

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

void merge(int *a, int *ans, int s, int m, int t){
	int ak, bk, ansk;

	ak = s, bk = m+1, ansk = s;
	while(ak<=m&&bk<=t){
		*(ans+ansk++) = (*(a+ak)<*(a+bk))?*(a+ak++):*(a+bk++);
	}
	for(; ak<=m; ak++){
		*(ans+ansk++) = *(a+ak);
	}
	for(; bk<=t; bk++){
		*(ans+ansk++) = *(a+bk);
	}
}

void mergesort(int *a, int n, int low, int high, int *ans){
	int mid;
	int *temp;

	temp = (int*)malloc(sizeof(int)*n);  //save the result of sort

	if(low==high){
		*(ans+low) = *(a+low);
		return;
	}
	mid = (low+high)/2;
	//sort a[low...mid]
	mergesort(a, n, low, mid, temp);
	//sort a[mid+1, high]
	mergesort(a, n, mid+1, high, temp);
	//merge temp[low...mid] temp[mid+1, high] into ans[low...high]
	merge(temp, ans, low, mid, high);
	free(temp);
}

int main(void){
	int data[] = {2,4,8,5,1,6,3,10,9};
	int n = sizeof(data)/sizeof(int);
	int ansk;

	int *ans = (int*)malloc(sizeof(int)*n);
	int *temp = (int*)malloc(sizeof(int)*n);

	mergesort(data, n, 0, n-1, ans);
	for(ansk=0; ansk<n; ansk++){
		printf("%d ", *(ans+ansk));
	}
	printf("\n");

	return 0;
}

2.堆排序

 

分析:

①将无序数列视为一棵完全二叉树的节点,并以层逐个加入树中,树的节点数/2的节点必有孩子;

②堆排序(结果需要从小到大排序)旨在将最大值元素移至树根处,并将其与树最后节点交换即可;

③对于一个结点,需要满足一个条件a[i]>a[2*i]和a[i]>a[2*i+1];

④当一个结点与其孩子交换后,需要对交换的孩子向下调整,保证满足条件③;

所以堆排序的步骤则为:

1)由无序数组视为一棵无安全二叉树的节点,从拥有孩子的节点开始,先对该树进行调整,使其满足条件③,此时形成大顶堆;

2)树根结点与树最后节点交换后,由于已经形成大顶堆,所以第二大的元素必为根结点的孩子,所以只需要进行向下调整即可将最大元素置于根结点位置;假设第二大元素不为根结点孩子,那么必然位于根结点孩子的左或右子树,而由于第三个条件,子树的根结点必为最大,所以必定不满足条件③。

 

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

void swap(int *a, int *b){
	int temp;
	temp = *a;
	*a = *b;
	*b = temp;
}

void heapadjust(int *data, int n, int i){
	//downward adjustment
	int k;
	int max;

	for(k=i+1; k<=n/2; k++){
		//compare root,lchild,rchild
		max = (*(data+k-1)>*(data+2*k-1))?k-1:2*k-1;
		if(2*k<n)
			max = (*(data+max)>*(data+2*k))?max:2*k;
		if(max==k-1)
			continue;
		else{
			swap(data+k-1, data+max);
			heapadjust(data, n, max);
		}
	}
}
void heapsort(int n, int *data){
	int k;

	for(k=0; k<n; k++){
		swap(data, data+n-k-1);
		heapadjust(data, n-k-1, 0);
	}
}

int main(void){
	int data[]={5,4,3,2,1};
	int k;
	int n=sizeof(data)/sizeof(int);
	
	for(k=n/2; k>=0; k--)
		heapadjust(data, n, 0);  //initialize heap
	heapsort(n, data);
	for(k=0; k<n; k++){
		printf("%d ", *(data+k));
	}
	printf("\n");
	return 0;
}

3.快速排序

分析:

①寻找位置s,将无序数列第一个元素放置于as,使得as>aj (t<j<s),as<ai (n>i>s);

②对无序数列at,...,as-1和as+1,...,an重复步骤①即可,知道t=s-1或s+1=n位置。

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

void swap(int *a, int *b){
	int temp;

	temp = *a;
	*a = *b;
	*b = temp;
}

int find_mid(int *d, int low, int high){
	int k;
	
	while(low<high){
		while(*(d+low)<*(d+high)&&low<high)
			high--;
		swap(d+low, d+high);
		while(*(d+low)<*(d+high)&&low<high)
			low++;
		swap(d+low, d+high);
	}
	return low;
}

void quicksort(int *d, int low, int high){
	int mid;

	if(low<high){
		mid = find_mid(d, low, high);
		quicksort(d, low, mid-1);
		quicksort(d, mid+1, high);
	}
}

int main(void){
	int data[] = {5,9,7,8,2,4,6,3,1};
	int n = sizeof(data)/sizeof(int);
	int k;

	quicksort(data, 0, n-1);
	for(k=0; k<n; k++)
		printf("%d ", *(data+k));
	printf("\n");
	return 0;
}




 

转载于:https://www.cnblogs.com/xhyzjiji/p/6159359.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值