随笔——算法笔记(未整理)

以下为一些日常收集算法笔记,由于各种原因没有时间整理,暂且记录如下。

程序设计心得:
如果在进行设计某个函数时,没有思路,可以选择

  • 引入新的变量
  • 引入新的函数
    结合画图板整理思路。

曾经有某位大佬说过:“计算机科学领域的任何问题都可以通过增加一个间接的中间层来解决”,事实上也确实如此。

二分查找

#include <stdio.h>

// 二分查找
int Find(int* arr, int n, int val)
{
	if (NULL == arr || n < 1)return -2;
	int left = 0, right = n - 1;
	int mid = 0;
	int pos = -1;
	while (left <= right)
	{
		//mid = (left + right)/2;
		//mid = (right - left + 1) / 2 + left;
		mid = (right - left + 1) * 0.618 + left;
		if (val < arr[mid])
		{
			right =  mid - 1;
		}
		else  if (val > arr[mid])
		{
			left = mid + 1;
		}
		else
		{
			// 找最左边的数
			while (mid > left&& arr[mid - 1] == val) { --mid; }
			// 找最右边的数
			//while (mid > left&& arr[mid + 1] == val) { ++mid; }
			pos = mid;
			break;
		}
	}
	return pos;
}


// 二分查找,递归版本
int FindVal(int* arr, int left, int right, int val)
{
	int pos = -1;
	int mid = (right - left + 1) / 2 + left;
	if (left < right)
	{
		if (val < arr[mid])
		{
			pos = FindVal(arr, left, mid - 1, val);
		}
		else  if (val > arr[mid])
		{
			pos = FindVal(arr, mid + 1, right, val);
		}
		else
		{
			// 找最左边的数
			while (mid > left&& arr[mid-1] == val) { --mid; }
			// 找最右边的数
			//while (mid > left&& arr[mid + 1] == val) { ++mid; }

			pos = mid;
		}
	}
	return pos;
}

int main()
{
	int arr[] = { 12,12,12,12,13,13,13,13,25,26,47,58,59,69,78,90,100 };
	//int index = FindVal(arr, 0, sizeof(arr) / sizeof(arr[0]), 13);
	int index = Find(arr, sizeof(arr) / sizeof(arr[0]), 13);
	printf("%d", index);
	return 0;
}

递归求斐波拉切数列优化

// 参照此函数的循环优化递归斐波那契数列
int fun(int n)
{
	int a = 1, b = 1, c = 1;
	for(int i=3;i <= n;i++)
	{
		c = a + b;
		b = a;
		a = c;
	}
	return a;
}

// 递归斐波那契数列优化
int fibn(int n, int a, int b)
{
	if (n <= 2)return a;
	else return fibn(n - 1, a + b, a);

}

int fib(int n)
{
	int a = 1, b = 1;
	return fibn(n, a, b);
}

int main()
{
	for (int i = 1; i < 10; i++)
	{

		int n = fun(i);
		int m = fib(i);
		printf("%d %d\n", n, m);
	}
	return 0;
}

完全二叉树

void func(int i, int n)
{
	if (i >= n) return;
	else
	{
		func(i + 1, n);
		func(i + 1, n);
	}
}

其中递归的 i 值可以模拟出一个树形,红线表示递归的实际调用顺序。
在这里插入图片描述
用途:如求一个集合的所有子集 {1,2,3}
在brr[] 中设置三个为分别表示 1,2,3的有和无。比如 brr中 000 表示 arr的1,2,3都不存在,相反 brr 中 111 表示 arr 中 1,2,3都存在,相关代码如下:

void func(int* arr, int* brr, int i, int n)
{
	if (i >= n)
	{
		for (int j = 0; j < n; ++j)
		{
			if (brr[j])
			{
				printf("%d ",arr[j]);
			}
		}
		printf("\n");
	}
	else
	{
		brr[i] = 1;
		func(arr, brr, i + 1, n); //左
		brr[i] = 0;
		func(arr, brr, i + 1, n); //右
	}
}

int main()
{
	int arr[] = { 1,2,3 };
	int brr[] = { 1,1,1 };
	func(arr,brr,0,3);
	return 0;
}

输出:
在这里插入图片描述

斐波那契数列在计算机科学领域乃至数学上和生活中都有着广泛的用途。比如在程序设计中的兔子产子问题,走台阶问题,青蛙跳荷塘问题,在数学上的杨辉三角也可以中斐波那契数列计算,甚至数学上还给出了直接计算某一项值的公式,在日常生活中如向日葵的葵花籽排列问题等。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我叫RT

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值