数据结构——王卓老师

数据结构的基本概念

基本的数据结构

线性结构

线性表

定义与特点

线性表是具有相同特性的数据元素的一个有限序列
专业术语:直接前驱、直接后继、线性起点、终端终点
线性表(a1, a2, a3, … ,ai,…an)
其中a(i-1)是ai的直接前驱,a(i+1)是直接后继,a1是线性表的线性起点,an是线性表的终端终点
n为元素总个数,即表长
n=0时称为空表
例如:字母表:数据元素都是字母,元素间关系是线性的;学生情况登记表;12星座
特点:同一线性表中的元素必定具有相同特性,数据元素间的关系是线性关系

案例引入

eg1:
一元多项式的运算P(x) = 4 + 3x + 5x ^2
在这里插入图片描述
相加可找到R = (p0+q0, p1+q1, … pn+qn)
eg2:
稀疏多项式S(x) = 1 + 3x ^10000 + 2x ^20000
若是按照eg1存储则将造成浪费
在这里插入图片描述
线性表P = ((p1, e1), …, (pn,en))pn:系数 en:指数
eg3:稀疏多项式的和
线性表A = ((7,0), (3,1), (9, 8), (5,17))
线性表B = ((8,1), (22,7), (-9,8))

  1. 创建一个新数组c
  2. 从头遍历比较a和b的每一项
    1. 指数相同 2)指数不相同
  3. 遍历完毕,将另一个剩余项一次复制到c中
    eg4:图书信息管理系统
顺序表类型定义
基本操作

InitList(&L);
DestoryList(&L)(内存都无);
ClearList(&L)(为空表);
ListEmpty(L);
ListLength(L);
GetElem(L,i,&e);
LocateElem(L,e,compare())返回线性表L中第一个与e满足compare()的数据元素的位序,若无,返回0;
PriorElem(L,cur_e, &pre_e)cur_e是L的数据元素,且不是第一个,用pre_e返回它的前驱;
NextElem(L,cur_e, &next_e);
ListInsert(&L,i,e) 1<=i<=ListLength(L)+1,在L的第i个位置插入新数据元素e,L的长度加1;
ListDelete(&L,i,&e);
ListTraverse(&L,visited())

顺序存储的表示和实现

定义:把逻辑上相邻的数据元素存储在物理上相邻的存储单元中
依次存储,没有空出的存储单元(随机存取)

  1. 线性表第一个数据元素的存储位置,称为线性表的起始位置或基地址

  2. 顺序表:地址连续、依次存放、随机存放、类型相同

  3. 与数组相似,但是线性表长可变,数组长度不可动态定义,可以是int a[10];int a[]; int a[SIZE];int a[2+2];

  4. 顺序表的定义
    ①typedef struct {
    ElemType elem[MaxSize]; //存放空间的基地址,静态分配
    int length;
    }SqList; //顺序表类型

    ②typedef struct {
    ElemType * elem; //存放空间的基地址,动态分配
    int length;
    }SqList; //顺序表类型

  5. 平均查找长度ASL,即期望值在这里插入图片描述

  6. 实现LinkInsert的ASL = n/2,为O(n),因为每个数据元素插入的概率总为1/(n+1),插入在位置L.length时,移动0次;插入在L.length-1,移动1次,…,因此ASL = 1/(n+1)*(1+2+…+n) = n/2

  7. 实现ListDelete的ASL = n-1/2,因为每个数据元素被删除的概率总为1/n

  8. 优点:任一元素均可随意存取
    缺点:在插入、删除元素时,需要移动大量元素;浪费存储空间;属于静态存储形式,数据元素的个数不能随意扩充

类C语言

引用变量:int &j = i;//j是一个引用类型,代表i的一个替代名,i改变时,j也跟着改变
可实现的代码;int i = 5; int &j = i; int k = j;//5 5 5
内存中是没有为j分配空间的,而是直接对i进行操作

链式存储的表示和实现

用一组物理位置任意的存储单元来存放线性表的数据元素,逻辑顺序和物理顺序不一定相同(顺序存取)
有关术语:节点、链表

  1. 单链表:结点只一个指针域的链表
  2. 双链表:结点有两个指针域的链表
  3. 循环链表:首尾相接的链表
  4. 头指针:是指向链表中第一个结点的指针
  5. 首元结点:链表中第一个数据元素的结点
  6. 头结点:首元结点之前的结点,不是存储的第一个元素
    链表的存储结构:带头结点(头指针指向头结点)+不带头结点(头指针指向首元结点)
  7. 表示空表:①无头结点的:头指针为空②带头结点的:头结点的指针域为空
  8. 头结点的优点:便于对首元结点的处理;便于空表、非空表的处理
  9. 访问和操作时只能通过头指针进入链表
  10. 单链表的定义:
    typedef struct Lnode {
    ElemType data;
    struct Lnode * next;
    }Lnode, *LinkList;
    typedef struct {
    char num[8];
    char name[8];
    int score;
    }ElemType;
  11. 变量的定义:①头结点LinkList L; ②其他结点:Lnode *p;

三种链表(单链表,双向链表,循环链表)

顺序表和链式表的比较

  1. 链式存储结构
    优点:1. 结点空间可以动态申请和释放 2.插入和删除数据元素不需要移动数据元素
    缺点:1. 存储密度小(存储数据本身占用的空间/结点占用的空间容量) 2. 非随机存取,对任一结点的操作需要依照指针找到该结点
    在这里插入图片描述

线性表的应用

线性表的合并

如La=(7,5,3,11)Lb=(2,6,3) ——→ La = (7,5,3,11,2,6),即A∪B
算法步骤:union(&La,Lb)
依次取出Lb的每个元素

  1. 在La中查找该元素
  2. 如果找不到,则将其插入La的末尾
有序表的合并

将已知两个非递减的序列La和Lb,要求Lc的数据元素为La和Lb按照非递减有序排列
顺序表算法步骤:

  1. 创建一个空表Lc
  2. 依次从La和Lb中选择元素值较小的结点插入到Lc的后面,直至其中一个表变空为止
  3. 继续将剩下的另一个顺序表的剩余结点插入在Lc的最后
    顺序表的实现:时间复杂度O(ListLength(La)+ListLength(Lb)) 空间复杂度Lc 即O(ListLength(La)+ListLength(Lb))
    链表实现:
pa = La->next; pb = Lb->next;
pc = Lc = La;
while (pa && pb) {
		if(pa->data <= pb->data) {
		pc->next = pa;
		pc = pa;
		pa = pa->next;
	}
	else {
		pc->next = pb;
		pc = pb;
		pb = pb->next;
	}
}
pc->next = pa?pa:pb; //(?前面的作为条件而赋值运算符优先级数最低)
delete Lb;

时间复杂度O(ListLength(La)+ListLength(Lb)),空间复杂度O(1)

稀疏多项式

线性表A = ((7,0), (3,1), (9, 8), (5,17))
线性表B = ((8,1), (22,7), (-9,8))

  1. 创建一个新数组c
  2. 从头遍历比较a和b的每一项
  1. 指数相同 2)指数不相同
  1. 遍历完毕,将另一个剩余项一次复制到c中
    顺序存储结构存在问题:1.存储空间分配不灵活;运算的空间复杂度高(要为c分配不确定长的空间)
    链式存储结构较好

栈和队列

串、数组和广义表

非线性结构

树和二叉树

树和森林及哈夫曼树

图论

基本的数据处理技术

查找技术

排序技术

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值