数据结构学习

数据结构基础概念篇

  1. 栈和队列的特点,什么情况下使用?
  2. 栈:先进后出的结构。队列:先进先出的结构。
  3. 栈的应用:非常广泛,在CPU内部就有提供栈这个机制。主要用途:函数调用和返回,数字转字符,表达式求值,走迷宫等等。在CPU内部栈主要是用来进行子程序调用和返回,中断时数据保存和返回。在编程语言中:主要用来进行函数的调用和返回。可以说在计算机中,只要数据的保存满足先进后出的原理,都优先考虑使用栈,所以栈是计算机中不可缺的机制。
    队列的应用:队列主要用在和时间有关的地方,特别是操作系统中,队列是实现多任务的重要机制。windows中 的消息机制就是通过队列来实现的。进程调度也是使用队列来实现,所以队列也是一-个重要的机制。只要满足数据的先进先出原理就可以使用队列。

线性表

1.线性表的逻辑结构
2.线性表的基本操作

1.InitList(&L)
初始化表。构造一个空的线性表L,分配内存空间。
2.ListLength(L)
返回线性表L的长度,即L中数据元素的个数。
3.GetData(L,i)
按位查找。返回线性表L中第i个法元素的值,
4.InsList(&L,i,e)
在L中第i个位置之前插入新的数据元素e,L的长度加1。
因为要修改线性表L的具体内容,并且把修改的效果带回去,所以用&5.DelList(&L,i,&e)
删除L的第i个数据元素,并用e返回其值(即返回删除元素的值),L的长度减16.Locate(L,e)
按值查找。如果L中存在数据元素e,则将当前指针指向数据元素e所在位置并返回true,否则返回false。
7.DestroyList(L)
将L销毁,释放线性表L所占内存空间。
8.ClearList(L)
将L置为空表。
9.EmptyList(L)
判空。返回true或false。
10.PrintList(L)
按前后顺序输出线性表L中的所有元素值。

清空链表和销毁链表的区别:
当清空所有数据的节点,并且释放头结点后,该链表就无法再通过头结点创建,访问,插入,删除节点,因此相当于销毁了此链表。
清空链表,不清空头结点,链表还是可以继续使用。从第一个有数据的节点开始释放。
销毁链表后,不能对链表进行任何操作,否则为访问权限冲突,因为头结点指向的内存的操作权限已经归还给了操作系统。

释放链表的节点,是将链表每个节点包括指针域和数据域的一块结构体所占据的内存的操作权限还给系统,即释放了该块内存。

3.顺序存储

顺序表:关系线性化,结点顺序存。
计算存储地址:loc(Ai)=loc(A1)+(i-1)*sizeof(ElemType)
loc(A1)为基地址,即第一个元素的地址。

4.链式存储

连接方式:单、双、循环
实现角度:动态、静态

1.单链表
typedef struct Node
{
	ElemType data;//数据域
	struct Node*next;//指针域
}Node,*LinkList;
//Node*强调返回的是一个结点,LinkList L强调这是一个单链表

//初始化
//建立:头插法、尾插法
//查找:按位、按值
//求单链表长度
//插入
//删除
//合并两个有序的单链表

2.循环链表
//初始化
//建立(尾插法)
//合并算法(两种)

3.双向链表
typedef struct DNode
{
	ElemType data;
	struct DNode *prior,*next;
}DNode,*DoubleList;
//前插(插入)操作
//删除

4.静态链表
#define MaxSize 10//链表可能达到的最大长度
typedef struct
{
	ElemType data;
	int cursor;
}Component,StaticList[MaxSize];
//初始化
//分配结点空间

5.一元多项式的表示及相加

1.一元多项式的表示
2.一元多项式的存储
//顺序存储
//链式存储
typedef struct Polynode
{
	int coef;//系数
	int exp;//指数
	struct Polynode *next;
}Polynode,*Polylist;
//建立(尾插法)
3.一元多项式的相加运算

栈 LIFO

1.InitStack(S)
将S初始化为空栈
2.ClearStack(S)
栈置空
3.IsEmpty(S)
4.IsFull(S)
5.Push(S,x)
入栈
6.Pop(S,x)
删除(弹出)栈S的顶部元素,并用x带回该值。
7.GetTop(S,x)
读取栈顶元素,该元素不出栈

1.顺序栈

//初始化
//进栈
//出栈
//读栈顶元素
//多栈共享技术

2.双端顺序栈

//初始化
//进栈
//出栈

3.链栈

typedef struct node
{
	StackElementType data;
	struct node *next;
}LinkStackNode;
typedef LinkStackNode *LinkStack;

//进栈
//出栈
//多栈运算

4.括号匹配问题
5.表达式求值
6.栈与递归的实现

1.斐波那契数列
2.汉诺塔

队列 FIFO

1.InitQueue(Q)
初始化为一个空队列。
2.IsEmpty(Q)
3.IsFull(Q)
4.EnterQueue(Q,x)
入队。
5.DeleteQueue(Q,x)
出队。
6.GetHead(Q,x)
取队列Q的队头元素,并用x带回其值。

1.链队列

typedef struct Node//队列链式存储结构定义
{
    QueueElementType data;//定义数据域
    struct Node *next;//定义指针域
}LinkQueueNode;
typedef struct
{
    LinkQueueNode *front;//队头指针
    LinkQueueNode *rear;//队尾指针
}LinkQueue;

//初始化
//入队
//出队

2.循环队列

解决假溢出问题

//初始化
//入队
//出队

3.打印杨辉三角形
4.键盘输入循环缓冲区问题
只允许在队尾插入元素,在队头删除元素

  1. 链队列的基本运算
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
typedef struct Qnode//队列链式存储结构定义
{
    int data;//定义数据域
    struct Qnode *next;//定义指针域
}Qnode;
typedef struct
{
    Qnode *front;//队头指针
    Qnode *rear;//队尾指针
}LQueue;
void Init_LQueue(LQueue *q)//链队列的初始化
{
    q->front=q->rear=(Qnode*)malloc(sizeof(Qnode));//生成空间
    q->front->next=NULL;
}
void En_LQueue(LQueue *q,int x)//入队,将元素x插入到链队列q中,作为q的新队尾
{
    Qnode *p;
    p=(Qnode*)malloc(sizeof(Qnode));
    p->data=x;
    p->next=NULL;//置新结点的指针为空
    q->rear->next=p;//将链队列中队尾结点指针域指向新结点
    q->rear=p;//将队尾指针指向新结点
}
int De_LQueue(LQueue *q,int *x)//出队,若链队列q不为空,则删除队头元素,并返回其值
{
    Qnode *p;
    if(q->rear==q->front)//空链队列
        return 0;
    p=q->front->next;//取队头
    *x=p->data;
    q->front->next=p->next;//删除队首结点
    if(q->front->next==NULL)
        q->rear=q->front;
    free(p);
    return 1;
}
void Display_LQueue(LQueue *q)//链队列数据元素的显示
{
    Qnode *p;
    p=q->front->next;
    while(p!=NULL)
    {
        printf("%d",p->data);
        p=p->next;
    }
    printf("\n");
}
int main(int argc,char *argv[])
{
    int i,x,y,cord;
    LQueue q;
    Init_LQueue(&q);
    printf("初始化\n建立初始链队列如下:\n");
    for(i=1;i<=4;i++)
        En_LQueue(&q,i);
    Display_LQueue(&q);
    do
    {
        printf("       主菜单     \n");
        printf("   1    入队      \n");
        printf("   2    出队      \n");
        printf("   3    结束程序  \n");
        printf("-------------------------------\n");
        printf("请输入您选择的菜单号<1,2,3>:\n");
        scanf("%d",&cord);
        switch(cord)
        {
        case 1:
            printf("请输入入队元素:");
            scanf("%d",&y);
            En_LQueue(&q,y);
            printf("该元素入队后得到的新队列如下:");
            Display_LQueue(&q);
            break;
        case 2:
            if(De_LQueue(&q,&x)==0)
                printf("队空,不能出队!\n");
            else
            {
                printf("出队元素为:%d\n",x);
                printf("出队后得到的新队列如下:");
                Display_LQueue(&q);
            }
            break;
        case 3:
            exit(0);
            break;
        default:
            printf("输入有误!");
        }
    }while(cord<=3);
    return 0;
}

字符串
子串
主串
子串在主串中的位置
串相等
空串和空格串

1.StrAssign(S,chars)
生成一个值等于chars串的S。
2.StrInsert(S,pos,T)
在串S的第pos个字符之前插入串T。
3.StrDelete(S,pos,len)
从串S中删除第pos个字符起长度为len的子串。
4.StrCopy(S,T)
由串T复制得串S。
5.StrEmpty(S)
判串空。
6.StrCompare(S,T)
若S>T,则返回值大于0;若S=T,则返回值等于0;若S<T,则返回值小于07.StrLength(S)
返回串S的长度,即串S中的字符个数。
8.StrClear(S)
置空
9.StrCat(S,T)
将串T的值连接在串S的后面。
10.SubString(Sub,S,pos,len)
用Sub返回串S的第pos个字符起长度为len的子串。
11.StrIndex(S,pos,T)
若串S中存在和串T相同的子串,则返回它在串S中第pos个字符之后第一次出现的位置;否则返回0.
12.StrReplace(S,T,V)
用V替换串S中出现的所有与T相等的不重叠的子串。
13.StrDestroy(S)
销毁串S。

1.定长顺序串

#define MAXLEN 40
typedef struct
{
	char ch[MAXLEN];
	int len;
}SString;
1.串插入函数
2.串删除函数
3.串比较函数
4.定位函数

2.串的简单模式匹配BF算法
3.KMP算法
4.堆串

typedef struct
{
	char *ch;
	int len;
}HString;
1.堆串插入函数
2.堆串赋值函数

5.块链串

#define BLOCK_SIZE 4
typedef struct Block
{
	char ch[BLOCK_SIZE];
	struct Block *next;
}Block;
typedef struct
{
	Block *head;
	Block *tail;
	int len;
}BLString;

当BLOCK_SIZE等于1时,每个结点存放一个字符,结构同线性链表,存储结构可定义如下:
typedef struct chBlock
{
	char ch;
	struct chBlock *next;
}chBlock;

6.简单的行编辑器

数组

这里定义的数组,下标统一从1开始。

1.InitArray(A,n,bound1,...,boundn)
若维数n和各维的长度合法,则构造相应的数组A,并返回TRUE。
2.DestroyArray(A)
销毁数组A。
3.GetValue(A,e,index1,...,indexn)
若下标合法,则用e返回数组A中由index1,...,indexn所指定的元素的值。
4.SetValue(A,e,index1,...,indexn)
若下标合法,则将数组A中由index1,...,indexn所指定的元素的值置为e。

1.数组的顺序存储与实现

不同维数的数组的地址计算

2.特殊矩阵的压缩存储

1.三角矩阵
(1)下三角矩阵
(2)上三角矩阵
(3)对称矩阵
2.带状矩阵
(1)带状矩阵描述
(2)三对角带状矩阵特点
(3)三对角带状矩阵压缩存储方法
	①确定存储该矩阵所需的一维向量空间的大小
	②确定非零元素在一维数组空间中的地址
3.稀疏矩阵
(1)稀疏矩阵的三元组表表示法
	①稀疏矩阵的三元组存储表示
	②稀疏矩阵三元组表的类型定义
	③三元组表实现稀疏矩阵的转置运算
	NO.1 矩阵转置的经典算法
	NO.2 用三元组表实现稀疏矩阵的转置
	方法一:列序递增转置法
	方法二:一次定位快速转置法
(2)稀疏矩阵的链式存储结构:十字链表
	①十字链表的存储表示
	②十字链表的类型定义
	③十字链表算法实现

广义表

1.广义表的头尾链表存储结构
2.广义表的同层结点链存储结构
3.广义表的操作实现
	求广义表L的表头
	求广义表L的表尾
	求广义表的长度
	求广义表的深度
	统计广义表中原子数目
	复制广义表



子树
结点
结点的度
叶结点
分支结点
结点的层次
结点的层序编号
树的度
树的高度(深度)
有序树
森林
同构
孩子结点
双亲结点
兄弟结点
堂兄弟
祖先结点
子孙结点
前辈
后辈

1.InitTree(Tree)
将Tree初始化为一棵空树。
2.DestroyTree(Tree)
销毁树Tree。
3.CreateTree(Tree)
创建树
4.TreeEmpty(Tree)
判空
5.Root(Tree)
返回树Tree的根
6.Parent(Tree,x)
若x为非根结点,则返回它的双亲,否则返回“空”。
7.FirstChild(Tree,x)
若x为非叶子结点,则返回它的第一个孩子结点,否则返回“空”。
8.NextSibling(Tree,x)
若x不是其双亲的最后一个孩子结点,则返回x后面的下一个兄弟结点,否则返回“空”。
9.InsertChild(Tree,p,Child)
将Child插入Tree中,做p所指向结点的子树。
10.DeleteChild(Tree,p,i)
删除Tree中p所指向结点的第i棵子树。
11.TraverseTree(Tree,Visit())
按照某种次序对树Tree的每个结点调用Visit()函数访问一次且最多一次。若Visit()失败,则操作失败。

二叉树

1.Initiate(bt)
将bt初始化为空二叉树。
2.Create(bt)
创建一棵非空二叉树bt。
3.Destroy(bt)
销毁二叉树bt。
4.Empty(bt)
判空。
5.Root(bt)
求二叉树bt的根结点。
6.Parent(bt,x)
求双亲函数。求二叉树bt中结点x的双亲结点。
7.LeftChild(bt,x)
求左孩子,返回结点x的左孩子。
8.RightChild(bt,x)
求右孩子,返回结点x的右孩子。
9.Traverse(bt)
遍历操作。按某个次序依次访问二叉树中每个结点一次且仅一次。
10.Clear(bt)
清除操作。将二叉树bt置为空树。

1.性质

满二叉树
满二叉树的顺序表示
完全二叉树

2.存储结构

1.顺序存储结构
2.链式存储结构

3.遍历

先序遍历DLR
中序遍历LDR
后序遍历LRD

4.遍历算法应用

1.输出二叉树中的结点
2.输出二叉树中的叶子结点
3.统计叶子结点数目(两种)
4.建立二叉链表方式存储的二叉树
5.求二叉树的高度
6.按树状打印二叉树

5.基于栈的递归消除

1.中序遍历二叉树的非递归算法
2.后序遍历二叉树的非递归算法

6.线索二叉树

1.二叉树的线索化
2.在线索二叉树中找前驱、后继结点
3.遍历中序线索树

7.由遍历序列确定二叉树
8.树的存储结构

1.双亲表示法
2.孩子表示法
3,孩子兄弟表示法

9.树、森林与二叉树的相互转换

1.树转换为二叉树
2.森林转换为二叉树
3.二叉树还原为树或森林

10.树的遍历

1.先根遍历
2.后根遍历

11.森林的遍历

1.先序遍历
2.中序遍历
3.后序遍历

12.哈夫曼树

路径
路径长度
结点的权
带权路径长度

1.构造哈夫曼树
	初始化
	找最小树
	删除与加入
	判断
2.哈夫曼树的类型定义
	存储结构类型定义
3.算法实现

13.哈夫曼编码

前缀编码
哈夫曼编码:定理

14.并查集与等价类划分 P199

1.CreateGraph(G)
创建图G。
2.DestroyGraph(G)
销毁图G。
3.LocateVertex(G,v)
若图G中存在顶点v,则返回顶点v在图G中的位置。
4.GetVertex(G,i)
返回图G中的第i个顶点的值。
5.FirstAdjVertex(G,v)
返回图G中顶点v的第一个邻接点。
6.NextAdjVertex(G,v,w)
返回图G中顶点v的下一个邻接点(紧跟在w后)。
7.InsertVertex(G,u)
在图G中增加一个顶点u。
8.DeleteVertex(G,v)
删除图G的顶点v及与顶点v相关联的弧。
9.InsertArc(G,v,w)
在图G中增加一条从顶点v到顶点w的弧。
10.DeleteArc(G,v,w)
删除图G中从顶点v到顶点w的弧。
11.TraverseGraph(G)
按照某种次序,对图G的每个顶点访问一次且仅访问一次。

顶点

弧尾
弧头
有向图

无向图
完全图、稀疏图和稠密图
子图
邻接点:邻接到、邻接自
度、入度和出度
权与网
路径与回路
简单路径、简单回路
连通图:连通、连通分量、强连通图、强连通分量

1.图的存储结构

1.邻接矩阵表示法
2.邻接表表示法
3.十字链表
4.邻接多重表

2.图的遍历

1.深度优先搜索
2.广度优先搜索

3.图的应用

1.无向图的连通分量
2.图中两个顶点之间的简单路径
3.图的生成树和最小生成树
	普里姆算法
	克鲁斯卡尔算法
4.拓扑排序
5.关键路径
6.求某一顶点到其他各顶点的最短路径
7.求任意一对顶点间的最短路径
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值