Mooc数据结构-基础和线性结构
Posted weihuchao
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mooc数据结构-基础和线性结构相关的知识,希望对你有一定的参考价值。
1 数据结构
解决问题方法的效率,跟数据的组织方式有关
解决问题方法的效率,跟空间的利用效率有关
解决问题方法的效率,跟算法的巧妙程度有关
数据结构
数据对象在计算机中的组织方式
逻辑结构
物理存储结构
数据对象必定与一系列加在其上的操作相关联
完成这些操作所用的方法就是算法
抽象数据类型(Abstract Data Type)
数据类型
数据对象集
数据集合相关联的操作集
抽象: 描述数据类型的方法不依赖与具体实现
与存放数据的机器无关
与数据存储的物理结构无关
与实现操作的算法和编程语言无关
只描述数据对象集和相关操作集是什么, 并不涉及如何做到的问题
2 算法
算法
一个有限指令集
接受一些输入(或者没有输入)
产生输出
一定在有限步骤之后终止
每一条指令必须
有充分明确的目标, 不可以有歧义
计算机能处理的范围之内
描述应不依赖于任何一种计算机语言以及具体的实现手段
判定算法好换的依据-复杂度
空间复杂度S(n)
时间复杂度T(n)
一般来说关注的是最坏情况的复杂度和平均复杂度
复杂度的渐进表示法
1 < logn < n <nlogn < n2 <2n < n!
3 最大子列和
最大子列和问题就是, 给定一个数字序列, 求其中按顺序截取的子序列和最大的
1) 算法1, 分三层遍历, 第一层遍历序列, 第二层遍历当前之后的, 第三层计算序列的和
算法1的具体实现
def algo_1(my_list):
max_sum = 0
size = len(my_list)
for i in range(size):
for j in range(i,size):
current_sum = 0
for k in range(i,j+1):
current_sum += my_list[k]
if current_sum >= max_sum:
max_sum = current_sum
print(max_sum)
2) 算法2, 分两层遍历, 第一层遍历, 第二计算值
具体代码如下
def algo_2(my_list):
max_sum = 0
size = len(my_list)
for i in range(size):
current_sum = 0
for j in range(i,size):
current_sum += my_list[j]
if current_sum > max_sum:
max_sum = current_sum
print(max_sum)
3) 算法3, 分而治之
分而治之实现比较复杂
基本思想就是, 分成两个部分, 求出左边最大的, 求出右边最大的, 求出跨边界最大的, 三者最大的就是最大的
算法内容是:
先中分, 再中分,不断中分
从最小两个分部开始, 选择最大的值
在联合就近第二小的选择, 处理跨边界, 从边界出发, 得到向左延续的1格, 2格..求出最大的, 右边也是, 然后两个最大的合在一起就是边界最大
不断重复直到最后
4) 算法4, 在线处理
时间复杂度为o(n), 应该是最快的时间复杂度了
该算法的特点的可以等待输入就可以获得当前序列的最大子序列, 这也是在线处理的由来
具体的思路是, 抓住子序列的特点的连续的
要使得连续序列能够增大, 则部分和应该是正数, 当出现负数和式, 需要舍弃值重新计算序列
具体实现如下
def algo_4(my_list):
max_sum = 0
current_sum = 0
size = len(my_list)
for i in range(size):
current_sum += my_list[i]
if current_sum > max_sum:
max_sum = current_sum
elif current_sum < 0:
current_sum = 0
print(max_sum)
4 线性表
线性结构最简单的就是线性表
4.1 多项式的表示
多项式的主要信息有两个, 一个是x的次数, 一个是对应的系数
1) 方法1, 数组方式
数组按照索引的方式, 索引对应x的次数, 系数就存放在对应的数组位置
优点: 计算十分方便
缺点: 浪费空间
2) 方法2: 二维数组方式
数组里面再存一个数组, 数组里面存放系数和次数
为了便于计算, 存储的时候要按照次数按顺序存入
计算方式:
取出两个多项式的第0项目, 比较系数大小, 如果不相同, 输出大的, 然后获得对应多项式的第1项目, 在比较系数进行运算; 如果相同直接运算输出;
优点: 不用存储系数为0的项目, 节省空间
3) 方法3: 使用链表存储
定义一个结构体, 内容有次数, 系数, 下一个指针
计算方式同方法2
4.2 线性表以及顺序存储
一般来说, 线性表的问题都是有两种方式, 要么是数组, 要么是链表
线性表: 由类型数据元素构成有序序列的线性结构
表中元素的个数恒伟线性表的长度
线性表没有元素时, 称为空表
表其实位置称为表头, 表结束位置称为表尾
线性表的ADT表示
4.2.1 线性表的顺序存储实现
利用数组的连续存储空间顺序存放线性表的各个元素
使用数组的方式来构建线性表
数据类型表示
typedef struct{
ElementType Data[MAXSIZE];
int Last;
}List;
List L,*PtrL;
线性表的主要操作
1) 初始化
List *MakeEmpty(){
List *PtrL;
PtrL = (List *)malloc(sizeof(List));
PtrL->Last = -1;
return PtrL;
}
2) 查找
int Find(ElementType X, List *PtrL)
{
int i = 0;
while( i<=PtrL->Last && PtrL->Data[i]!=X )
i++;
if( i> PtrL->Last)
return -1;
else
return i;
}
查找的平均次数是 (n+1)/2
平均时间性能为 O(n)
3) 插入
在第i(1<=i<=n+1)个位置插入元素X
对应在数据上, 就是插入到索引 i-1 的位置
需要遵循的是先移动再插入
实现为
void Insert(ElementType X, int i, List *PtrL)
{
int j;
if(PtrL->Last == MAXSIZE-1){
printf("表满了");
return ;
}
if( i < 1 || PtrL->Last+2){
printf("位置不合法");
return ;
}
for(j=PtrL->Last; j>=i-1; j--)
PtrL->Data[j+1] = PtrL->Data[j];
PtrL->Data[i-1] = x;
PtrL->Last++;
return;
}
4) 删除
删除第i(1<=i<=n)个元素
后面的元素依次往前移动
实现
void Delete( int i, List *PtrL)
{
int j;
if( i <1 || PtrL->Last+1 ){
printf("不存在第%d个元素", i);
return ;
}
for( j=1; j<=PtrL->Last; j++)
PtrL->Data[j-1] = PtrL->Data[j];
PtrL->Last--;
return ;
}
平均移动次数为(n-1)/2
平均时间性能为O(n)
4.2.2 线性表的链式存储实现
链式存储不需要物理存储上也是相邻存储
元素之间通过指针来链接
定义数据结构
typedef struct Node
{
ElementType Data;
struct Node *Next;
}List;
List L, *PtrL;
主要的操作实现
1) 求表长度
int Length(List *PtrL)
{
List *p = PtrL;
int j = 0;
while(p){
p = p->Next;
j++
}
return j;
}
时间复杂度为O(n)
2) 查找
按照序号查找
List *FindKth( int K, List *PtrL)
{
List *p = PtrL;
int i = 1;
while( p != NULL && i < K){
p = p->Next;
i++;
}
if( i==K )
return p;
else
return NULL;
}
按值查找
List *Find(ElementType X, List *PtrL){
List *p = PtrL;
while( p!=NULL && p->Data!=X)
p = p -> Next;
return p;
}
平均时间复杂度为O(0)
3) 插入
在第i-1(1<=i<=n+1)个结点后插入一个值为X的新结点
插入的步骤
1) 创建一个新的节点, 用s指向
2) 找到i-1个节点, 用p执行
3) 修改指针
s->Next = p->Next;
p->Next = s;
顺序不能交换, 不然的话就找不到第i个节点的指针了
4) 删除
删除第i[1,n]个位置上的节点
步骤
1) 找到i-1个节点, 用p指向
2) 用s指向被删除的节点
s = p->next;
3) 修改p指针
p->next = s->next;
4) 释放s的空间
4.2.3 广义表和多重链表
之前的一元多项式可以用顺序表表示
如果是二元多项式的话, 就可以同样的先看成是关于x的一元多项式, 然后x的系数是关于y的一元多项式
广义表:
线性表的推广
在广义表中元素可能是另一个广义表, 而相对的线性表中就是一个单元素
多重链表
链表中的节点可能同时隶属于多个链
多重链表中的节点有多个指针域, 但是不是有多个指针域就是剁成链表, 判断的依据是不是指向自身的
可以用典型的多重链表-十字链表来存储稀疏矩阵
只存储非0项, 数据域为: 行, 列, 数值
每个节点通过两个指针域, 把同行同列串起来, 也就是Right和Down指针
以上是关于Mooc数据结构-基础和线性结构的主要内容,如果未能解决你的问题,请参考以下文章
数据结构学习笔记二线性表---顺序表篇(画图详解+代码实现)