数据结构(复习)

前言:课程及学习原因

        笔者现阶段已经大三寒假阶段,准备参加2025年考研。本人目标不算远大,计划考本校(本校也只是一个平平无奇的双非一本)。因此,笔者计划写人生第一个博客,用于记录数据结构的复习笔记。

        数据结构这门课程是计算机考研408专业课中分数占比最高的一门课,同样难度也是最高的,

当然,世上无难事,只要肯攀登!

考点一:时间复杂度的计算

1、算法的效率

        一个算法效率的批判标准主要是看T(n)和S(n)即时间复杂度和空间复杂度。

2、T(n)时间复杂度

        对于T(n),其中n表示问题规模。这部分作为常考点难度较低,下面给出一段代码作为示例

(1) i=n-1;
(2) while(i>=0&&(A[i]!=k))
(3)     i--;
(4) return i;

对于这段简单代码,不难看出:

1、代码的目的是找到数组A[n]最后一个元素开始,向前寻找与k值相等的A[i],并将i返回。

2、不难看出代码(1)和代码(4)执行1次。而对于代码(2)和(3),我们则要开始讨论

        a、最理想情况:A[n-1]=k,那么代码(2)和代码(3)就只执行一次

        b、平均情况:假设在每一位找到k的概率相等,那么代码运行次数期望值应该是

1到n的求和,再除以概率1/n=1/n*n(1+n)/2。

tips:看不懂也可以不用管

        c、最坏情况(时间复杂度):最坏情况下,即指当程序在A[0]处才找到k。回到代码,代码(2)和代码(3)分别执行了n次,再加上代码(1)和代码(4)可得到

T(n)=1+n +n+1=2n+2

T(n)=2n+2

在分析一个算法的时间复杂度,有以下两条规则:

1)加法规则:T(n)=T1(n)+T2(n)=O(f(n))+O(g(n))=O(max(f(n),g(n)))即抓高阶

2)乘法规则:T(n)=T1(n)*T2(n)=O(f(n))*O(g(n))=O(f(n)*g(n))

综上:

O(n)=n

常见的渐进时间复杂度为

        O(1)<O(log2n)<O(n)<O(nlog2n)<O(n*n)<O(n*n*n)<O(2^n)<O(n!)<O(n^n)

补充:

//n是描述问题规模的非负整数
(1)x=2;
(2)while(x<n/2)
(3)x=2*x;

    该题当中由于n是描述问题规模的非负整数,所以代码(2)也可以看成while(x<n)

代码(3)中,不难发现x每次是以2倍增长

T(n)=1+logn+logn=2logn+1

O(n)=logn

可以发现,底数加上2即可,但其实底数在部分试题中又常常被省略,所以笔者在该部分也不过度提及,大家在做题的时候记得加上!!!

考点二:线性表(增!删!改!查!)

1、自诉:

        笔者在学习数据结构时,当时觉得时间复杂度比较简单,但是到了线性表这里就备受打击了,感觉脑袋不够用了,呜呜呜。

        线性表其实就是一个由n(n>=0)个相同数据类型元素组成的一个有限序列,当n=0表示为该表空表。

2.1、线性表的基本操作

InitList(&L):初始化表。构造一个空的线性表L。

DestroyList(&L):销毁操作。销毁线性表,并释放线性表L所占用的内存空间。

ListInsert(&L,i,e):插入操作。在表L中的第i个位置上插入指定元素e。

ListDelete(&L,i,&e):删除操作。删除表L中第i个位置的元素,并用e返回删除元素的值。

LocateElem(L,e):按值查找操作。在表L中查找具有给定关键字值的元素。

GetElem(L,i):按位查找操作。获取表L中第i个位置的元素的值。

其他常用操作:

Length(L) 求表长。返回线性表L的长度,即L中数据元素的个数。

PrintList(L) 输出操作。按前后顺序输出线性表L的所有元素值。

Empty(L) 判空操作。若L为空表,则返回true,否则返回false。

2.2、线性表的顺序表示

2.2.1、顺序表的基本操作实现

#include <stdio.h>
#include <malloc.h>
//1、静态分配
#define MaxSize1 50
typedef struct {
	int data[MaxSize1];
	int length;
}SqList;
//2、动态分配
#define InitSize 100
typedef struct {
	int * data;
	int length, MaxSize2;
}SeqList;

void InitList1(SqList& L) {//静态表初始化
	L.length = 0;
}
void InitList2(SeqList& L) {
	L.data = (int*)malloc(sizeof(int) * MaxSize1);
	L.length = 0;
	L.MaxSize2 = InitSize;
}
//顺序表的基本操作:增删改查
//1、插入一个元素:要判断插入范围是否在1到L.length+1之间,储存空间够不够。在i位插入元素则需要将i到L.length的元素向后移动一位。
bool ListInsert1(SqList& L, int i, int e) {
	if (i <= 0 || i > L.length + 1)
		return false;
	if (L.length >= MaxSize1)
		return false;
	for (int j = L.length + 1; j > i; j--) {//从最后一个元素到第i个元素,都向后移动一位。
		L.data[j] = L.data[j - 1];
	}
	L.data[i-1] = e;
	L.length++;
	return true;
}
//2、删除表中第i个元素:
bool ListDelete(SqList& L, int i, int &e) {
	if (i<0 || i>L.length)
		return false;
	e = L.data[i-1];
	for (int j = i-1 ; j < L.length ; j++) {
		L.data[j] = L.data[j + 1];
	}
	L.length--;
	return false;
}
//3、按值查找(顺序查找)要求返回其位序
int LocateElem(SqList& L, int e) {
	for (int j = 0; j < L.length; j++) {
		if (L.data[j] == e)
			return j+1;
	}
	return 0;
}

int main() {
	//静态表操作
	SqList L1;
	printf("初始化\n");
	InitList1(L1);
	ListInsert1(L1, 0, 0);
	ListInsert1(L1, 1, 1);
	ListInsert1(L1, 2, 2);
	ListInsert1(L1, 3, 3);
	ListInsert1(L1, 4, 4);
	ListInsert1(L1, 5, 6);
	for (int i = 0; i < L1.length; i++) {
		printf("%d\n", L1.data[i]);
	}
	printf("删除指定元素\n");
	int elem = 0;
	ListDelete(L1, 3, elem);
	for (int i = 0; i < L1.length; i++) {
		printf("%d\n", L1.data[i]);
	}
	printf("elem=%d\n",elem);

	int location = 0;
	printf("按值查找:\n");
	location=LocateElem(L1,2);
	printf("location=%d", location);


	//动态表操作
	SeqList L2;
	InitList2(L2);
}

2.3、线性表综合应用题(单独文章)详情

  • 8
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

陈啊尘

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

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

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

打赏作者

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

抵扣说明:

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

余额充值