数据结构与算法-排序算法

插入排序: 直接插入排序、折半插入排序、希尔排序
交换排序: 冒泡排序、快速排序
选择排序: 简单选择排序、树形选择排序、堆排序
归并排序: 2- 路归并排序
分配排序: 基数排序(借助 多关键字排序思想

插入排序

直接插入排序:

从第2个记录开始,逐个将每个元素插入到元素前面的有序子序列中去。

//使用vector容器写法

#include<iostream>
#include<vector>
using namespace std;
#define max_size 10000

vector<int> insertion(vector<int>& arr) {
	vector<int> result;
	result.push_back(arr[arr.size() - 1]);
	arr.pop_back();

	while (!arr.empty()) {
		int temp = arr[arr.size() - 1];
		arr.pop_back();
		for (int i = 0; i <= result.size(); i++) {
			if (i == result.size()) {
				result.push_back(temp);
				break;
			}
			if (temp < result[i]) {
				result.insert(result.begin() + i, temp);
				break;
			}
		}
	}
	return result;
}

//直接插入排序
int main() {
	srand(time(0));

	vector<int> arr(max_size);
	for (int i = 0; i < max_size; i++) { arr[i] = rand() % 100; }

	arr = insertion(arr);

	for (auto entry : arr) {
		cout << entry << ' ';
	}
	cout << endl;
}
//使用数组的写法

#include<iostream>
#include<vector>
using namespace std;
#define max_size 100

void insertion(int* arr,int size) {
	for (int i = 1; i < size; i++) {
		int temp = arr[i];
		int j = i - 1;
		while (j >= 0&& arr[j] > temp) {
			arr[j + 1] = arr[j];
			j--;
		}
		arr[j + 1] = temp;
	}
}


void Print(int* arr, int size) {
	for (int i = 0; i < size; i++) {
		cout << arr[i] << ' ';
	}
	cout << endl;
}

//直接插入排序
int main() {
	srand(time(0));

	int* arr = new int[max_size];
	for (int i = 0; i < max_size; i++) { arr[i] = rand() % 100; }
	Print(arr, max_size);
	insertion(arr,max_size);
	Print(arr, max_size);

	
}
希尔排序(缩小增量排序)
D.L Shell 即分析插入排序在什么条件下排序效率是高的 :
  (1) 记录本身是基本有序的。
(2 )记录数目相对较少。

希尔排序(Shell Sort)是插入排序的一种更高效的改进版本。希尔排序是非稳定排序算法。该方法因DL. Shell于1959年提出而得名。希尔排序是把记录按不同的步长分组,对每组使用直接插入排序算法排序,随着步长逐渐缩小,整个序列将逐渐变为有序。

希尔排序的基本思想是将待排序序列分割成若干子序列分别进行直接插入排序,具体步骤如下:

  1. 选择一个步长 gap,可以是序列长度的一半或者其他方式确定。
  2. 将序列分割成间隔为 gap 的子序列。
  3. 对每个子序列应用直接插入排序。
  4. 减小步长 gap(通常减半),重复步骤2和3,直到 gap 为1,此时整个序列几乎已经有序,再对整个序列进行一次直接插入排序。
#include<iostream>
#include<vector>
using namespace std;
#define max_size 10


void Print(int* arr, int size) {
	for (int i = 0; i < size; i++) {
		cout << arr[i] << ' ';
	}
	cout << endl;
}



//希尔排序
void shellSort(int* arr, int size) {
	for (int gap = size / 2; gap >= 1; gap /= 2) {

		for (int i = gap; i < size; i+=gap) {
			int temp = arr[i];
			int j = i - gap;
			while (j >= 0 && arr[j] > temp) {
				arr[j + gap] = arr[j];
				j-=gap;
			}
			arr[j + gap] = temp;
		}

		Print(arr, max_size);

	}
}

//插入排序
void insertion(int* arr,int size) {
	for (int i = 1; i < size; i++) {
		int temp = arr[i];
		int j = i - 1;
		while (j >= 0&& arr[j] > temp) {
			arr[j + 1] = arr[j];
			j--;
		}
		arr[j + 1] = temp;
	}
}




int main() {
	srand(time(0));

	int* arr = new int[max_size];
	int* brr = new int[max_size];
	for (int i = 0; i < max_size; i++) { arr[i] = rand() % 100; }
	for (int i = 0; i < max_size; i++) { brr[i] = arr[i]; }
	Print(arr, max_size);
	Print(brr, max_size);
	cout << endl;
	shellSort(arr,max_size);
	insertion(brr, max_size);
	cout << endl;
	Print(arr, max_size);
	Print(brr, max_size);

	
}

交换排序

冒泡排序算法(起泡排序,Bubble sort)
1. 将第一个元素与第二个元素比较,若逆序则交换;然后比较第二个元素与第三个元素;依此类推,直至第n-1个元素和第n个元素比较为止—— 第一趟冒泡排序,最大的元素被安置在最后一个位置
2. 对前n-1个记录进行 第二趟冒泡排序,结果使次大的元素被安置在第n-1个位置
3. 重复上述过程, 直到 “在一趟排序过程中没有进行过交换记录的操作” 为止
#include<iostream>
#include<vector>
using namespace std;
#define max_size 10


void Print(int* arr, int size) {
	for (int i = 0; i < size; i++) {
		cout << arr[i] << ' ';
	}
	cout << endl;
}



//冒泡排序

void bubbleSort(int* arr, int size) {
	for (int i = size; i > 1; i--) {

		bool check = false;
		for (int j = 0; j < i-1; j++) {
			if (arr[j] > arr[j+1]) {
				int temp = arr[j];
				arr[j] = arr[j+1];
				arr[j+1] = temp;

				check = true;
			}
		}
		if (check == false) { break; }

	}
}


//希尔排序
void shellSort(int* arr, int size) {
	for (int gap = size / 2; gap >= 1; gap /= 2) {

		for (int i = gap; i < size; i+=gap) {
			int temp = arr[i];
			int j = i - gap;
			while (j >= 0 && arr[j] > temp) {
				arr[j + gap] = arr[j];
				j-=gap;
			}
			arr[j + gap] = temp;
		}

		//Print(arr, max_size);

	}
}

//插入排序
void insertion(int* arr,int size) {
	for (int i = 1; i < size; i++) {
		int temp = arr[i];
		int j = i - 1;
		while (j >= 0&& arr[j] > temp) {
			arr[j + 1] = arr[j];
			j--;
		}
		arr[j + 1] = temp;
	}
}




int main() {
	srand(time(0));

	int* arr = new int[max_size];
	int* brr = new int[max_size];
	int* crr = new int[max_size];
	for (int i = 0; i < max_size; i++) { arr[i] = rand() % 100; }
	for (int i = 0; i < max_size; i++) { brr[i] = arr[i]; }
	for (int i = 0; i < max_size; i++) { crr[i] = arr[i]; }
	Print(arr, max_size);
	//Print(brr, max_size);
	//Print(crr, max_size);
	cout << endl;
	shellSort(arr,max_size);
	insertion(brr, max_size);
	bubbleSort(crr, max_size);
	cout << endl;
	Print(arr, max_size);
	Print(brr, max_size);
	Print(crr, max_size);

	
}
快速排序算法
算法思想:
快速排序将所给元素划分成两部分,其中一部分的元
素比另一部分的元素小,然后再分别对这两部分元素
递归用该方法排序,以达到整个序列有序。
#include<iostream>
#include<vector>
using namespace std;
#define max_size 10


void Print(int* arr, int size) {
	for (int i = 0; i < size; i++) {
		cout << arr[i] << ' ';
	}
	cout << endl;
}


int partition(int* arr, int left, int right) {
	int index = left;
	int value = arr[index];
	while (left != right) {
		if (index == left) {
			//动右边
			if (arr[right] < value) {
				arr[left] = arr[right];
				left++;
				index = right;
			}
			else {
				//不做处理
				right--;
			}
		}
		else if (index == right) {
			//动左边
			if (arr[left] > value) {
				arr[right] = arr[left];
				right--;
				index = left;
			}
			else {
				//不做处理
				left++;
			}
		}
	}
	arr[left] = value;

	return left;
}

//快速排序
//递归实现
void quickSort(int* arr, int left, int right) {
	if (left < right) {
		int index = partition(arr, left, right);

		quickSort(arr, left, index - 1);
		quickSort(arr, index + 1, right);
	}
}

//冒泡排序

void bubbleSort(int* arr, int size) {
	for (int i = size; i > 1; i--) {

		bool check = false;
		for (int j = 0; j < i-1; j++) {
			if (arr[j] > arr[j+1]) {
				int temp = arr[j];
				arr[j] = arr[j+1];
				arr[j+1] = temp;

				check = true;
			}
		}
		if (check == false) { break; }

	}
}

//希尔排序
void shellSort(int* arr, int size) {
	for (int gap = size / 2; gap >= 1; gap /= 2) {

		for (int i = gap; i < size; i+=gap) {
			int temp = arr[i];
			int j = i - gap;
			while (j >= 0 && arr[j] > temp) {
				arr[j + gap] = arr[j];
				j-=gap;
			}
			arr[j + gap] = temp;
		}

		//Print(arr, max_size);

	}
}

//插入排序
void insertion(int* arr,int size) {
	for (int i = 1; i < size; i++) {
		int temp = arr[i];
		int j = i - 1;
		while (j >= 0&& arr[j] > temp) {
			arr[j + 1] = arr[j];
			j--;
		}
		arr[j + 1] = temp;
	}
}



int main() {
	srand(time(0));

	int* arr = new int[max_size];
	//int arr [5] = {3,1,5,2,4};
	int* brr = new int[max_size];
	int* crr = new int[max_size];
	int* drr = new int[max_size];
	for (int i = 0; i < max_size; i++) { arr[i] = rand() % 100; }
	for (int i = 0; i < max_size; i++) { brr[i] = arr[i]; }
	for (int i = 0; i < max_size; i++) { crr[i] = arr[i]; }
	for (int i = 0; i < max_size; i++) { drr[i] = arr[i]; }
	Print(arr, max_size);
	//Print(brr, max_size);
	//Print(crr, max_size);
	cout << endl;
	shellSort(arr,max_size);
	insertion(brr, max_size);
	bubbleSort(crr, max_size);
	quickSort(drr, 0,max_size-1);
	cout << endl;
	Print(arr, max_size);
	Print(brr, max_size);
	Print(crr, max_size);
	Print(drr, max_size);

	
}

选择排序

简单选择排序
简单选择排序: 每趟从待排序元素中选出最小元素,
放在已排好序的子表的最后,直到全部元素排序完毕。
void SelectSort(int* arr, int size) {
	int min_index;

	for (int i = 0; i < size; i++) {
		min_index = i;
		for (int j = i + 1; j < size; j++) {
			if (arr[j] < arr[min_index]) {
				min_index = j;
			}
		}
		//选择最小值
		if (i != min_index) {
			int temp = arr[min_index];
			arr[min_index] = arr[i];
			arr[i] = temp;
		}
	}
}
堆排序
堆的定义
堆的定义: 堆是一棵满足以下条件的二叉树:
是一棵删掉最右边的一些叶结点的完全二叉树;
堆中每个结点存放一个数据元素;
每个结点中的元素 不小于 其孩子中的元素 (大顶堆)
每个结点中的元素不大于其孩子中的元素(小顶堆)。
数据结构: 用数组 (SqList &H) 来存放一个堆
//堆排序
void adjustBig(int* arr, int n ,int i) {
	int largest = i;
	if (i * 2 + 1 < n && arr[i * 2 + 1] > arr[largest]) {
		largest = i * 2 + 1;
	}
	if (i * 2 + 2 < n && arr[i * 2 + 2] > arr[largest]) {
		largest = i * 2 + 2;
	}
	if (largest != i) {
		swap(arr[i], arr[largest]);
		adjustBig(arr, n, largest);
	}
}

void heapSort(int* arr, int size) {
	for (int i = size / 2 - 1; i >= 0; i--) {
		adjustBig(arr, size  , i);
	}
	for (int i = size-1; i >= 0; i--) {
		swap(arr[0], arr[i]);
		adjustBig(arr, i, 0);
	}
}

归并排序

归并排序(Merge Sort)是一种高效的排序算法,采用分治法(Divide and Conquer)的一个典型应用。它将数组递归地分成两半分别排序,然后将结果归并(合并)起来,以此实现整个数组的排序。归并排序在所有情况下都能保证 O(n log n) 的时间复杂度,是一种稳定的排序算法。

归并排序的基本步骤如下:

  1. 分解:将当前序列从中间分成前后两部分。
  2. 递归排序:递归地对前后两部分分别进行归并排序。
  3. 合并:将两个排序好的部分合并成最终的排序序列
#include<iostream>
#include<vector>
using namespace std;
#define max_size 100


void Print(int* arr, int size) {
	for (int i = 0; i < size; i++) {
		cout << arr[i] << ' ';
	}
	cout << endl;
}


//归并排序

void Merge(int* arr, int low, int mid, int high) {
	int* brr = new int[high - low + 1];
	int x = 0, i = low, j = mid + 1;
	while (i<=mid&&j<=high) {
		if (arr[i] < arr[j]) {
			brr[x] = arr[i++];
		}
		else {
			brr[x] = arr[j++];
		}

		x++;
	}
	while (i <= mid) {
		brr[x] = arr[i++];
		x++;
	}
	while (j <= high) {
		brr[x] = arr[j++];
		x++;
	}
	for (int k = 0; k <= high - low; k++) {
		arr[k + low] = brr[k];
	}
	delete[] brr;
}

void MergeSort(int* arr, int low, int high) {
	if (low < high) {

		int mid = (low + high) / 2;
		MergeSort(arr, low, mid);
		MergeSort(arr, mid + 1, high);

		Merge(arr, low, mid, high);
	}
}

void GuiBinSort(int* arr, int size) {
	MergeSort(arr, 0, size - 1);
}





//堆排序
void adjustBig(int* arr, int n ,int i) {
	int largest = i;
	if (i * 2 + 1 < n && arr[i * 2 + 1] > arr[largest]) {
		largest = i * 2 + 1;
	}
	if (i * 2 + 2 < n && arr[i * 2 + 2] > arr[largest]) {
		largest = i * 2 + 2;
	}
	if (largest != i) {
		swap(arr[i], arr[largest]);
		adjustBig(arr, n, largest);
	}
}

void heapSort(int* arr, int size) {
	for (int i = size / 2 - 1; i >= 0; i--) {
		adjustBig(arr, size  , i);
	}
	for (int i = size-1; i >= 0; i--) {
		swap(arr[0], arr[i]);
		adjustBig(arr, i, 0);
	}
}


//简单选择排序  -- 比较次数固定
void SelectSort(int* arr, int size) {
	int min_index;

	for (int i = 0; i < size; i++) {
		min_index = i;
		for (int j = i + 1; j < size; j++) {
			if (arr[j] < arr[min_index]) {
				min_index = j;
			}
		}
		//选择最小值
		if (i != min_index) {
			int temp = arr[min_index];
			arr[min_index] = arr[i];
			arr[i] = temp;
		}
	}
}




int partition(int* arr, int left, int right) {
	int index = left;
	int value = arr[index];
	while (left != right) {
		if (index == left) {
			//动右边
			if (arr[right] < value) {
				arr[left] = arr[right];
				left++;
				index = right;
			}
			else {
				//不做处理
				right--;
			}
		}
		else if (index == right) {
			//动左边
			if (arr[left] > value) {
				arr[right] = arr[left];
				right--;
				index = left;
			}
			else {
				//不做处理
				left++;
			}
		}
	}
	arr[left] = value;

	return left;
}

//快速排序
//递归实现
void quickSort(int* arr, int left, int right) {
	if (left < right) {
		int index = partition(arr, left, right);

		quickSort(arr, left, index - 1);
		quickSort(arr, index + 1, right);
	}
}





//冒泡排序

void bubbleSort(int* arr, int size) {
	for (int i = size; i > 1; i--) {

		bool check = false;
		for (int j = 0; j < i-1; j++) {
			if (arr[j] > arr[j+1]) {
				int temp = arr[j];
				arr[j] = arr[j+1];
				arr[j+1] = temp;

				check = true;
			}
		}
		if (check == false) { break; }

	}
}


//希尔排序
void shellSort(int* arr, int size) {
	for (int gap = size / 2; gap >= 1; gap /= 2) {

		for (int i = gap; i < size; i+=gap) {
			int temp = arr[i];
			int j = i - gap;
			while (j >= 0 && arr[j] > temp) {
				arr[j + gap] = arr[j];
				j-=gap;
			}
			arr[j + gap] = temp;
		}

		//Print(arr, max_size);

	}
}

//插入排序
void insertion(int* arr,int size) {
	for (int i = 1; i < size; i++) {
		int temp = arr[i];
		int j = i - 1;
		while (j >= 0&& arr[j] > temp) {
			arr[j + 1] = arr[j];
			j--;
		}
		arr[j + 1] = temp;
	}
}




int main() {
	srand(time(0));

	int* arr = new int[max_size];
	//int arr [5] = {3,1,5,2,4};
	int* brr = new int[max_size];
	int* crr = new int[max_size];
	int* drr = new int[max_size];
	int* err = new int[max_size];
	int* frr = new int[max_size];
	int* grr = new int[max_size];
	for (int i = 0; i < max_size; i++) { arr[i] = rand() % 100; }
	for (int i = 0; i < max_size; i++) { brr[i] = arr[i]; }
	for (int i = 0; i < max_size; i++) { crr[i] = arr[i]; }
	for (int i = 0; i < max_size; i++) { drr[i] = arr[i]; }
	for (int i = 0; i < max_size; i++) { err[i] = arr[i]; }
	for (int i = 0; i < max_size; i++) { frr[i] = arr[i]; }
	for (int i = 0; i < max_size; i++) { grr[i] = arr[i]; }
	Print(arr, max_size);
	//Print(brr, max_size);
	//Print(crr, max_size);
	cout << endl;
	shellSort(arr,max_size);
	insertion(brr, max_size);
	bubbleSort(crr, max_size);
	quickSort(drr, 0,max_size-1);
	SelectSort(err, max_size);
	heapSort(frr, max_size);
	GuiBinSort(grr, max_size);
	cout << endl;
	Print(arr, max_size);
	Print(brr, max_size);
	Print(crr, max_size);
	Print(drr, max_size);
	Print(err, max_size);
	Print(frr, max_size);
	Print(grr, max_size);

	
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值