数据结构(一)——绪论

一、数据结构概论

1.抽象数据类型(Abstract Data Type )

(1)数据类型:

  • 数据对象集
  • 数据集合相关联的操作集

(2)抽象:描述数据类型的方法不依赖于具体实现

  • 与存放数据的机器无关
  • 与数据存储的物理结构无关
  • 与实现操作的算法和编程语言均无关

(3)即:只描述数据对象集和相关操作集 只描述数据对象集和相关操作集“ 是什么”,并不涉及 ,并不涉及“ 如何做到”的问题。

2.复杂度的渐进表示法

 

二、几个小算法

1.计算多项式的值(秦九韶算法)

变形之后:

#include<cstdio>
double f(int n, double a[], double x) {
	double p = a[n];
	for (int i = n; i > 0; i--)
		p = a[i - 1] + x * p;
	return p;
}

2.clock() 函数用法示例:

(1)原理:捕捉从程序开始运行到clock()被调用时所耗费的时间。这个时间单位是被调用时所耗费的时间。这个时间单位是clock tick ,即“ 时钟打点”。常数CLK_TCK( 或CLOCKS_PER_SEC)
(2)一个应用:计算函数平均运行时间。让被测函数 重复运行充分多次,使得测出的总的时钟打点间隔充分长,最后计算被测函数充分多次,使得测出的总的时钟打点间隔充分长,最后计算被测函数平均每次运行的时间即可。

#include<cstdio>
#include<ctime>
using namespace std;
clock_t start, stop;
double duration;
void MyFunction(){}
int main() {
	start = clock();
	MyFunction();
	stop = clock();
	duration = ((double)(stop - start)) / CLK_TCK;
	return 0;
}

 3.最大子列和问题:

(1)描述:给定K个整数组成的序列{ N_1, N_2, ... N_K},“连续子列”被定义为{ N​i​​, N​i+1​​, ..., N​j​​ },其中 1≤i≤j≤K。“最大子列和”则被定义为所有连续子列元素的和中最大者。

法一:暴力枚举(时间复杂度为O(n ^ 2))

#include<cstdio>
int MaxSubseqSum(int A[], int N) {
	int ThisSum, MaxSum = 0;
	int i, j;
	for (int i = 0; i < N; i++) {
		ThisSum = 0;
		for (int j = i; j < N; j++) {
			ThisSum += A[j];
			if (ThisSum > MaxSum)  MaxSum = ThisSum;
		}
	}
	return MaxSum;
}

法二:分治法(时间复杂度O(n * log n))

#include<cstdio>
#include<algorithm>
using namespace std;
int DivideAndConquer(int List[], int left, int right) {
	int MaxLeftSum, MaxRightSum;  /* 存放左右子问题的解 */
	int MaxLeftBorderSum = 0, MaxRightBorderSum = 0;  /*存放跨分界线的结果*/
	int LeftBorderSum = 0, RightBorderSum = 0;
	if (right - left <= 1) {
		if (List[left] > 0) return List[left];
		else return 0;
	}
	int center = (left + right) / 2;
	MaxLeftSum = DivideAndConquer(List, left, center);
	MaxRightSum = DivideAndConquer(List, center, right);
	for (int i = center; i >= left; i--) {
		LeftBorderSum += List[i];
		MaxLeftBorderSum = max(MaxLeftBorderSum, LeftBorderSum);
	}
	for (int i = center + 1; i < right; i++) {
		RightBorderSum += List[i];
		MaxRightBorderSum = max(MaxRightBorderSum, RightBorderSum);
	}
	return max(max(MaxLeftSum, MaxRightSum), MaxLeftBorderSum + MaxRightBorderSum);

}

法三:在线处理(时间复杂度为O(n))

因为读入数据时间复杂度是线性的,因此认为复杂度是线性的已经可以了。

#include<cstdio>
int MaxSubseqSum(int A[], int N) {
	int ThisSum = 0, MaxSum = 0;
	int i;
	for (int i = 0; i < N; i++) {
		ThisSum += A[i];
		if (ThisSum > MaxSum)  MaxSum = ThisSum;
		else if (ThisSum < 0)  ThisSum = 0;
	}
	return MaxSum;
}

4.计算组合数

(1)递归算法

#include<cstdio>
int combinat(int m, int n) {
	if (n == 0 || m == n) return 1;
	return combinat(m - 1, n) + combinat(m - 1, n - 1);
}

(2)动态规划

#include<cstdio>
const int maxSize = 100;
int combinate(int m, int n) {
	int C[maxSize][maxSize];
	if (n == 0 || m == n) return 1;
	for (int i = 1; i <= m; i++) C[i][0] = C[i][i] = 1;
	for (int i = 1; i <= m; i++) {
		for (int j = 1; j < i; j++) {  
		//你会发现i = 1时并不会进入第二重循环,因此也不会算C[0][1]的值
			C[i][j] = C[i - 1][j] + C[i - 1][j - 1];
		}
	}
	return C[m][n];
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值