数据结构
队列
循环队列
循环队列的空和满
如果采用和普通的队列一样的处理方式,比如front和rear都指向实际元素的位置,就会出现判空和判满一样的
处理方式一般是空一个元素,然后让rear指向实际队尾的下一个元素
Q.font == Q.rear;//空
(Q.rear + 1) % Q.length == Q.front;
串数组和广义表
串
子串的个数
- 子串: n(n+1)/2 + 1
- 非空子串:n(n+1)/2
- 非空真子串:n(n+1)/2 - 1
理解:就是n个一个字符的子串,n-1个两个字符的子串,以此类推, 到最后一个相等的子串,就是非真子串,就是n(n+1)/2个,最后加上一个空子串。
树
二叉树
二叉树的结构
typedef struct BiTNode
{
ElemType data;
struct BiTNode *lchild;
struct BiTNode *rchild;
}
二叉树的性质
- 二叉树第i层最多有2i-1
树的下一层的个数是上一层的两倍 - 深度为k的二叉树至多有2k - 1个节点
- 度为0的节点个数等于度为2的节点个数+1 n0 = n2 + 1;
完全二叉树的性质
完全二叉树就是满二叉树少了最右边的几个节点
- 有n个节点的完全二叉树的深度是log2n + 1,向下取整
- 2i是节点的左孩子2i+1是右孩子
树和二叉树
如果将一个树转化成二叉树,用二叉链表的形式存储,那么根节点的右指针就是空
huffmanTree 哈夫曼树
哈夫曼树是前缀编码,就是任何一个编码都不是其他编码的前缀
其他
先序后序和中序的叶子节点的位置都一样
图
有向完全图的弧的个数为n(n - 1);
图的一些性质
强连通图就是有向图的最小连通分量
图的结构
邻接矩阵
typedef struct{
char vexs[MVNum]; //存放顶点的一维数组
int arcs[MVNum][MVNum]; //邻接矩阵
int vexnum,arcnum; //图的当前顶点数和边数
}MGraph;
邻接表
typedef struct ArcNode{ //表结点
int adjvex; //邻接点的位置
struct ArcNode *nextarc; //指向下一个表结点的指针
}ArcNode;
typedef struct VNode{
char data; //顶点信息
ArcNode *firstarc; //指向第一个表结点的指针
}VNode, AdjList[MVNum]; //AdjList表示邻接表类型
typedef struct{
AdjList vertices; //头结点数组
int vexnum, arcnum; //图的当前顶点数和边数
}ALGraph;
图的应用
- 拓扑序列 就是从没有前驱的开始输出,有前驱的就不能输出 一般可以用拓扑序列来判断是否成环
排序
插入排序
直接插入排序
#include <stdio.h>
typedef int DataType; // 定义具体数据类型
#define LISTSIZE 100 // LISTSIZE 表示顺序表可能的最大数据元素数目
/****** 顺序表存储结构 ******/
typedef struct
{
DataType list[LISTSIZE];
int length;
}SqList;
/****** 初始化顺序表 ******/
int InitList(SqList *L) // L为指向顺序表的指针
{
L->length = 0;
return 1;
}
/****** 求顺序表表长 ******/
int ListLenth(SqList L) // L为顺序表
{
return L.length;
}
/****** 判断顺序表是否为空 ******/
int ListEmpty(SqList L) // L为顺序表
{
if (L.length <= 0)
{
return 1;
}
else
{
return 0;
}
}
/****** 向顺序表插入元素 ******/
int ListInsert(SqList *L, int pos, DataType item)
{ // L为指向顺序表的指针,pos为插入位置,item为待插入的数据元素
int i;
if (L -> length >= LISTSIZE) // 判断顺序表是否已满
{
printf("顺序表已满,无法插入\n");
return 0;
}
if (pos <= 0 || pos > L -> length + 1)
{ // 检查元素插入位置是否在顺序表里
printf("插入位置不合法\n");
return 0;
}
for (i = L -> length - 1; i >= pos - 1; i--)
{ // 移动数据元素
L -> list[i + 1] = L -> list[i];
}
L -> list[pos - 1] = item; // 插入元素
L -> length++; // 表长加一
return 1;
}
/****** 遍历顺序表 ******/
int TraverList(SqList L) // L为顺序表
{
int i;
for(i = 0; i < L.length; i++)
{
printf("%d ", L.list[i]);
}
printf("\n");
return 1;
}
void InsertSort(SqList *L);
int main()
{
SqList L;
DataType x;
char ch;
int pos = 1;
InitList(&L);
do
{
scanf("%d",&x);
ListInsert( &L , pos++ , x );
}while ((ch=getchar())!='\n');
InsertSort(&L);
printf("The sorted List is\n");
TraverList(L);
return 0;
}
void InsertSort(SqList *L){
int j;
int temp;
for(int i = 1; i < L->length; i++){
if(L->list[i] < L->list[i - 1]){
temp = L->list[i];
L->list[i] = L->list[i - 1];
for(j = i - 1; j > 0; j--){
if(L->list[j - 1] > temp){
L->list[j] = L->list[j - 1];
}
else{
L->list[j] = temp;
break;
}
}
if(j == 0){
L->list[0] = temp;
}
}
TraverList(*L);
}
}