栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

刷题笔记。

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

刷题笔记。

前言

以前在学校只专注于研究感兴趣的技术,开发一些乱七八糟的项目,几乎没刷过题,现在面试笔试被各种毒打。现在开始亡羊补牢。只记录算法或思路,不记录题目,不间断更新,顺便重拾C++


文章目录
  • 前言
    • @[TOC](文章目录)
  • 排序算法
    • 冒泡排序
    • 选择排序
    • 插入排序
    • 希尔排序
    • 归并排序
    • 快速排序
  • 一些题型解题思路
    • 统计素数(或者叫质数)个数
    • 数组中3数最大乘积
    • 判断链表是否有环
排序算法 冒泡排序
void BubbleSort(int arr[], int len)
{
	for (int i = 0; i < len; i++) {
		//因为第len - i后面的元素是已经排好了,所以每次只需要遍历 0 到 len - 1 - i 个元素
		for (int j = 0; j < len - 1 - i; j++) {
			//若当前元素大于下一个元素,则交换
			if (arr[j] > arr[j + 1]) {
				int temp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = temp;
			}
		}
	}
}
选择排序
void SelectSort(int arr[], int len) 
{
	for (int i = 0; i < len; i++) {

		int minIndex = i;

		//从元素下一个开始往后找最小的
		for (int j = i + 1; j < len; j++) {
			if (arr[minIndex] > arr[j]) {
				minIndex = j;
			}
		}

		//将当前下标的元素与最小元素交换
		int temp = arr[i];
		arr[i] = arr[minIndex];
		arr[minIndex] = temp;
	}
}
插入排序
void InsertSort(int arr[], int len) 
{
	//第一个不用排,从1开始
	for (int i = 1; i < len; i++) {

		int cur = arr[i];//先拿出要进行插入的元素
		int insertIndex = 0;//下面循环中如果一直找不到可以插的位置,直到循环结束,说明目前它最小,就插到第一个元素的位置

		//往前找有没有还可以插入的地方,同时把排好的元素向后移动
		for (int j = i - 1; j >= 0; j--) {
			if (cur < arr[j]) {
				arr[j + 1] = arr[j];//当前选择的元素比排好的小,排好的元素后移
			} else {
				insertIndex = j + 1;//插入位置为当前与cur比较的元素的前面
				break;
			}
		}

		arr[insertIndex] = cur;
	}
}
希尔排序
//希尔排序 使数据逐渐变得有序,最后在比较有序的数据里进行插入排序,减少插入排序时移动元素的次数
void ShellSort(int arr[],int len)
{
	int gap = len / 2;
	while (gap > 0)
	{
		//外面一层循环次数为数组的组数,里面一层为每组的元素个数
		for (int i = gap; i < len; i++) {

			int cur = arr[i];//先拿出要进行插入的元素
			int insertIndex = i - gap;//下面循环中如果一直找不到可以插的位置,直到循环结束,说明目前它最小,就插到第一个元素的位置

			//往前找有没有还可以插入的地方,同时把排好的元素向后移动,
			//不过希尔排序需要跨步,把一个数组看成若干个交错在一起的数组,gap就是跨的距离,直到gap = 1,就变成普通插入排序
			for (int j = i - gap; j >= 0; j -= gap) {
				if (cur < arr[j]) {
					arr[j + gap] = arr[j];//当前选择的元素比排好的小,排好的元素后移
				} else {
					insertIndex = j + gap;//插入位置为当前与cur比较的元素的前面
					break;
				}
			}

			arr[insertIndex] = cur;
		}
		gap /= 2;
	}
}
归并排序
//将数组start到mid 和 mid+1到end进行合并
void MergeArr(int arr[], int start, int mid, int end, int temArr[])
{
	int i = start, j = mid + 1, k = 0;

	//比较长度相同部分
	while (i <= mid && j <= end) {
		if (arr[i] < arr[j])
			temArr[k++] = arr[i++];
		else
			temArr[k++] = arr[j++];
	}

	//i超出部分
	while (i <= mid) {
		temArr[k++] = arr[i++];
	}

	//j超出部分
	while (j <= end) {
		temArr[k++] = arr[j++];
	}

	for (int i = 0; i < k; i++)
		arr[start + i] = temArr[i];
}

void RecursionMergeSort(int arr[], int start, int end, int temArr[])
{
	if (start >= end) return;//结束递归的条件

	//排序两边的数组
	int mid = (start + end) / 2;
	RecursionMergeSort(arr, start, mid, temArr);
	RecursionMergeSort(arr, mid + 1, end, temArr);

	//将排好的数组合并
	MergeArr(arr, start, mid, end, temArr);
}

//归并排序
void MergeSort(int arr[],int len)
{
	int* temArr = (int*)malloc(len * sizeof(int));
	RecursionMergeSort(arr, 0, len - 1, temArr);
}
快速排序
void Swap(int arr[], int i, int j) {
	int temp = arr[i];
	arr[i] = arr[j];
	arr[j] = temp;
}

//快速排序 前后指针法
void QuckSort(int arr[], int start, int end)
{
	if (start >= end) return; //递归结束条件

	//取第一个元素为基准
	int key = arr[start];
	int prev = start;
	int latter = prev + 1;

	while (latter <= end) {
		//若后面的值比key小,交换到前面去,不要交换第一个位置,交换完成后latter后移
		if (arr[latter] < key) {
			Swap(arr, ++prev, latter);
		}
		latter++;
	}

	//当latter越界后prev所在的位置就是数列中比key小的最后那个数,交换它们
	Swap(arr, start, prev);

	//继续排序左右两边 prev所指的key不用继续排列了
	QuckSort(arr, start, prev - 1);
	QuckSort(arr, prev + 1, end);
}

一些题型解题思路 统计素数(或者叫质数)个数
//暴力方式

bool isPrimer(int n)
{
	//i * i <= n不能是i * i < n,如果n能被i整除也不是素数,例如9,如果仅仅是小于号就判断为素数了
	for (int i = 2; i * i <= n; i++) {
		if (n % i == 0) return false;
	}
	return true;
}

int PrimerCount(int n)
{
	if (n < 2) return 0;
	if (n == 2) return 1;
	int count = 1;//2算一个
	for (int i = 3; i <= n; i+=2) {
		if (isPrimer(i)) count++;
	}
	return count;
}

//埃筛法

int PrimerCountAS(int n)
{
	if (n < 2) return 0;

	int count = 0;
	bool *isPrimer = new bool[n + 1];
	memset(isPrimer, true, n * sizeof(bool));

	for (int i = 2; i <= n; i++) {
		if (isPrimer[i]) {
			count++;
			//查找i的倍数并标记不是素数
			for (int j = i + i; j <= n; j += i) {
				isPrimer[j] = false;
			}
		}
	}

	delete[] isPrimer;
	return count;
}
数组中3数最大乘积
同符号直接取最大前3个数相乘,有正有负则保证结果为正的前提下,取绝对值最大的3个
判断链表是否有环
双指针算法,慢指针每次位移一个位置,快指针比慢指针快一步,每次位移两个位置。
如果进入到环,因为指针比较快会迟早从后面追上慢指针。
当快指针==慢指针,代表有环,但快指针为null或它的下一个为null,则遍历结束,没有环。

另一个方法:
每次遍历到一个节点的时候,给它标上一个下标,当发现下一个节点被标记过,则有环
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1002267.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号