IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 7种排序算法 -> 正文阅读

[数据结构与算法]7种排序算法

7种排序算法

#pragma once
#include<iostream>
#include<string>
/*#define SWAP1(x,y){x=x^y;y=x^y;x=x^y;}//不能用于同址交换,如SWAP(arr[1],arr[1]);会获得0值!
#define SWAP2(x,y){int temp;temp=x;x=y;y=temp;}//最保险的交换方式
#define SWAP3(x,y){x=x+y;y=x-y;x=x-y;}//可能溢出,x值高出边界*/
using namespace std;
class sort {
public:
	void SWAP1(int &x, int &y) { x = x ^ y; y = x ^ y; x = x ^ y; }//不能用于同址交换,如SWAP(arr[1],arr[1]);会获得0值!
	void SWAP2(int &x, int &y) { int temp; temp = x; x = y; y = temp; }//最保险的交换方式
	void SWAP3(int &x, int &y) { x = x + y; y = x - y; x = x - y; }//可能溢出,x值高出边界

	void SWAP(int &x, int &y) {//int &x,int &y
		if (x != y) {
			SWAP1(x, y);
		}
		else {
			SWAP2(x, y);
		}
	}

	void selectsort(int arr[], int len) {//选择排序
		int i, j;
		int index;
		for (i = 0; i < len; i++) {
			index = i;
			for (j = i + 1; j < len; j++) {
				index = (arr[j] < arr[index]) ? j : index;
			}
			//2,1,4,3,5当i=1,index=1,SWAP(arr[1],arr[1]);同值亦或得0值,导致交换失败
			SWAP(arr[i], arr[index]);
		}
	}

	void bobsort(int arr[], int len) {//冒泡排序
		int i, j;
		for (i = 0; i < len; i++) {
			for (j = 0; j < len - i - 1; j++) {
				if (arr[j] > arr[j + 1]) { SWAP(arr[j], arr[j + 1]); }
			}
		}
	}

	void insertsort1(int arr[], int len) {//直接插入排序
		int i, j;
		for (i = 1; i < len; i++) {
			for (j = i - 1; j >= 0 && arr[j] > arr[j + 1]; j--) {
				SWAP(arr[j], arr[j + 1]);
			}
		}
	}

	void insertsort2(int arr[], int len) {//间接插入排序
		int i, j;
		int tmp;
		for (i = 1; i < len; i++) {
			tmp = arr[i];
			for (j = i - 1; j >= 0 && arr[j] > tmp; j--) {
				arr[j + 1] = arr[j];
			}
			SWAP(arr[j + 1], tmp);
		}
	}

	void hillsort(int arr[], int len) {//希尔排序
		int i, j;
		int tmp, d;
		d = len >> 1;
		while (d > 0) {
			for (i = d; i < len; i++) {
				tmp = arr[i];
				for (j = i - d; j >= 0 && arr[j] > tmp; j -= d) {
					arr[j + d] = arr[j];
				}
				SWAP(arr[j + d], tmp);
			}
			d >>= 1;
		}
	}

	void quicksort(int arr[], int low, int high) {//快速排序
		int t = arr[low];
		int f = low + 1;
		int b = high;
		if (low >= high) return;
		while (f <= b) {
			while (f <= b && arr[f] <= t) f++;
			while (f <= b && arr[b] >= t) b--;
			if (f < b) {
				SWAP(arr[f], arr[b]);
				f++;
				b++;
			}
		}
		arr[low] = arr[b];
		arr[b] = t;
		quicksort(arr, low, b - 1);
		quicksort(arr, b + 1, high);
	}
	//堆排两步法
	void heapify1(int arr[], int len) {//变为大更堆
		int i = 0;
		while (i < len) {
			if ((2 * i + 1) < len && (2 * i + 2) < len) {
				int *lc = &arr[2 * i + 1];
				int *rc = &arr[2 * i + 2];
				int *p = (*lc > *rc) ? lc : rc;
				if (*p > arr[i]) {
					SWAP(*p, arr[i]);
					i = 0;
				}
				else {
					i++;
				}
			}
			else if ((2 * i + 1) < len) {//只有左孩子
				int lc = arr[2 * i + 1];
				if (lc > arr[i]) {
					SWAP(arr[2 * i + 1], arr[i]);
					i = 0;
				}
				else {
					i++;
				}
			}
			else {
				i++;
			}
		}
	}

	void heapsort1(int arr[], int len) {//堆排序1
		while (len > 0) {
			heapify1(arr, len);
			SWAP(arr[0], arr[len - 1]);
			len--;
		}
	}
	
	//堆排三步法:
	void heapify2(int arr[], int index,int heapsize) {
		int lc = index * 2 + 1;//lc表示左孩子
		while (lc < heapsize) {
			int largest = (lc + 1 < heapsize && arr[lc + 1] > arr[lc]) ? lc + 1 : lc;//lc+1表示右孩子;将左右孩子中最大的给largest
			largest = arr[largest] > arr[index] ? largest : index;//父和最大孩子谁大把其下标给largest;
			if (largest == index) {
				break;
			}
			SWAP2(arr[largest], arr[index]);
			index = largest;
			lc = index * 2 + 1;
		}
	}//(优于heap1)

	void heapinsert(int arr[], int index) {//使得index节点与其孩子满足大更堆规范(3个节点间)
		while (arr[index] > arr[(index - 1) / 2]) {
			SWAP2(arr[index], arr[(index - 1) / 2]);
			index = (index - 1) / 2;
		}
	}

	void heapsort2(int arr[], int len) {//堆排序2
		if (arr == NULL || len < 2) {//判断数组规范
			return;
		}
		for (int i = 0; i < len; i++) {//使得index节点与其孩子满足大更堆规范(3个节点间)
			heapinsert(arr, i);
		}
		int heapsize = len;
		SWAP2(arr[0], arr[--heapsize]);//交换大更堆的头尾
		while (heapsize > 0) {
			heapify2(arr, 0, heapsize);//恢复大更堆
			SWAP2(arr[0], arr[--heapsize]);//交换大更堆的头尾
		}
	}

	/*归并排序:
		核心merge算法:从中间将arr分为两半:L—M 和 M+1—R,
		从L开始和M+1开始分别到M和R结束的元素比较,较小的传入临时数组T中,
		最后剩下没有比较的元素直接传入T中,
		最后将T中的元素覆盖arr原来的元素;

		process算法:通过分治递归回溯给左右两半merge提供由小到大的不同mid,以此由小到大的范围执行merge;
		process(arr,L, mid);//先是左半部分递归回溯
		process(arr, mid + 1, R);//再是右半部分递归回溯
		merge(arr, L, mid, R);//第一次回溯中,左右部分各一个,merge得到最小段的有序序列,往后继续回溯。。。

		mergesort算法:确定数组合法且长度合理,随后执行process;
	*/
	void mergesort(int arr[],int len) {
		if (arr == NULL || len < 2) {
			return;
		}
		process(arr,0,len-1);
	}

	void process(int arr[], int L, int R) {
		if (L == R) {
			return;
		}
		int mid = L + ((R - L) >> 2);
		process(arr,L, mid);
		process(arr, mid + 1, R);
		merge(arr, L, mid, R);
	}

	void merge(int arr[], int L, int M, int R) {
		int len = R - L + 1;
		int *T = new int[len];
		int p1 = L;
		int p2 = M + 1;
		int i=0;
		while (p1 <= M && p2 <= R) {
			T[i++] = arr[p1] < arr[p2] ? arr[p1++] : arr[p2++];
		}
		while (p1<=M) {
			T[i++] = arr[p1++];
		}
		while (p2 <= R) {
			T[i++] = arr[p2++];
		}
		for (i = 0; i < len;i++) {
			arr[L+i] = T[i];
		}
	}

	void printArr(int arr[], int len) {//输出数组
		int i;
		for (i = 0; i < len; i++) {
			cout << arr[i] << "\t";
		}
	}
};

测试:

#include<iostream>
#include<fstream>
#include<string>
#include<ctime>//clock()函数
#include"sort.h"
#define MAXSIZE 100
using namespace std;

void Print_runtime() {
	cout << clock() <<"us"<< endl;
}
int main() {
	string str;
	sort S;
	int arr[MAXSIZE];
	int length=5;
	fstream testfile;
	//从test文本中读取数据,初始化数组:
	testfile.open("test.txt", ios::in);
	if (!testfile.is_open()) { cout << "false!" << endl; }
	int i;
	for (i = 0; i < length; i++) {
		testfile >> arr[i];
	}
	S.printArr(arr, length);
	//选择排序方式:
	printf("\nInput sort name:(bob,insert1,insert2,hill,select,quick,heap1,heap2,merge):\n");
	cin >> str;
	if (str.find("bob") != string::npos) {S.bobsort(arr,length); Print_runtime();}//冒泡排序
	else if (str.find("insert1") != string::npos) { S.insertsort1(arr, length); Print_runtime(); }//插入排序1
	else if (str.find("insert2") != string::npos) { S.insertsort2(arr, length); Print_runtime();}//插入排序2
	else if (str.find("hill") != string::npos) { S.hillsort(arr,length); Print_runtime();}//希尔排序
	else if (str.find("select") != string::npos) { S.selectsort(arr, length); Print_runtime();}//选择排序
	else if (str.find("quick") != string::npos) { S.quicksort(arr,0,length-1); Print_runtime();}//快速排序
	else if (str.find("heap1") != string::npos) { S.heapsort1(arr,length - 1); Print_runtime();}//堆排序
	else if (str.find("heap2") != string::npos) { S.heapsort2(arr, length); Print_runtime();}//堆排序
	else if (str.find("merge") != string::npos) { S.mergesort(arr,length); Print_runtime();}//归并排序
	S.printArr(arr, length);
	system("pause");
}
/*要点记录:
1.要使用相对路径时,应将文件放在cpp文件所处的文件夹中。
*/
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-09-18 10:27:04  更:2021-09-18 10:28:05 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/17 13:19:17-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码