数据结构与算法导论(C++)连载(九)--排序算法

本文代码实现了六种较为基础的排序算法(冒泡、插入、希尔、堆、归并、快速)。

一、最小堆的建立(堆排序中要用到)

在MinHeap.h中:

#include"iostream"

using namespace std;
#define ElenmentType int

typedef struct HeapStruct *MinHeap;
struct HeapStruct {
	ElenmentType * Elements;   //存储堆元素
	int Size;                 //堆当前的元素个数
	int Capactiy;             //堆的最大容量
};

MinHeap CreateMinHeap(int MaxSize, int MinData);
void Insert(MinHeap H, ElenmentType item);
ElenmentType DeleteMin(MinHeap H);
int IsFull(MinHeap H);
int IsEmpty(MinHeap H);
void BuildMinHeap(MinHeap H, ElenmentType A[], int N);

在MinHeap.cpp中:

#include"MinHeap.h"

MinHeap CreateMinHeap(int MaxSize, int MinData)
{
	MinHeap H;
	H = (MinHeap)malloc(sizeof(struct HeapStruct));
	H->Elements = (int *)malloc((MaxSize + 1) * sizeof(ElenmentType));
	H->Size = 1;
	H->Capactiy = MaxSize;
	H->Elements[1]  = MinData;
	return H;
}

void Insert(MinHeap H, ElenmentType item)
{ /* 将元素item 插入最小H, 其中H->Elements[0]已经定义为哨兵 */
	int i;
	if (IsFull(H)) {
		cout << "error\n";
		return;
	}
	i = ++H->Size; /* i指向插入后堆中的最后一个元素的位置 */
	for (; H->Elements[i / 2] > item; i /= 2)
		H->Elements[i] = H->Elements[i / 2]; /* 向下过滤结点 */
	H->Elements[i] = item; /* 将item 插入 */
}


ElenmentType DeleteMin(MinHeap H)
{ /* 从最大堆H中取出键值为最大的元素, 并删除一个结点 */
	int Parent, Child;
	ElenmentType MinItem, temp;
	if (IsEmpty(H)) {
		cout << "error\n";
		return -1;
	}
	MinItem = H->Elements[1]; /* 取出根结点最小值 */
							  /* 用最小堆中最后一个元素从根结点开始向上过滤下层结点 */
	temp = H->Elements[H->Size--];
	for (Parent = 1; Parent * 2 <= H->Size; Parent = Child) {
		Child = Parent * 2;
		if ((Child != H->Size) &&
			(H->Elements[Child] > H->Elements[Child + 1]))
			Child++; /* Child指向左右子结点的较大者 */
		if (temp <= H->Elements[Child]) break;
		else /* 移动temp元素到下一层 */
			H->Elements[Parent] = H->Elements[Child];
	}
	H->Elements[Parent] = temp;
	return MinItem;
}

int IsFull(MinHeap H)
{
	if (H->Size >= H->Capactiy)
		return 1;
	else
		return 0;
}

int IsEmpty(MinHeap H)
{
	if (H->Size == 0)
		return 1;
	else
		return 0;
}

void BuildMinHeap(MinHeap H,ElenmentType A[],int N)
{
	int i;
	for (i = 1; i < N; i++)
		Insert(H, A[i]);
}

可参考本连载中最大堆的实现:https://blog.youkuaiyun.com/qq_28821995/article/details/89601543

二、排序算法的实现

在SortFunction.h中:

#include"iostream"

using namespace std;

#define ElenmentType int

void Swap(ElenmentType *A, ElenmentType *B);
void Bubble_sort(ElenmentType A[], int N);
void Insertion_Sort(ElenmentType A[], int N);
void Shell_Sort(ElenmentType A[], int N);
void Heap_Sort(ElenmentType A[], int N);
void Merge(ElenmentType A[], ElenmentType TmpA[], int L, int R, int RightEnd);
void MSort(ElenmentType A[], ElenmentType TmpA[],
	int L, int RightEnd);
void Merge_sort(ElenmentType A[], int N);
ElenmentType Median3(ElenmentType A[], int Left, int Right);
void QuickSort(ElenmentType A[], int Left, int Right);
void Quick_Sort(ElenmentType A[], int N);

在SortFunction.cpp中:

#include"SortFunction.h"
#include"MinHeap.h"


void Swap(ElenmentType *A, ElenmentType *B)
{
	ElenmentType C;
	C = *A;
	*A = *B;
	*B = C;
}

void Bubble_sort(ElenmentType A[], int N)
{
	int P, flag = 0,i;
	for (P = N - 1; P >= 0; P--) {   
		for (i = 0; i < P; i++) {   //每一次循环把0-P中最大的数移到A[P-1]
			if (A[i] > A[i + 1]) {
				Swap(&A[i], &A[i + 1]);
				flag = 1;      //发生了交换
			}
		}
		if (flag == 0) break;  //如果没有发生交换,则跳出去
	}
}

void Insertion_Sort(ElenmentType A[], int N)
{
	int P, i;
	ElenmentType Tmp;
	for (P = 1; P < N; P++) {
		Tmp = A[P];  //摸下一张牌
		for (i = P; i > 0 && A[i - 1] > Tmp; i--)
			A[i] = A[i - 1]; //大于该数的都往后移
		A[i] = Tmp;
	}
}

void Shell_Sort(ElenmentType A[], int N)
{
	int D, P, i;
	ElenmentType Tmp;
	for (D = N / 2; D > 0; D /= 2) {  // 希尔增量序列
		for (P = D; P < N; P++) {  //插入排序
			Tmp = A[P];
			for (i = P; i >= D && A[i - D] > Tmp; i -= D)
				A[i] = A[i - D];
			A[i] = Tmp;
		}
	}
}

void Heap_Sort(ElenmentType A[], int N)
{
	MinHeap H = NULL;
	int i;
	H = CreateMinHeap(100, A[0]);
	BuildMinHeap(H, A, N);
	for (i = 0; i < N; i++)
		A[i] = DeleteMin(H);
}

void Merge(ElenmentType A[], ElenmentType TmpA[], int L, int R, int RightEnd)
{
	int LeftEnd, NumElements,Tmp,i;
	LeftEnd = R - 1; //左边终点位置,假设左右两列挨着
	Tmp = L;  // 存放结果的数组的初始位置
	NumElements = RightEnd - L + 1;
	while (L<=LeftEnd && R<=RightEnd)
	{
		if (A[L] <= A[R]) TmpA[Tmp++] = A[L++];
		else TmpA[Tmp++] = A[R++];
	}
	while (L <= LeftEnd)
		TmpA[Tmp++] = A[L++];
	while (R <= RightEnd)
		TmpA[Tmp++] = A[R++];
	for (i = 0; i < NumElements; i++, RightEnd--)
		A[RightEnd] = TmpA[RightEnd];
}

void MSort(ElenmentType A[], ElenmentType TmpA[],
	int L, int RightEnd)
{
	int Center;
	if (L < RightEnd) {
		Center = (L + RightEnd) / 2;
		MSort(A, TmpA, L, Center);
		MSort(A, TmpA, Center + 1, RightEnd);
		Merge(A, TmpA, L, Center + 1, RightEnd);
	}
}
//统一函数接口
void Merge_sort(ElenmentType A[], int N)
{
	ElenmentType *TmpA;
	TmpA = (ElenmentType *)malloc(N * sizeof(ElenmentType));
	if (TmpA != NULL) {
		MSort(A, TmpA, 0, N - 1);
		free(TmpA);
	}
	else cout << "error";
}

ElenmentType Median3(ElenmentType A[], int Left, int Right)
{
	int Center;
	Center = (Left + Right) / 2;
	//保证三个数按大小排序
	if (A[Left] > A[Center])
		Swap(&A[Left], &A[Center]);
	if (A[Left] > A[Right])
		Swap(&A[Left], &A[Right]);
	if (A[Center] > A[Right])
		Swap(&A[Center], &A[Right]);
	Swap(&A[Center], &A[Right - 1]); // 将中位数藏到右边 只需要考虑A[Left+1]到A[Right-2]
	return A[Right - 1];  //返回中位数
}

void QuickSort(ElenmentType A[], int Left, int Right)
{
	int Cutoff=10,i,j;  //选用快速排序的阈值
	ElenmentType Pivot;
	if (Cutoff <= Right - Left) {
		Pivot = Median3(A, Left, Right);
		i = Left+1; j = Right - 1;
		while(1){
			while ((A[i] <= Pivot)&&(i<j)) { i++; }
			while ((A[j] >= Pivot)&&(i<j)) { j--; }
			if (i < j)
				Swap(&A[i], &A[j]);
			else break;
		}
		Swap(&A[i], &A[Right - 1]);
		QuickSort(A, Left, i - 1);
		QuickSort(A, i + 1, Right);
	}
	else
		Insertion_Sort(A, Right - Left + 1);
}

//统一接口
void Quick_Sort(ElenmentType A[], int N)
{
	QuickSort(A, 0, N - 1);
}

在main.cpp中:

#include"SortFunction.h"
#include"MinHeap.h"

int main()
{
	ElenmentType A_Bubble_sort[6] = { 5,4,6,7,1,8 };
	Bubble_sort(A_Bubble_sort, 6);
	cout << "Bubble_sort:";
	for (size_t i = 0; i < 6; i++)
		cout << A_Bubble_sort[i] << " ";

	cout << "\n";
	ElenmentType A_Insertion_Sort[6] = { 5,4,6,7,1,8 };
	Insertion_Sort(A_Insertion_Sort, 6);
	cout << "Insertion_Sort:";
	for (size_t i = 0; i < 6; i++)
		cout << A_Insertion_Sort[i] << " ";

	cout << "\n";
	ElenmentType A_Shell_Sort[6] = { 5,4,6,7,1,8 };
	Shell_Sort(A_Shell_Sort, 6);
	cout << "Shell_Sort:";
	for (size_t i = 0; i < 6; i++)
		cout << A_Shell_Sort[i] << " ";

	cout << "\n";
	ElenmentType A_Heap_Sort[6] = { 5,4,6,7,1,8 };
	Heap_Sort(A_Heap_Sort, 6);
	cout << "Heap_Sort:";
	for (size_t i = 0; i < 6; i++)
		cout << A_Heap_Sort[i] << " ";

	cout << "\n";
	ElenmentType A_Merge_sort[6] = { 5,4,6,7,1,8 };
	Merge_sort(A_Merge_sort, 6);
	cout << "Merge_sort:";
	for (size_t i = 0; i < 6; i++)
		cout << A_Merge_sort[i] << " ";

	cout << "\n";
	ElenmentType A_Quick_Sort[6] = { 5,4,6,7,1,8 };
	Quick_Sort(A_Quick_Sort, 6);
	cout << "Quick_Sort:";
	for (size_t i = 0; i < 6; i++)
		cout << A_Quick_Sort[i] << " ";
	
	cout << "\n";
	system("pause");
	return 0;
}

运行结果:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值