几种排序算法的实现

常见排序算法的c语音实现

头文件sort.h

#ifndef SORT_H_
#define SORT_H_

typedef int ElemetType;

//插入排序
void insertSort(ElemetType list[],int n);

//希尔排序
void shellSort(ElemetType list[],int n);

//堆排序
void heapSort(ElemetType list[],int n);
void heap(ElemetType list[],int i,int n);

//归并排序
void mergeSort(int list[],int n);
void merge(int src[],int temp[],int head,int mid,int rear);

//快速排序(三数中值选择法)
void quickSort(ElemetType list[],int n);
void quickSort(ElemetType list[],int start,int end);
ElemetType median(ElemetType list[],int start,int end);

#endif /* SORT_H_ */

具体实现

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

/**
 * 插入排序由N-1趟排序组成。对于P=1趟到P=N-1趟排序,要保证从下标0到下标P已经排好序
 */
void insertSort(ElemetType list[], int n) {
	for (int i = 1, j; i < n; i++) {
		int tmp = list[i]; //可减少赋值操作
		for (j = i; j >= 1 && tmp < list[j - 1]; j--) {
			list[j] = list[j - 1];
		}
		list[j] = tmp; //为第i个值找到合适位置
	}
}

/**
 * 希尔排序通过比较相距一定间隔的元素来工作,各趟比较所用的距离随着算法的进行而减小
 * 直到只比较相邻元素的最后一趟排序
 */
void shellSort(ElemetType list[], int n) {

	//初始距离为数组长度除以2取整
	for (int increase = n / 2; increase > 0; increase = increase / 2) {
		for (int i = increase; i < n; i++) {
			int k, tmp = list[i];
			for (k = i; k >= increase; k -= increase) {
				if (list[k] < list[k - increase]) {
					list[k] = list[k - increase];
				} else {
					break;
				}
			}
			list[k] = tmp;
		}
	}
}

/**
 * 堆排序
 */
void heapSort(ElemetType list[], int n) {
	//先将数组用二叉堆表示
	for (int i = 9 / 2 - 1; i >= 0; i--)
		heap(list, i, 9);
	//将第一个元素(数组最大值)与最后一个交换后,数组长度减1,然后对下标为0的元素进行最大堆排列
	for (int i = n - 1; i >= 0; i--) {
		int tmp = list[i];
		list[i] = list[0];
		list[0] = tmp;
		heap(list, 0, i);
	}
}

//对下标为i的元素进行最大堆排列。当前:i,父亲 :(i-1)/2,左孩子:2*i+1,右孩子:(i+1)*2
void heap(ElemetType list[], int i, int n) {
	int up, left, right, tmp;
	left = 2 * i + 1;
	right = 2 * i + 2;
	if (left < n && right < n)
		up = list[left] > list[right] ? left : right;
	else if (left < n && right >= n)
		up = left;
	else
		return;

	if (list[up] > list[i]) {
		tmp = list[i];
		list[i] = list[up];
		list[up] = tmp;
		heap(list, up, n);
	}
}

/**
 * 归并排序,经典递归算法
 */
void mergeSort(int list[], int n) {
	ElemetType *temp = (ElemetType*) malloc(sizeof(ElemetType) * n);
	for (int i = 0; i < n; i++)
		temp[i] = list[i];
	merge(list, temp, 0, n / 2, n - 1);
	free(temp);
}

//合并
void merge(int src[], int temp[], int head, int mid, int rear) {
	if (mid == head && mid == rear) {
		return;
	} else {
		merge(src, temp, head, (head + mid) / 2, mid);
		merge(src, temp, mid + 1, (rear + mid + 1) / 2, rear);

		int i, m, n;
		for (i = head, m = head, n = mid + 1; m <= mid && n <= rear; i++) {
			if (temp[m] < temp[n]) {
				src[i] = temp[m];
				m++;
			} else {
				src[i] = temp[n];
				n++;
			}
		}
		for (; m <= mid; i++, m++)
			src[i] = temp[m];

		for (; n <= rear; n++, i++)
			src[i] = temp[n];

		for (i = head; i <= rear; i++)
			temp[i] = src[i];

	}
}

/**
 * 快速排序(三数中值选择枢纽值法)
 */
void quickSort(ElemetType list[], int n) {
	quickSort(list, 0, n - 1);
}

void quickSort(ElemetType list[], int start, int end) {
	if (start >= end)
		return;
	ElemetType pivot = median(list, start, end); //枢纽值
	ElemetType temp;
	int i = start, j = end - 1;
	while (true) {
		for (; i < j && list[i] < pivot; i++)
			;
		for (; j > i && list[j] > pivot; j--)
			;

		if (i == j)
			break;
		temp = list[i];
		list[i] = list[j];
		list[j] = temp;
	}

	list[end] = list[i];
	list[i] = pivot;

	quickSort(list, start, i - 1);
	quickSort(list, i + 1, end);
}

//返回start、end、和(start+end)/2位置上的中值
ElemetType median(ElemetType list[], int start, int end) {
	int mid = (start + end) / 2;
	int a, b; //a记录大的,b记录第二大的
	ElemetType temp;
	if (list[start] >= list[mid]) {
		a = start;
		b = mid;
	} else {
		a = mid;
		b = start;
	}

	if (list[end] > list[mid]) {
		b = end;
	}

	if (list[b] > list[a]) {
		b = a;
	}

	temp = list[b];
	list[b] = list[end];
	list[end] = temp;
	return list[end];
}

测试

int main() {
	ElemetType list[] = { 5, 2, 6, 8, 7, 4, 3, 1, 9 };
	//插入排序
	insertSort(list,9);
	//希尔排序
	shellSort(list,9);
	//堆排序
	heapSort(list, 9);
	//归并排序
	mergeSort(list, 9);
	//快速排序
	quickSort(list,9);
	for (int i = 0; i < 9; i++)
		printf("%d ", list[i]);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/jygqm/article/details/80892521