各种基础算法代码集合(基于C语言)

//二叉树代码实现
typedef struct TreeNode{
	int data;
	struct TreeNode *left;
	struct TreeNode *right;
}Node;

struct TreeNode* Create()
{
	int val;
	scanf("%d", &val);

	struct TreeNode* root = (struct TreeNode*)malloc(sizeof(struct TreeNode*));

	if (val <= 0)
		return NULL;

	if (root == NULL)
		printf("malloc TreeNode fail!");

	if (val > 0)
	{
		root->data = val;
		printf("请输入%d的左节点: ", val);
		root->left = Create();
		printf("请输入%d的右节点: ", val);
		root->right = Create();
	}
	return root;
}

void PreTree(struct TreeNode* root)
{
	if (root == NULL)
		return;
	printf("%d   ", root->data);
	PreTree(root->left);
	PreTree(root->right);
}

void InTree(struct TreeNode* root)
{
	if (root == NULL)
		return;
	InTree(root->left);
	printf("%d   ", root->data);
	InTree(root->right);
}


void BackTree(struct TreeNode* root)
{
	if (root == NULL)
		return;
	BackTree(root->left);
	BackTree(root->right);
	printf("%d   ", root->data);
}
//基于冒泡排序算法改进的
//鸡尾酒排序
void ch_sort(int array[], int length)
{
	int temp = 0;
	int count = 0;
	for (int i = 0; i < length / 2; i++)
	{
		bool isSorted = true;
		//奇数轮
		for (int j = i; j < length - i - 1; j++)
		{
			if (array[j] > array[j + 1])
			{
				temp = array[j];
				array[j] = array[j + 1];
				array[j + 1] = temp;

				isSorted = false;
			}
		}
		count++;
		if (isSorted)
			break;

		//偶数轮
		isSorted = true;
		for (int j = length - i - 1; j > i; j--)
		{
			if (array[j] < array[j - 1])
			{
				temp = array[j];
				array[j] = array[j - 1];
				array[j - 1] = temp;

				isSorted = false;
			}
		}
		count++;
		if (isSorted)
			break;
	}
	printf("走了%d次!", count);
}
//双边循环的快速排序法
int partition(int arr[], int startID, int endID)
{
	int pivot = arr[startID];
	int left = startID;
	int right = endID;

	while (left != right)
	{
		while (left < right && arr[right] > pivot)
			right--;
		while (right > left && arr[left] <= pivot)
			left++;
		//交换left和right
		if (left < right)
		{
			int temp = arr[left];
			arr[left] = arr[right];
			arr[right] = temp;
		}
	}

	arr[startID] = arr[left];
	arr[left] = pivot;

	return left;
}
//单边循环快速排序法
int partition_Oneside(int arr[], int startID, int endID)
{
	int pivot = arr[startID];
	int mark = startID;

	for (int i = startID + 1; i <= endID; i++)
	{
		if (arr[i] < pivot)
		{
			mark++;
			int p = arr[mark];
			arr[mark] = arr[i];
			arr[i] = p;
		}
	}
	arr[startID] = arr[mark];
	arr[mark] = pivot;
	return mark;
}
void quickSort(int array[], int length, int startID, int endID)
{
	if (startID >= endID)
		return;

	//int pivotID = partition(array, startID, endID);
	int pivotID = partition_Oneside(array, startID, endID);
	
	quickSort(array, length, startID, pivotID - 1);
	quickSort(array, length, pivotID + 1, endID);
}
void upAdjust(int arr[], int len)
{
	int childIndex = len - 1;
	int parentIndex = (childIndex - 1) / 2;
	int temp = arr[childIndex];
	while (childIndex > 0 && temp < arr[parentIndex])
	{
		arr[childIndex] = arr[parentIndex];
		childIndex = parentIndex;
		parentIndex = (parentIndex - 1) / 2;
	}
	arr[parentIndex] = temp;
}

//堆排序算法
void downAdjust(int arr[], int index, int len)
{
	int temp = arr[index];
	int childIndex = 2 * index + 1;
	while (childIndex < len)
	{
		if (childIndex + 1 < len && arr[childIndex + 1] > arr[childIndex])
			childIndex++;
		if (temp >= arr[childIndex])
			break;
		arr[index] = arr[childIndex]; 
		index = childIndex;
		childIndex = 2 * childIndex + 1;
	}
	arr[index] = temp;
}
void heapSort(int array[], int length)
{
	//1.排序成最大二叉堆
	//从最后一个非叶子节点开始
	for (int i = (length - 2) / 2; i >= 0; i--)
	{
		downAdjust(array, i, length);
	}
	for (int i = 0; i < length; i++)
		printf("%d\t", array[i]);
	//2.循环删除堆顶元素,移到尾部
	for (int i = length - 1; i > 0; i--)
	{
		int temp = array[i];
		array[i] = array[0];
		array[0] = temp;
		downAdjust(array, 0, i);
	}
}

//计数排序,类似于map,创建一个map,将数据解析并填入,最后直接按顺序读取

//桶排序也类似于计数排序

 

//判断链表是否有环,解题思路追及问题,时间复杂度O(n)空间复杂度O(1)
typedef struct Node2{
	int data;
	struct Node2 *next;
};
bool iscycle(Node2 *head)
{
	Node2 *p1 = head;
	Node2 *p2 = head;
	while (p2 != NULL && p2->next != NULL)
	{
		p1 = p1->next;
		p2 = p2->next->next;
		if (p1 == p2)
			return true;
	}
	return false;
}
//计算环的长度
int cycleLen(Node2 *head)
{
	Node2 *p1 = head;
	Node2 *p2 = head;
	int frist_meet = 0;
	int len = 0;
	while (p2 != NULL && p2->next != NULL)
	{
		p1 = p1->next;
		p2 = p2->next->next;
		if (p1 == p2)
		{
			frist_meet = 1;
			break;
		}
	}
	while (frist_meet == 1)
	{
		len = len + 1;
		p1 = p1->next;
		p2 = p2->next->next;
		if (p1 == p2)
			break;
	}
	return len;
}
//计算入环点
struct Node2* cyclePoint(Node2 *head)
{
	Node2 *p1 = head;
	Node2 *p2 = head;
	int frist_meet = 0;
	while (p2 != NULL && p2->next != NULL)
	{
		p1 = p1->next;
		p2 = p2->next->next;
		if (p1 == p2)
		{
			frist_meet = 1;
			break;
		}
	}
	p2 = head;
	while (frist_meet == 1)
	{
		p1 = p1->next;
		p2 = p2->next;
		if (p1 == p2)
			break;
	}
	return p2;
}

void cycle()
{
	struct Node2* node1 = (struct Node2*)malloc(sizeof(struct Node2*));
	struct Node2* node2 = (struct Node2*)malloc(sizeof(struct Node2*));
	struct Node2* node3 = (struct Node2*)malloc(sizeof(struct Node2*));
	struct Node2* node4 = (struct Node2*)malloc(sizeof(struct Node2*));
	struct Node2* node5 = (struct Node2*)malloc(sizeof(struct Node2*));
	struct Node2* node6 = (struct Node2*)malloc(sizeof(struct Node2*));
	struct Node2* node7 = (struct Node2*)malloc(sizeof(struct Node2*));
	node1->data = 5;
	node1->next = node2;
	node2->data = 3;
	node2->next = node3;
	node3->data = 7;
	node3->next = node4;
	node4->data = 2;
	node4->next = node5;
	node5->data = 6;
	node5->next = node6;
	node6->data = 8;
	node6->next = node7;
	node7->data = 1;
	node7->next = node4;

	bool isCycle = iscycle(node1);
	printf("%d\n", isCycle);

	int Len = cycleLen(node1);
	printf("cycle length = %d\n", Len);

	Node2 *point = cyclePoint(node1);

}
//栈操作
#define maxsize 10

typedef struct Stack
{
	int data[maxsize];
	int topIdx;
};
int push(Stack &stack, int element)
{
	if (stack.topIdx == maxsize - 1)
		return 0;

	stack.data[stack.topIdx++] = element;

	return 1;
}
int pop(Stack &stack)
{
	if (stack.topIdx == 0)
		return 0;

	int val = stack.data[--stack.topIdx];
	return val;
}
int isEmpty(Stack stack)
{
	if (stack.topIdx == 0)
		return 1;
	return 0;
}
int isFull(Stack stack)
{
	if (stack.topIdx == maxsize - 1)
		return 1;
	return 0;
}

void stack_test()
{
	Stack stack1;
	stack1.topIdx = 0;
	push(stack1, 4);
	push(stack1, 9);
	push(stack1, 7);
	push(stack1, 3);
	push(stack1, 8);
	push(stack1, 5);
}
//栈操作获取最小值操作
//时间复杂度O(1)最坏情况空间复杂度O(n)
#define maxsize 10

typedef struct Stack
{
	int data[maxsize];
	int topIdx;
};
int isEmpty(Stack stack)
{
	if (stack.topIdx == 0)
		return 1;
	return 0;
}
int isFull(Stack stack)
{
	if (stack.topIdx == maxsize - 1)
		return 1;
	return 0;
}
int push(Stack &stack, Stack &minstack, int element)
{
	if (stack.topIdx == maxsize - 1)
		return 0;

	stack.data[stack.topIdx++] = element;

	if (isEmpty(minstack) || element <= minstack.data[minstack.topIdx - 1])
	{
		minstack.data[minstack.topIdx++] = element;
	}

	return 1;
}
int pop(Stack &stack, Stack &minstack)
{
	if (stack.topIdx == 0)
		return 0;

	int val = stack.data[--stack.topIdx];
	if (val == minstack.data[minstack.topIdx - 1])
		minstack.data[--minstack.topIdx];
	return val;
}
int getmin(Stack minstack)
{
	if (minstack.topIdx == 0)
		return 0;
	int min = minstack.data[minstack.topIdx - 1];

	return min;
}
void stack_test()
{
	Stack stack1, minstack1;
	stack1.topIdx = 0;
	minstack1.topIdx = 0;
	push(stack1, minstack1, 4);
	push(stack1, minstack1, 9);
	push(stack1, minstack1, 7);
	push(stack1, minstack1, 3);
	push(stack1, minstack1, 8);
	push(stack1, minstack1, 5);

	pop(stack1, minstack1);
	pop(stack1, minstack1);
	//pop(stack1, minstack1);

	int min = getmin(minstack1);
	printf("%d\n", min);
}
//最大公约数
//辗转相除法,更相减损法
//这里用的是更相减损法+移位运算
int gcd(int a, int b)
{
	if (a == b)
		return a;
	if (a > b)
	{
		if (a % b == 0)
			return b;
	}
	else
	{
		if (b % a == 0)
			return a;
	}

	if ((a & 1) == 0 && (b & 1) == 0)
	{
		return gcd(a >> 1, b >> 1) << 1;
	}
	else if ((a & 1) == 0 && (b & 1) != 0)
		return gcd(a >> 1, b);
	else if ((a & 1) != 0 && (b & 1) == 0)
		return gcd(a, b >> 1);
	else
	{
		int max = a > b ? a : b;
		int min = a < b ? a : b;
		return gcd(max - min, min);
	}
}
//是否为2的整数次幂
bool isPowerof2(int num)
{
	return (num & (num - 1)) == 0;
}
//贪心算法
char *remove(char *num, int len, int k)
{
	int ret_len = len - k;
	if (ret_len == 0)
		return 0;
	char *temp = (char *)malloc(len * sizeof(char *));
	char *ret = (char *)malloc((ret_len + 1) * sizeof(char *));

	temp[0] = num[0];

	int pose = 0;
	for (int i = 1; i < len; i++)
	{
		if (k > 0)
		{
			//printf("%c\t", temp[pose]);
			if (num[i] < temp[pose])
			{
				temp[pose] = num[i];
				k--;
			}
			else
			{
				pose++;
				temp[pose] = num[i];
			}
		}
		else
		{
			pose++;
			temp[pose] = num[i];
		}
	}	
	if (k != 0)
	{
		pose = 0;
		for (int i = k; i < ret_len + k; i++)
		{
			ret[pose++] = temp[i];
		}
		ret[pose] = '\0';
		return ret;
	}
	else
	{
		pose++;
		temp[pose] = '\0';
		return temp;
	}
}

贪心算法更多的是考虑局部最优解,而动态规划则更多的考虑全局最优解!

动态规划的要点:确定全局最优解和最优子结构之间的关系,以及问题的边界。用数学公式来表达就是状态转移方程式!

int Ret[100][100] = { {0} };
int num[100] = { 0 };
//递归方法,存在很多的重叠计算情况
int getBestvalue2(int people, int p[], int g[], int g_len)
{
	if (people == 0 || g_len == 0)
		return 0;
	if (people < p[g_len - 1])
		return getBestvalue2(people, p, g, g_len - 1);
	return Max(getBestvalue2(people, p, g, g_len - 1), getBestvalue2(people - p[g_len - 1], p, g, g_len - 1) + g[g_len - 1]);
}
//优化一,通过一行一行去填表格,找到最高收益,避免了重复的计算
int getBestvalue(int people, int p[], int g[], int g_len)
{
	for (int i = 1; i <= g_len; i++)
	{
		for (int j = 1; j <= people; j++)
		{
			if (j >= p[i - 1])
			{
				Ret[i][j] = Max(Ret[i - 1][j], Ret[i - 1][j - p[i - 1]] + g[i - 1]);
			}
			else
				Ret[i][j] = Ret[i - 1][j];
		}
	}
	return Ret[g_len][people];
}
//最终优化的结果,只需要记录第一行的值,即十个人,一种收益模式;其余的都可以根据这一行的数据得到
int getBestvalue3(int people, int p[], int g[], int g_len)
{
	for (int i = 1; i <= g_len; i++)
	{
		for (int j = people; j >= 1; j--)
		{
			if (j >= p[i - 1])
			{
				num[j] = Max(num[j], num[j - p[i - 1]] + g[i - 1]);
				printf("%d\t", num[j]);
			}
		}
		printf("\n");
	}
	return num[people];
}
void getBesttest()
{
	int w = 10;
	int p[5] = { 5, 5, 3, 4, 3 };		//所需员工
	int g[5] = { 400, 500, 200, 300, 350 }; //收益
	//int ret = getBestvalue(w, p, g, 5);
	//int ret = getBestvalue2(w, p, g, 5);
	int ret = getBestvalue3(w, p, g, 5);
	printf("%d\n", ret);
}
//异或运算+分治法解决两个数字奇数次出现的问题
int *findlost(int arr[], int len)
{
	int temp = 0;
	int *ret = (int *)malloc(3 * sizeof(int *));
	int a = 0, b = 0;
	for (int i = 0; i < len; i++)
	{
		temp ^= arr[i];
	}
	if (temp == 0)
		return NULL;
	int flag = 1;
	while (0 == (temp & flag))
		flag <<= 1;
	for (int i = 0; i < len; i++)
	{
		if (0 == (arr[i] & flag))
			a ^= arr[i];
		else
			b ^= arr[i];
	}
	ret[0] = a; ret[1] = b;
	printf("%d,%d\n", ret[0], ret[1]);
	return ret;
}

LRU(least recently used)算法(内存管理算法),移除最近最少使用的,可以搭配双向链表或者哈希链表来实现功能!

第1章 多项式计算 1.1 一维多项式求值 1.2 一维多项式多组求值 1.3 二维多项式求值 1.4 复系数多项式求值 1.5 多项式相乘 1.6 复系数多项式相乘 1.7 多项式相除 1.8 复系数多项式相除 1.9 实系数多项式类 1.10 复系数多项式类 第2章 复数运算 2.1 复数乘法 2.2 复数除法 2.3 复数乘幂 2.4 复数的n次方根 2.5 复数指数 2.6 复数对数 2.7 复数正弦 2.8 复数余弦 2.9 复数类 第3章 随机数的产生 3.1 产生0-1之间均匀分布的一个随机数 3.2 产生0-1之间均匀分布的随机数序列 3.3 产生任意区间内均匀分布的一个随机整数 3.4 产生任意区间内均匀分布的随机整数序列 3.5 产生任意均值与方差的正态分布的一个随机数 3.6 产生任意均值与方差的正态分布的随机数序列 第4章 矩阵运算 4.1 实矩阵相乘 4.2 复矩阵相乘 4.3 一般实矩阵求逆 4.4 一般复矩阵求逆 4.5 对称正定矩阵的求逆 4.6 托伯利兹矩阵求逆的特兰持方法 4.7 求一般行列式的值 4.8 求矩阵的秩 4.9 对称正定矩阵的乔里斯基分解与行列式求值 4.10 矩阵的三角分解 4.11 一般实矩阵的QR分解 4.12 一般实矩阵的奇异值分解 4.13 求广义逆的奇异值分解法 第5章 矩阵特征值与特征向量的计算 5.1 约化对称矩阵为对称三对角阵的豪斯荷尔德变换法 5.2 求对称三对角阵的全部特征值与特征向量 5.3 约化一般实矩阵为赫申伯格矩阵的初等相似变换法 5.4 求赫申伯格矩阵全部特征值的QR方法 5.5 求实对称矩阵特征值与特征向量的雅可比法 5.6 求实对称矩阵特征值与特征向量的雅可比过关法 第6章 线性代数方程组的求解 6.1 求解实系数方程组的全选主元高斯消去法 6.2 求解实系数方程组的全选主元高斯-约当消去法 6.3 求解复系数方程组的全选主元高斯消去法 6.4 求解复系数方程组的全选主元高斯-约当消去法 6.5 求解三对角线方程组的追赶法 6.6 求解一般带型方程组 6.7 求解对称方程组的分解法 6.8 求解对称正定方程组的平方根法 6.9 求解托伯利兹方程组的列文逊方法 6.10 高斯-赛德尔迭代法 6.11 求解对称正定方程组的共轭梯度法 6.12 求解线性最小二乘问题的豪斯荷尔德变换法 6.13 求解线性最小二乘问题的广义逆法 6.14 求解病态方程组 第7章 非线性方程与方程组的求解 7.1 求非线性方程实根的对分法 7.2 求非线性方程一个实根的牛顿法 7.3 求非线性方程一个实根的埃特金迭代法 7.4 求非线性方程一个实根的试位法 7.5 求非线性方程一个实根的连分式法 7.6 求实系数代数方程全部根的QR方法 7.7 求实系数代数方程全部根的牛顿下山法 7.8 求复系数代数方程全部根的牛顿下山法 …… 第8章 插值与逼近 第9章 数值积分 第10章 常微分方程组的求解 第11章 数据处理 第12章 极值问题的求解 第13章 数学变换与滤波 第14章 特殊函数的计算 第15章 排序 第16章 查找 参考文献 作者介绍
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值