排序算法类(待完善)

 不多说废话了,直接贴上代码,个人把常用的排序算法写成了一个类,方便随时调用,部分内容待后续补充

//main.cpp

#include "sort.h"
int main() {

	Sort sort_class;
	int test_array[10] = { 10,5,5,9,3,55,6,3,1,0 };
	sort_class.len = sizeof(test_array) / sizeof(test_array[0]);
	// sort_class.bubbleSort(test_array);
	//sort_class.half_insertSort(test_array);
	sort_class.shellSort(test_array);
	sort_class.print(test_array);

	return 0;
}
#pragma once
//sort.h

#define _CRT_SECURE_NO_WARNINGS

#include <iostream>
#include <math.h>
using namespace std;
#define ElemType int
class Sort {
public:
	int len;
	// 交换排序
	void bubbleSort(ElemType *array);

	int partition(ElemType *array, int low, int high); //划分函数是快排的关键
	void quickSort(ElemType *array, int low, int high); // 实际执行的是这个
	void quickSort(ElemType *array);	//调用这个即可,为了统一各个排序函数的调用方式

	// 选择排序
	void selectSort(ElemType *array);
	void heapSort(ElemType *array);

	// 插入排序
	void insertSort(ElemType *array);
	void half_insertSort(ElemType *array); //折半插排
	void shellSort(ElemType *array);

	void swap(ElemType *array, int i, int j);
	void print(ElemType *array);
};
//sort.cpp

#include "sort.h"

void Sort::swap(ElemType *array, int i, int j) {
	auto temp = array[i];
	array[i] = array[j];
	array[j] = temp;
}

void Sort::bubbleSort(ElemType *array) {

	printf("bubbleSort:\n");
	for (int i = 0; i < len; i++) {
		bool flag = false;
		for (int j = i + 1; j < len; j++) {
			if (array[i] > array[j]) {
				swap(array, i, j);
				flag = true;  // 如果本轮遍历发生交换,则则设置flag
			}
		}
		if (flag == false) {
			return; //说明剩下的都是有序了,相比无flag比较次数少点
		}
	}
}

int Sort::partition(ElemType *array, int low, int high) {
	auto pivot = array[low]; // 将当前表中第一个元素作为枢轴元素,占用O(1)的空间 这时候low已经备份,可以覆蓋
	while (low < high) {
		while (low < high && array[high] >= pivot)
			--high; //比枢轴大的元素放在右边不动
		array[low] = array[high]; // 碰到比枢轴小的,移到左边  这时候high已经备份,可以覆蓋
		while (low < high && array[low] >= pivot)
			++low; //比枢轴小的元素放在左边不动
		array[high] = array[low]; // 碰到比枢轴大的,移到右边  这时候新的low已经备份,可以覆蓋
	}
	array[low] = pivot;		// 枢轴元素存放到最终的位置 将第一个备份的放回去
	return low;		//返回枢轴元素的位置
}
void Sort::quickSort(ElemType *array, int low, int high) {
	int pivotPos = 0;
	while (low < high) {
		pivotPos = partition(array, low, high);
		quickSort(array, low, pivotPos); // 对左边部分递归快排
		quickSort(array, pivotPos, high); //对又变部分递归快排
	}
}
void Sort::quickSort(ElemType *array) {
	/*
	快排是对冒泡排序的一种改进。
	基本思想:基于分治法
	*/
	printf("quickSort:\n");
	int low = 0, high = len - 1;
	quickSort(array, low, high);
}

void Sort::selectSort(ElemType *array) {
	/* 简单选择排序
	基本思想:每一趟(如第i趟)在后面n-i+1(i=1,2...,n-1)个待排序元素中选取关键字最小的元素,作为有序子序列的第i个元素。
	选择排序的时间复杂度为:O(n^2),空间复杂度:O(1)
	选择排序是不稳定的;
	*/
	printf("selectSort:\n");
	int min_pos; //记录最小元素的位置
	for (int now_start = 0; now_start < len - 1; now_start++) {
		min_pos = now_start; 
		for (int j = now_start+1; j < len; j++) {
			if (array[j] < array[min_pos]) 
				min_pos = j;	//更新最小元素的位置 
		}
		if (min_pos != now_start)
			swap(array, now_start, min_pos);	// 将第i小的元素与第i个位置的元素互换
	}
}

void Sort::heapSort(ElemType *array) {
	/*
	堆排序是一种树形选择排序方法
	*/
	printf("heapSort:\n");
}

void Sort::insertSort(ElemType *array) {
	/*
	直接插入排序
	基本思想:每次将一个待排序的记录,按其关键字大小插入到前面已经排好序的子序列中
	感觉像是逐步遍历逆序数
	适用于基本有序的排序表和数据量不大的排序表
	*/
	printf("insertSort:\n");
	int i, j;
	int temp;
	for (i = 1; i < len; i++) {
		if (array[i] < array[i - 1]) {
			temp = array[i];	//哨兵,好多情况下把array[0]作为哨兵,不存放元素,数组总长度为n+1,我这里单独搞了一个temp,考虑到这是一个类,尽量和其他的排序方法参数兼容
			for (j = i - 1; temp < array[j]; j--)
				array[j + 1] = array[j]; //元素后移
			array[j + 1] = temp; // 发现第j个位置的元素已经小于temp,所以把temp放到第j+1个位置
		}
	}

}
void Sort::half_insertSort(ElemType *array) {
	/*
	折半插入排序
	基本思想:与直接插排的区别在于,直接插排是边比较变移动,需要移动多少个就需要比较多少次
	而折半插排是将比较和移动这两个操作进行了分离,先确定插入位置,再移动元素,
	好处在于:折半查找的方式减少了比较的次数
	注:移动操作的次数无论如何是不能被减少的(除非你用链表,就不需要移动了,但是用了链表之后折半查找方式就行不通了)
	*/
	printf("half_insertSort:\n");
	int i, j;
	int temp;
	int low, high, mid;
	for (i = 1; i < len; i++) {
		if (array[i] < array[i - 1]) {
			temp = array[i];	//哨兵,好多情况下把array[0]作为哨兵,不存放元素,数组总长度为n+1,我这里单独搞了一个temp,考虑到这是一个类,尽量和其他的排序方法参数兼容
			low = 0; high = i - 1;
			// 
			while (low <= high) {
				mid = (low + high) / 2;
				if (array[mid] < temp)
					low = mid + 1;
				else high = mid - 1;
			}
			for (j = i - 1; j > high; j--)
				array[j + 1] = array[j]; //元素后移
			array[high + 1] = temp; // 发现第j个位置的元素已经小于temp,所以把temp放到第j+1个位置
		}
	}
}
void Sort::shellSort(ElemType *array) {
	/*
	希尔排序(有称缩小增量排序)
	基本思想:弥补直接插排的缺陷(只适用于基本有序的和数据量不大的),
	步长的理解:并不是按照多少步长进行划分一组,比如dk,dk+1,...,2dk-1是一组
	而是dk,2dk,3dk...这些是一组。注意区别归并排序
	*/
	printf("shellSort:\n");
	int dk;
	int temp;
	int i, j;
	for (dk = len / 2; dk >= 1; dk /= 2) {
		for (i = dk + 1; i < len; i++) {	//在每一个组里面采用的仍旧是插入排序
			if (array[i] < array[i - dk]) {
				temp = array[i];
				for (j = i - dk; j >= 0 && temp < array[j]; j -= dk)
					array[j + dk] = array[j];
				array[j + dk] = temp;
			}
		}
	}
}

void Sort::print(ElemType *array) {
	for (int i = 0; i < len; i++)
		printf("%d ", array[i]);
}

 

    原文作者:算法
    原文地址: https://www.twblogs.net/a/5bddf75e2b717720b51b1f79
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞